diff --git a/.ci/build.sh b/.ci/build.sh index e18aa483771..fb360b826bf 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -338,7 +338,8 @@ strip_binary=strip if is_windows then # Switch into the correct MSYSTEM if required. - msys=MINGW$arch + msys=UCRT$arch + [ ! -d "/$msys" ] && msys=MINGW$arch [ ! -d "/$msys" ] && msys=CLANG$arch if [ -d "/$msys" ] then diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9e5521cf4b0..69ca14b4afa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,6 +9,8 @@ Checklist * [ ] I have discussed this with core contributors already * [ ] This pull request requires changes to the ROM set * [ ] I have opened a roms pull request - https://github.com/86Box/roms/pull/changeme/ +* [ ] This pull request requires changes to the asset set + * [ ] I have opened an assets pull request - https://github.com/86Box/assets/pull/changeme/ References ========== diff --git a/.github/workflows/cmake_windows_msys2.yml b/.github/workflows/cmake_windows_msys2.yml index 8959395eb37..986d63a0b7b 100644 --- a/.github/workflows/cmake_windows_msys2.yml +++ b/.github/workflows/cmake_windows_msys2.yml @@ -69,21 +69,21 @@ jobs: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake # slug: "-MSYS64" - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - slug: "-64" - runner: windows-2022 +# - msystem: MINGW64 +# prefix: mingw-w64-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "MINGW64" +# runner: windows-2022 # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake # slug: "CLANG64" # runner: windows-2022 -# - msystem: UCRT64 -# prefix: mingw-w64-ucrt-x86_64 -# toolchain: ./cmake/flags-gcc-x86_64.cmake -# slug: "UCRT64" -# runner: windows-2022 + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + slug: "-64" + runner: windows-2022 - msystem: CLANGARM64 toolchain: ./cmake/flags-gcc-aarch64.cmake slug: -arm64 diff --git a/.github/workflows/codeql_windows_msys2.yml b/.github/workflows/codeql_windows_msys2.yml index 9673ab6508c..2982c273448 100644 --- a/.github/workflows/codeql_windows_msys2.yml +++ b/.github/workflows/codeql_windows_msys2.yml @@ -83,21 +83,21 @@ jobs: # - msystem: MSYS # toolchain: ./cmake/flags-gcc-x86_64.cmake # slug: "-MSYS64" - - msystem: MINGW64 - prefix: mingw-w64-x86_64 - toolchain: ./cmake/flags-gcc-x86_64.cmake - slug: "-64" - runner: windows-2022 +# - msystem: MINGW64 +# prefix: mingw-w64-x86_64 +# toolchain: ./cmake/flags-gcc-x86_64.cmake +# slug: "MINGW64" +# runner: windows-2022 # - msystem: CLANG64 # prefix: mingw-w64-clang-x86_64 # toolchain: ./cmake/llvm-win32-x86_64.cmake # slug: "CLANG64" # runner: windows-2022 -# - msystem: UCRT64 -# prefix: mingw-w64-ucrt-x86_64 -# toolchain: ./cmake/flags-gcc-x86_64.cmake -# slug: "UCRT64" -# runner: windows-2022 + - msystem: UCRT64 + prefix: mingw-w64-ucrt-x86_64 + toolchain: ./cmake/flags-gcc-x86_64.cmake + slug: "-64" + runner: windows-2022 # - msystem: CLANGARM64 # toolchain: ./cmake/flags-gcc-aarch64.cmake # slug: -arm64 diff --git a/CMakeLists.txt b/CMakeLists.txt index 29fedd6ad59..3004b37117d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 5.2 + VERSION 6.0 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) @@ -186,6 +186,7 @@ cmake_dependent_option(WACOM "Wacom Input Devices" cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) cmake_dependent_option(NETSWITCH "Network Switch Support" ON "DEV_BRANCH" OFF) cmake_dependent_option(VFIO "Virtual Function I/O" ON "DEV_BRANCH" OFF) +cmake_dependent_option(SOFTMODEM "AC'97 Softmodem" ON "DEV_BRANCH" OFF) # Ditto but for Qt if(QT) diff --git a/README-UNIX-MODE-WITH-OSD.txt b/README-UNIX-MODE-WITH-OSD.txt new file mode 100644 index 00000000000..2fff9010390 --- /dev/null +++ b/README-UNIX-MODE-WITH-OSD.txt @@ -0,0 +1,78 @@ +UNIX MODE WITH OSD + +86Box supports running on the linux framebuffer without QT and without X, making the pc appear as a nearly native old machine. + +running it that way is already supported but when doing it, 86box loses all menu and all abilities to mount floppies and CDs, it also becomes the owner of the entire pc with no way of quitting it or changing virtual console. + +to overcome this, an on screen display menu is available that allows doing everything the textual console (src/unix/unix.c) does; +mount/unmount all supported media like floppy and cd +hard reset the machine +quit 86box +seeing the current performance % + +key bindings: +Right Control + F11 opens the osd + +while is open: +arrows up, down moves the cursor +enter does the action, at mount options it enters a list of appropriate files (*.img, *.iso) +ESC goes back to main or closes the OSD + +current limitations: + OSD can mount images to first floppy and first cd, secondary devices are not supported + it does not show if an image is mounted or not + the option "version" does actully print it, but it can't be seen beacuse its printed under 86box display + extremely long filenames can overflow the blue window + the title does actually overflow the window width :) + +These are the steps to install a machine fully dedicated to 86Box and tuned to make it appear almost native. +This works almost the same for on a Raspberry Pi + + +1) install a vanilla Debian Trixie with netinst and without any graphical environment, or a "server" distro for RPI + depending on the machine speed, this will make boot time extremely short + +2) apt update if necessary + +3) install git and almost all required packages + apt install git build-essential cmake extra-cmake-modules pkg-config ninja-build libfreetype-dev libsdl2-dev libpng-dev libopenal-dev librtmidi-dev libfluidsynth-dev libsndfile1-dev libserialport-dev libevdev-dev libxkbcommon-dev libxkbcommon-x11-dev libslirp-dev + +4) setup git and clone + git@github.com:86Box/86Box.git + git@github.com:86Box/roms.git + +5) build (128 => super speed, too much for a 2GB machine) + cd 86Box + mkdir build + cd build + cmake .. --preset regular -D QT=OFF -D PREFER_STATIC=ON + cmake --build regular -j 128 + cd ../../ + ln -s 86Box/build/regular/src/86Box 86Box.exe + +6) boot + as root so it can take complete ownership of the linux framebuffer + +7) notes: +- 86Box will complain to be unable to find readline, this is fine, we don't need the command line at all +- ALSOFT will complain it can't connect to PipeWire, no problem, sounds will come from standard ALSA + +8) additional steps + add a new udev rule to automount any USB key to a known location so files in it can be listed in the OSD floppy/cd mount options + + create /etc/udev/rules.d/99-automount.rules + + with: + ACTION=="add", ENV{ID_BUS}=="usb", ENV{ID_TYPE}=="disk", ENV{ID_FS_TYPE}=="exfat", RUN+="/usr/bin/systemd-mount --no-block --automount=yes --collect /dev/%k '/mnt'" + + replicate this line for each filesystem you expect the usb key to be formatted, in this example "exfat" + this is going to conflict if multiple keys are inserted, don't do it + +final step + configure some 86box vm using another pc with the GUI + copy the VM definitions to this new pc and manually launch 86box from the textual command line + optionally craft a boot menu to be shown in place of the login prompt or setup 86box as a debiasn service, it will start at boot + just make sure the pc will be accessible via ssh or some other way, autobooting 86box canĂ make difficult terminating it + + + diff --git a/bumpversion.sh b/bumpversion.sh index 6e2536cbe7c..76ef075540c 100644 --- a/bumpversion.sh +++ b/bumpversion.sh @@ -43,23 +43,33 @@ pretty_date() { # Patch files. patch_file() { - # Stop if the file doesn't exist. - [ ! -e "$1" ] && return + # Parse arguments. + desc="$1" + shift + pattern="$1" + shift - # Patch file. - if sed -i -r -e "$3" "$1" - then - echo "[-] Patched $2 on $1" - else - echo "[!] Patching $2 on $1 failed" - fi + # Patch the specified files. + for file in "$@" + do + # Skip file if it doesn't exist. + [ ! -e "$file" ] && continue + + # Patch file. + if sed -i -r -e "$pattern" "$file" + then + echo "[-] Patched $desc in $file" + else + echo "[!] Patching $desc in $file failed" + fi + done } -patch_file CMakeLists.txt VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/' -patch_file vcpkg.json version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/' -patch_file src/unix/assets/*.spec Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' -patch_file src/unix/assets/*.spec '%global romver' 's/(^%global\ romver\s+)[0-9]{8}/\1'"$romversion"'/' -patch_file src/unix/assets/*.spec 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' -patch_file src/unix/assets/*.spec 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' -patch_file src/unix/assets/*.metainfo.xml release 's/( .+/> '"$(date -R)"'/' -patch_file debian/changelog 'changelog version' 's/86box \(.+\)/86box \('"$newversion"'\)/' +patch_file VERSION 's/^(\s*VERSION ).+/\1'"$newversion"'/' CMakeLists.txt +patch_file version-string 's/(^\s*"version-string"\s*:\s*")[^"]+/\1'"$newversion"'/' vcpkg.json +patch_file Version 's/(Version:\s+)[0-9].+/\1'"$newversion"'/' src/unix/assets/*.spec +patch_file '%global romver' 's/(^%global\ romver\s+)[^\s]+/\1'"$romversion"'/' src/unix/assets/*.spec +patch_file 'changelog version' 's/(^[*]\s.*>\s+)[0-9].+/\1'"$newversion"-1'/' src/unix/assets/*.spec +patch_file 'changelog date' 's/(^[*]\s)[a-zA-Z]{3}\s[a-zA-Z]{3}\s[0-9]{2}\s[0-9]{4}/\1'"$(pretty_date)"'/' src/unix/assets/*.spec +patch_file release 's/( .+/> '"$(date -R)"'/' debian/changelog +patch_file 'changelog version' 's/86box \(.+\)/86box \('"$newversion"'\)/' debian/changelog diff --git a/debian/changelog b/debian/changelog index cfb4bd9d0d6..d2606a616a2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (5.2) UNRELEASED; urgency=medium +86box (6.0) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Thu, 18 Sep 2025 04:25:57 +0200 + -- Jasmine Iwanek Sun, 26 Oct 2025 17:41:47 +0100 diff --git a/src/86box.c b/src/86box.c index 4baed45f5bc..020cb609022 100644 --- a/src/86box.c +++ b/src/86box.c @@ -120,7 +120,6 @@ /* Stuff that used to be globally declared in plat.h but is now extern there and declared here instead. */ int dopause = 1; /* system is paused */ -atomic_flag doresize; /* screen resize requested */ volatile int is_quit; /* system exit requested */ uint64_t timer_freq; char emu_version[200]; /* version ID string */ @@ -144,10 +143,12 @@ int confirm_exit_cmdl = 1; /* (O) do not ask for confirmation on quit if set to uint64_t unique_id = 0; uint64_t source_hwnd = 0; #endif -char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */ -rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ -char log_path[1024] = { '\0' }; /* (O) full path of logfile */ -char vm_name[1024] = { '\0' }; /* (O) display name of the VM */ +char rom_path[1024] = { '\0' }; /* (O) full path to ROMs */ +rom_path_t rom_paths = { "", NULL }; /* (O) full paths to ROMs */ +char asset_path[1024] = { '\0' }; /* (O) full path to assets */ +rom_path_t asset_paths = { "", NULL }; /* (O) full paths to assets */ +char log_path[1024] = { '\0' }; /* (O) full path of logfile */ +char vm_name[1024] = { '\0' }; /* (O) display name of the VM */ int do_nothing = 0; int dump_missing = 0; int clear_cmos = 0; @@ -171,6 +172,7 @@ int vid_api = 0; /* (C) video r int vid_cga_contrast = 0; /* (C) video */ int video_fullscreen = 0; /* (C) video */ int video_fullscreen_scale = 0; /* (C) video */ +int fullscreen_ui_visible = 0; /* (C) video */ int enable_overscan = 0; /* (C) video */ int force_43 = 0; /* (C) video */ int video_filter_method = 1; /* (C) video */ @@ -262,6 +264,11 @@ struct accelKey def_acc_keys[NUM_ACCELS] = { .desc="Toggle fullscreen", .seq="Ctrl+Alt+PgUp" }, + { + .name="toggle_ui_fullscreen", + .desc="Toggle UI in fullscreen", + .seq="Ctrl+Alt+PgDown" + }, { .name="screenshot", .desc="Screenshot", @@ -331,8 +338,8 @@ __thread int is_cpu_thread = 0; static wchar_t mouse_msg[3][200]; -static volatile atomic_int do_pause_ack = 0; -static volatile atomic_int pause_ack = 0; +static volatile ATOMIC_INT do_pause_ack = 0; +static volatile ATOMIC_INT pause_ack = 0; #define LOG_SIZE_BUFFER 8192 /* Log size buffer */ @@ -657,6 +664,7 @@ pc_show_usage(char *s) "\n%sUsage: 86box [options] [cfg-file]\n\n" "Valid options are:\n\n" "-? or --help\t\t\t- show this information\n" + "-A or --assetpath path\t\t- set 'path' to be asset path\n" #ifdef SHOW_EXTRA_PARAMS "-C or --config path\t\t- set 'path' to be config file\n" #endif @@ -727,6 +735,7 @@ pc_init(int argc, char *argv[]) { char *ppath = NULL; char *rpath = NULL; + char *apath = NULL; char *cfg = NULL; char *global = NULL; char *p; @@ -793,6 +802,7 @@ pc_init(int argc, char *argv[]) */ plat_getcwd(usr_path, sizeof(usr_path) - 1); plat_getcwd(rom_path, sizeof(rom_path) - 1); + plat_getcwd(asset_path, sizeof(asset_path) - 1); for (c = 1; c < argc; c++) { if (argv[c][0] != '-') @@ -846,6 +856,12 @@ pc_init(int argc, char *argv[]) rpath = argv[++c]; rom_add_path(rpath); + } else if (!strcasecmp(argv[c], "--assetpath") || !strcasecmp(argv[c], "-A")) { + if ((c + 1) == argc) + goto usage; + + apath = argv[++c]; + asset_add_path(apath); } else if (!strcasecmp(argv[c], "--config") || !strcasecmp(argv[c], "-C")) { if ((c + 1) == argc || plat_dir_check(argv[c + 1])) goto usage; @@ -969,6 +985,7 @@ pc_init(int argc, char *argv[]) path_slash(usr_path); path_slash(rom_path); + path_slash(asset_path); /* * If the user provided a path for files, use that @@ -1009,6 +1026,16 @@ pc_init(int argc, char *argv[]) plat_init_rom_paths(); + // Add the VM-local asset path. + path_append_filename(temp, usr_path, "assets"); + asset_add_path(temp); + + // Add the standard ROM path in the same directory as the executable. + path_append_filename(temp, exe_path, "assets"); + asset_add_path(temp); + + plat_init_asset_paths(); + /* * If the user provided a path for ROMs, use that * instead of the current working directory. We do @@ -1039,6 +1066,36 @@ pc_init(int argc, char *argv[]) } else rom_path[0] = '\0'; + /* + * If the user provided a path for ROMs, use that + * instead of the current working directory. We do + * make sure that if that was a relative path, we + * make it absolute. + */ + if (apath != NULL) { + if (!path_abs(apath)) { + /* + * This looks like a relative path. + * + * Add it to the current working directory + * to convert it (back) to an absolute path. + */ + strcat(asset_path, apath); + } else { + /* + * The user-provided path seems like an + * absolute path, so just use that. + */ + strcpy(asset_path, apath); + } + + /* If the specified path does not yet exist, + create it. */ + if (!plat_dir_check(asset_path)) + plat_dir_create(asset_path); + } else + asset_path[0] = '\0'; + /* Grab the name of the configuration file. */ if (cfg == NULL) cfg = CONFIG_FILE; @@ -1076,6 +1133,8 @@ pc_init(int argc, char *argv[]) path_slash(usr_path); if (rom_path[0] != '\0') path_slash(rom_path); + if (asset_path[0] != '\0') + path_slash(asset_path); /* At this point, we can safely create the full path name. */ path_append_filename(cfg_path, usr_path, p); @@ -1083,7 +1142,10 @@ pc_init(int argc, char *argv[]) /* Build the global configuration file path. */ if (global == NULL) { plat_get_global_config_dir(global_cfg_path, sizeof(global_cfg_path)); - path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE); + // avoid strcpy global_cfg_path over itself (valgrind says it's bad...) + // path_append_filename(global_cfg_path, global_cfg_path, GLOBAL_CONFIG_FILE); + path_slash(global_cfg_path); + strcat(global_cfg_path, GLOBAL_CONFIG_FILE); } else { strncpy(global_cfg_path, global, sizeof(global_cfg_path) - 1); } @@ -1174,6 +1236,10 @@ pc_init(int argc, char *argv[]) pclog("# ROM path: %s\n", rom_path->path); } + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + pclog("# Asset path: %s\n", asset_path->path); + } + /* * We are about to read the configuration file, which MAY * put data into global variables (the hard- and floppy @@ -1720,6 +1786,7 @@ pc_reset_hard_init(void) void update_mouse_msg(void) { +#ifdef USE_SDL_UI wchar_t wcpufamily[2048]; wchar_t wcpu[2048]; wchar_t wmachine[2048]; @@ -1736,21 +1803,20 @@ update_mouse_msg(void) if (wcp) /* remove parentheses */ *(wcp - 1) = L'\0'; mbstowcs(wcpu, cpu_s->name, strlen(cpu_s->name) + 1); -#ifdef _WIN32 - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i.%%i%%%% - %ls", - plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i.%%i%%%% - %ls", - (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - wcsncpy(mouse_msg[2], L"%i.%i%%", sizeof_w(mouse_msg[2])); -#else - swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, plat_get_string(STRING_MOUSE_CAPTURE)); - swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls - %ls", + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls - %ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu, (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); - swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i.%%i%%%% - %ls - %ls/%ls", + swprintf(mouse_msg[2], sizeof_w(mouse_msg[2]), L"%ls v%ls - %%i%%%% - %ls - %ls/%ls", EMU_NAME_W, EMU_VERSION_FULL_W, wmachine, wcpufamily, wcpu); +#else + swprintf(mouse_msg[0], sizeof_w(mouse_msg[0]), L"%%i%%%% - %ls", + plat_get_string(STRING_MOUSE_CAPTURE)); + swprintf(mouse_msg[1], sizeof_w(mouse_msg[1]), L"%%i%%%% - %ls", + (mouse_get_buttons() > 2) ? plat_get_string(STRING_MOUSE_RELEASE) : plat_get_string(STRING_MOUSE_RELEASE_MMB)); + wcsncpy(mouse_msg[2], L"%i%%", sizeof_w(mouse_msg[2])); #endif } @@ -1832,9 +1898,9 @@ _ui_window_title(void *s) void ack_pause(void) { - if (atomic_load(&do_pause_ack)) { - atomic_store(&do_pause_ack, 0); - atomic_store(&pause_ack, 1); + if (ATOMIC_LOAD(do_pause_ack)) { + ATOMIC_STORE(do_pause_ack, 0); + ATOMIC_STORE(pause_ack, 1); } } @@ -1884,7 +1950,7 @@ pc_run(void) else fps = ((fps + 20) / 50) * 50; #endif - swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); + swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ dispatch_async_f(dispatch_get_main_queue(), wcsdup((const wchar_t *) temp), _ui_window_title); @@ -2069,10 +2135,10 @@ do_pause(int p) do_pause_ack = p; dopause = !!p; if ((p == 1) && !old_p) { - while (!atomic_load(&pause_ack)) + while (!ATOMIC_LOAD(pause_ack)) ; } - atomic_store(&pause_ack, 0); + ATOMIC_STORE(pause_ack, 0); } // Helper to find an accelerator key and return it's index in acc_keys diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index 3b7eaeb3f40..52ea9797206 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1469,8 +1469,10 @@ cdrom_seek(cdrom_t *dev, const uint32_t pos, const uint8_t vendor_type) break; } - dev->seek_pos = real_pos; cdrom_stop(dev); + + dev->seek_pos = real_pos; + dev->cached_sector = -1; } int diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 816a563d893..6452868abcf 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -1803,6 +1803,16 @@ image_load_cue(cd_image_t *img, const char *cuefile) lo_cmd = 0; image_log(img->log, " [SESSION ] Initialization successful\n"); + } else if (!strcmp(command, "TAOGAP")) { + ci = &(ct->idx[2]); + + ci->type = INDEX_ZERO; + ci->file = tf; + success = image_cue_get_frame(&frame, &line); + ci->length = frame; + + image_log(img->log, " [INDEX ] 02 (%8s): Initialization %s\n", + cit[ci->type + 2], success ? "successful" : "failed"); } } } diff --git a/src/cdrom/cdrom_mke.c b/src/cdrom/cdrom_mke.c index 98ae6c05723..1b0471f01b3 100644 --- a/src/cdrom/cdrom_mke.c +++ b/src/cdrom/cdrom_mke.c @@ -531,7 +531,6 @@ mke_command(mke_t *mke, uint8_t value) uint16_t i; /* This is wasteful handling of buffers for compatibility, but will optimize later. */ uint8_t x[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - int old_cd_status; if (mke->command_buffer_pending) { mke->command_buffer[6 - mke->command_buffer_pending + 1] = value; @@ -769,7 +768,6 @@ mke_command(mke_t *mke, uint8_t value) } break; case CMD1_SEEK: - old_cd_status = mke->cdrom_dev->cd_status; fifo8_reset(&mke->info_fifo); CHECK_READY_READ(); /* TODO: DOES THIS IMPACT CURRENT PLAY LENGTH? */ @@ -782,10 +780,6 @@ mke_command(mke_t *mke, uint8_t value) /* Note for self: Panasonic/MKE drives send seek commands in MSF format. */ cdrom_seek(mke->cdrom_dev, MSFtoLBA(mke->command_buffer[1], mke->command_buffer[2], mke->command_buffer[3]) - 150, 0); - if ((old_cd_status == CD_STATUS_PLAYING) || (old_cd_status == CD_STATUS_PAUSED)) { - cdrom_audio_play(mke->cdrom_dev, mke->cdrom_dev->seek_pos, -1, 0); - cdrom_audio_pause_resume(mke->cdrom_dev, old_cd_status == CD_STATUS_PLAYING); - } fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; case CMD1_SESSINFO: @@ -832,6 +826,9 @@ mke_command(mke_t *mke, uint8_t value) break; default: mke_log("MKE: Unknown Commnad [%02x]\n", mke->command_buffer[0]); + fifo8_reset(&mke->info_fifo); + fifo8_push_all(&mke->info_fifo, x, 6); + fifo8_push(&mke->info_fifo, mke_cdrom_status(mke->cdrom_dev, mke)); break; } } else if (!mke->command_buffer_pending) { @@ -1041,6 +1038,7 @@ static const device_config_t mke_config[] = { { .description = "320H", .value = 0x320 }, { .description = "330H", .value = 0x330 }, { .description = "340H", .value = 0x340 }, + { .description = "630H", .value = 0x630 }, { NULL } }, .bios = { { 0 } } diff --git a/src/chipset/cs8220.c b/src/chipset/cs8220.c index 3c3c237675b..34229d53664 100644 --- a/src/chipset/cs8220.c +++ b/src/chipset/cs8220.c @@ -218,25 +218,19 @@ cs8220_init(UNUSED(const device_t *info)) dev->ram_banks[0].virt = 0x00000000; dev->ram_banks[0].phys = 0x00000000; dev->ram_banks[0].size = 0x00080000; - dev->ram_banks[1].virt = 0x00080000; - dev->ram_banks[1].phys = 0x00080000; - dev->ram_banks[1].size = 0x00020000; - /* Pretend there's a 128k expansion. */ + /* Pretend there's a 256k expansion. */ dev->ram_banks[2].virt = 0x00100000; dev->ram_banks[2].phys = 0x00080000; - dev->ram_banks[2].size = 0x00020000; + dev->ram_banks[2].size = 0x00040000; break; case 896: dev->ram_banks[0].virt = 0x00000000; dev->ram_banks[0].phys = 0x00000000; dev->ram_banks[0].size = 0x00080000; - dev->ram_banks[1].virt = 0x00080000; - dev->ram_banks[1].phys = 0x00080000; - dev->ram_banks[1].size = 0x00020000; - /* Pretend there's a 256k expansion. */ + /* Pretend there's a 384k expansion. */ dev->ram_banks[2].virt = 0x00100000; dev->ram_banks[2].phys = 0x00080000; - dev->ram_banks[2].size = 0x00040000; + dev->ram_banks[2].size = 0x00060000; break; case 1024: dev->ram_banks[0].virt = 0x00000000; @@ -248,23 +242,31 @@ cs8220_init(UNUSED(const device_t *info)) break; } - if (dev->ram_banks[0].size > 0x00000000) + mem_set_mem_state(0x00000000, (mem_size << 10) + 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); + + if (dev->ram_banks[0].size > 0x00000000) { mem_mapping_add(&dev->ram_banks[0].mapping, dev->ram_banks[0].virt, dev->ram_banks[0].size, cs8220_mem_read, cs8220_mem_readw, NULL, cs8220_mem_write, cs8220_mem_writew, NULL, ram + dev->ram_banks[0].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[0])); + mem_set_mem_state(dev->ram_banks[0].virt, dev->ram_banks[0].size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } - if (dev->ram_banks[1].size > 0x00000000) + if (dev->ram_banks[1].size > 0x00000000) { mem_mapping_add(&dev->ram_banks[1].mapping, dev->ram_banks[1].virt, dev->ram_banks[1].size, cs8220_mem_read, cs8220_mem_readw, NULL, cs8220_mem_write, cs8220_mem_writew, NULL, ram + dev->ram_banks[1].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[1])); + mem_set_mem_state(dev->ram_banks[1].virt, dev->ram_banks[1].size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } - if (dev->ram_banks[2].size > 0x00000000) + if (dev->ram_banks[2].size > 0x00000000) { mem_mapping_add(&dev->ram_banks[2].mapping, dev->ram_banks[2].virt, dev->ram_banks[2].size, cs8220_mem_read, cs8220_mem_readw, NULL, cs8220_mem_write, cs8220_mem_writew, NULL, ram + dev->ram_banks[2].phys, MEM_MAPPING_INTERNAL, &(dev->ram_banks[2])); + mem_set_mem_state(dev->ram_banks[2].virt, dev->ram_banks[2].size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } io_sethandler(0x00a4, 0x0002, cs8220_in, NULL, NULL, cs8220_out, NULL, NULL, dev); diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index f48950cdc83..32df440981e 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1376,13 +1376,12 @@ piix_reset_hard(piix_t *dev) if (dev->type < 5) fregs[0x20] = 0x01; fregs[0x3d] = 0x04; - if (dev->type > 4) - fregs[0x60] = (dev->type > 3) ? 0x10 : 0x00; if (dev->type < 5) { + fregs[0x60] = (dev->type > 3) ? 0x10 : 0x00; fregs[0x6a] = (dev->type == 3) ? 0x01 : 0x00; fregs[0xc1] = 0x20; fregs[0xff] = (dev->type > 3) ? 0x10 : 0x00; - } + } else dev->max_func = 2; /* It starts with USB disabled, then enables it. */ } diff --git a/src/chipset/scamp.c b/src/chipset/scamp.c index 9019809b559..ba33bea393f 100644 --- a/src/chipset/scamp.c +++ b/src/chipset/scamp.c @@ -92,7 +92,7 @@ typedef struct ram_struct_t { int bank; } ram_struct_t; -typedef struct card_mem_t { +typedef struct mem_page_t { int in_ram; uint32_t virt_addr; uint32_t phys_addr; @@ -124,10 +124,6 @@ typedef struct scamp_t { mem_mapping_t mem_mappings[64]; /* The entire first 1 MB of memory space. */ mem_page_t mem_pages[64]; - uint32_t card_mem_size; - uint8_t *card_mem; - mem_page_t card_pages[4]; - port_92_t *port_92; } scamp_t; @@ -1180,14 +1176,6 @@ scamp_init(UNUSED(const device_t *info)) } } - dev->card_mem = NULL; - - for (uint8_t i = 0; i < 4; i++) { - dev->card_pages[i].virt_addr = i * EMS_PGSIZE; - dev->card_pages[i].phys_addr = dev->card_pages[i].virt_addr; - dev->card_pages[i].mem = dev->card_mem + dev->card_pages[i].phys_addr; - } - dev->port_92 = device_add(&port_92_device); return dev; diff --git a/src/chipset/sis_5571_h2p.c b/src/chipset/sis_5571_h2p.c index a285534871a..3ebb5f2404d 100644 --- a/src/chipset/sis_5571_h2p.c +++ b/src/chipset/sis_5571_h2p.c @@ -392,7 +392,6 @@ sis_5571_host_to_pci_reset(void *priv) dev->pci_conf[0x91] = 0x00; dev->pci_conf[0x92] = 0x00; dev->pci_conf[0x93] = 0x00; - dev->pci_conf[0x93] = 0x00; dev->pci_conf[0x94] = 0x00; dev->pci_conf[0x95] = 0x00; dev->pci_conf[0x96] = 0x00; diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 974f4e27421..3236bbbbe89 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -348,7 +348,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x58: - if ((dev->id >= VIA_585) || (dev->id < VIA_597) || (dev->id == VIA_597) || ((dev->id >= VIA_693A) || (dev->id < VIA_8601))) + if ((dev->id >= VIA_585) || (dev->id < VIA_597) || (dev->id == VIA_597) || ((dev->id >= VIA_693A) && (dev->id < VIA_8601))) dev->pci_conf[0x58] = (dev->pci_conf[0x58] & ~0xee) | (val & 0xee); else dev->pci_conf[0x58] = val; @@ -501,14 +501,14 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) break; case 0x69: if ((dev->id != VIA_585) || (dev->id != VIA_595)) { - if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) + if ((dev->id == VIA_693A) && (dev->id < VIA_8601)) dev->pci_conf[0x69] = (dev->pci_conf[0x69] & ~0xfe) | (val & 0xfe); else dev->pci_conf[0x69] = val; } break; case 0x6b: - if ((dev->id == VIA_693A) || (dev->id < VIA_8601)) + if ((dev->id == VIA_693A) && (dev->id < VIA_8601)) dev->pci_conf[0x6b] = val; else if (dev->id == VIA_691) dev->pci_conf[0x6b] = (dev->pci_conf[0x6b] & ~0xcf) | (val & 0xcf); @@ -520,7 +520,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) dev->pci_conf[0x6b] = (dev->pci_conf[0x6b] & ~0xc1) | (val & 0xc1); break; case 0x6c: - if ((dev->id == VIA_597) || ((dev->id == VIA_693A) || (dev->id < VIA_8601))) + if ((dev->id == VIA_597) || ((dev->id == VIA_693A) && (dev->id < VIA_8601))) dev->pci_conf[0x6c] = (dev->pci_conf[0x6c] & ~0x1f) | (val & 0x1f); else if (dev->id == VIA_598) dev->pci_conf[0x6c] = (dev->pci_conf[0x6c] & ~0x7f) | (val & 0x7f); diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index a4d83220bec..a476b9b9900 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -987,7 +987,7 @@ pipc_read(int func, int addr, void *priv) } } else if ((func <= (pm_func + 2)) && !(dev->pci_isa_regs[0x85] & ((func == (pm_func + 1)) ? 0x04 : 0x08))) { /* AC97 / MC97 */ if (addr == 0x40) - ret = ac97_via_read_status(dev->ac97, func - pm_func - 1); + ret = ac97_via_read_status(dev->ac97); else ret = dev->ac97_regs[func - pm_func - 1][addr]; } @@ -1583,7 +1583,7 @@ pipc_write(int func, int addr, uint8_t val, void *priv) case 0x41: dev->ac97_regs[func][addr] = val; - ac97_via_write_control(dev->ac97, func, val); + ac97_via_write_control(dev->ac97, val); break; case 0x42: diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 915cae93dce..9d5806edf04 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -102,6 +102,10 @@ # define OPCODE_SUB_LSR (0x25a << 21) # define OPCODE_SUBX_LSL (0x658 << 21) +# define OPCODE_INS_B (0x6e010400) +# define OPCODE_INS_H (0x6e020400) +# define OPCODE_INS_S (0x6e040400) +# define OPCODE_INS_D (0x6e080400) # define OPCODE_ADD_V8B (0x0e208400) # define OPCODE_ADD_V4H (0x0e608400) # define OPCODE_ADD_V2S (0x0ea08400) @@ -180,6 +184,7 @@ # define OPCODE_SQSUB_V8B (0x0e202c00) # define OPCODE_SQSUB_V4H (0x0e602c00) # define OPCODE_SQXTN_V8B_8H (0x0e214800) +# define OPCODE_SQXTUN_V8B_8H (0x2e212800) # define OPCODE_SQXTN_V4H_4S (0x0e614800) # define OPCODE_SHL_VD (0x0f005400) # define OPCODE_SHL_VQ (0x4f005400) @@ -207,6 +212,7 @@ # define OPCODE_ZIP1_V8B (0x0e003800) # define OPCODE_ZIP1_V4H (0x0e403800) # define OPCODE_ZIP1_V2S (0x0e803800) +# define OPCODE_ZIP1_V2D (0x4ec03800) # define OPCODE_ZIP2_V8B (0x0e007800) # define OPCODE_ZIP2_V4H (0x0e407800) # define OPCODE_ZIP2_V2S (0x0e807800) @@ -225,11 +231,11 @@ # define IMM_LOGICAL(imm) ((imm) << 10) -# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) +# define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) # define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) # define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) # define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) # define OFFSET12_B(offset) (offset << 10) @@ -716,6 +722,12 @@ host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } +void +host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index) +{ + codegen_addlong(block, OPCODE_INS_D | Rd(dst_reg) | Rn(src_reg) | ((dst_index & 1) << 20) | ((src_index & 1) << 14)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { @@ -1225,6 +1237,13 @@ host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } + +void +host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SQXTUN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { @@ -1475,6 +1494,11 @@ host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_re codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } void +host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V2D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index df751b4aa65..129c2b2a381 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -72,6 +72,7 @@ void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element); +void host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index); void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); @@ -184,6 +185,7 @@ void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); @@ -243,6 +245,7 @@ void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 2bb6281ff2c..d06685cb207 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -801,7 +801,8 @@ codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 1); + host_arm64_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); return 0; } @@ -849,28 +850,28 @@ codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG0, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG1, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG2, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG3, uop->imm_data); return 0; } @@ -1448,9 +1449,9 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1465,9 +1466,9 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) int src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTN_V4H_4S(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1480,9 +1481,9 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); + host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index d14fa0f23b7..7c34a69e5f1 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -53,6 +53,9 @@ duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) new_uop->imm_data = uop->imm_data; new_uop->p = uop->p; new_uop->pc = uop->pc; +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 + new_uop->is_a16 = uop->is_a16; +#endif if (uop->jump_dest_uop != -1) { new_uop->jump_dest_uop = uop->jump_dest_uop + offset; diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 60f7badea1a..bec1607e0cd 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -336,7 +336,11 @@ typedef struct uop_t { ir_reg_t src_reg_a; ir_reg_t src_reg_b; ir_reg_t src_reg_c; +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 + uintptr_t imm_data; +#else uint32_t imm_data; +#endif void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; @@ -601,7 +605,11 @@ uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_re } static inline void +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uintptr_t imm) +#else uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +#endif { uop_t *uop = uop_alloc(ir, uop_type); @@ -660,6 +668,9 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr uop->p = p; } +extern int codegen_mmx_enter(void); +extern int codegen_fp_enter(void); + #define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) #define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) @@ -724,6 +735,28 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr #define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) #define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +#define uop_FP_ENTER(ir) \ + do { \ + if (!codegen_fpu_entered) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_fp_enter); \ + uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ + } \ + codegen_fpu_entered = 1; \ + codegen_mmx_entered = 0; \ + } while (0) +#define uop_MMX_ENTER(ir) \ + do { \ + if (!codegen_mmx_entered) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + uop_CALL_FUNC_RESULT(ir, IREG_temp0, codegen_mmx_enter); \ + uop_CMP_IMM_JZ(ir, IREG_temp0, 1, codegen_exit_rout); \ + } \ + codegen_mmx_entered = 1; \ + codegen_fpu_entered = 0; \ + } while (0) +#else #define uop_FP_ENTER(ir) \ do { \ if (!codegen_fpu_entered) \ @@ -738,6 +771,7 @@ uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int sr codegen_mmx_entered = 1; \ codegen_fpu_entered = 0; \ } while (0) +#endif #define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) #define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index bb7d1f3ee86..68861ff5257 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -86,13 +86,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -100,13 +95,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif @@ -119,13 +112,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -133,13 +121,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif // clang-format on diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index f91377df8f9..234cfe3a262 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -201,7 +201,11 @@ static const uint8_t native_requested_sizes[9][8] = [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 + [REG_POINTER][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1 +#else [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 +#endif }; void diff --git a/src/config.c b/src/config.c index a06d9e8b438..86dc95ccaf1 100644 --- a/src/config.c +++ b/src/config.c @@ -339,6 +339,7 @@ load_machine(void) { .old = "infinia7200", .new = "tc430hx", .new_bios = "infinia7200" }, { .old = "dellvenus", .new = "vs440fx", .new_bios = "dellvenus" }, { .old = "gw2kvenus", .new = "vs440fx", .new_bios = "gw2kvenus" }, + { .old = "lgibmx7g", .new = "ms6119", .new_bios = "lgibmx7g" }, { 0 } }; @@ -569,6 +570,7 @@ load_input_devices(void) { ini_section_t cat = ini_find_section(config, "Input devices"); char temp[512]; + char tmp2[32]; char *p; p = ini_section_get_string(cat, "keyboard_type", NULL); @@ -646,18 +648,25 @@ load_input_devices(void) joystick_state[gp][js].plat_joystick_nr = ini_section_get_int(cat, temp, 0); if (joystick_state[gp][js].plat_joystick_nr) { + // --- Load Axis Mappings --- for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[joy_insn]); axis_nr++) { sprintf(temp, "joystick_%i_axis_%i", js, axis_nr); joystick_state[gp][js].axis_mapping[axis_nr] = ini_section_get_int(cat, temp, axis_nr); } + + // --- Load Button Mappings --- for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[joy_insn]); button_nr++) { sprintf(temp, "joystick_%i_button_%i", js, button_nr); joystick_state[gp][js].button_mapping[button_nr] = ini_section_get_int(cat, temp, button_nr); } + + // --- Load POV (Hat Switch) Mappings --- for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[joy_insn]); pov_nr++) { sprintf(temp, "joystick_%i_pov_%i", js, pov_nr); - p = ini_section_get_string(cat, temp, "0, 0"); - joystick_state[gp][js].pov_mapping[pov_nr][0] = joystick_state[gp][js].pov_mapping[pov_nr][1] = 0; + sprintf(tmp2, "%i, %i", 0, 0); + p = ini_section_get_string(cat, temp, tmp2); + joystick_state[gp][js].pov_mapping[pov_nr][0] = 0; + joystick_state[gp][js].pov_mapping[pov_nr][1] = 0; sscanf(p, "%i, %i", &joystick_state[gp][js].pov_mapping[pov_nr][0], &joystick_state[gp][js].pov_mapping[pov_nr][1]); } @@ -938,11 +947,35 @@ load_ports(void) #endif } +static char * +memrmem(char *src, char *start, char *what) +{ + if ((src == NULL) || (what == NULL)) + return NULL; + + while (1) { + if (memcmp(src, what, strlen(what)) == 0) + return src; + src--; + if (src < start) + return NULL; + } +} + static int load_image_file(char *dest, char *p, uint8_t *ui_wp) { char *prefix = ""; int ret = 0; + char *slash = NULL; + char *above = NULL; + char *use = NULL; + + if ((slash = memrmem(usr_path + strlen(usr_path) - 2, usr_path, "/")) != NULL) { + slash++; + above = (char *) calloc(1, slash - usr_path + 1); + memcpy(above, usr_path, slash - usr_path); + } if (strstr(p, "wp://") == p) { p += 5; @@ -952,7 +985,33 @@ load_image_file(char *dest, char *p, uint8_t *ui_wp) } else if ((ui_wp != NULL) && *ui_wp) prefix = "wp://"; - if (path_abs(p)) { + if (strstr(p, "ioctl://") == p) { + if (strlen(p) > (MAX_IMAGE_PATH_LEN - 11)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s", p); + + if (above != NULL) + free(above); + + return ret; + } + + if (memcmp(p, "/", strlen("/")) == 0) { + if ((strlen(prefix) + strlen(exe_path) + strlen(path_get_slash(exe_path)) + strlen(p + strlen("/"))) > + (MAX_IMAGE_PATH_LEN - 11)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, exe_path, path_get_slash(exe_path), + p + strlen("/")); + } else if (memcmp(p, "../", strlen("../")) == 0) { + use = (above == NULL) ? usr_path : above; + if ((strlen(prefix) + strlen(use) + strlen(path_get_slash(use)) + strlen(p + strlen("../"))) > + (MAX_IMAGE_PATH_LEN - 11)) + ret = 1; + else + snprintf(dest, MAX_IMAGE_PATH_LEN, "%s%s%s%s", prefix, use, path_get_slash(use), p + strlen("../")); + } else if (path_abs(p)) { if ((strlen(prefix) + strlen(p)) > (MAX_IMAGE_PATH_LEN - 11)) ret = 1; else @@ -966,6 +1025,9 @@ load_image_file(char *dest, char *p, uint8_t *ui_wp) path_normalize(dest); + if (above != NULL) + free(above); + return ret; } @@ -1135,15 +1197,8 @@ load_storage_controllers(void) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of cartridge_%02i_fn is more than 511\n", - c + 1); - else - strncpy(cart_fns[c], p, 511); - } else - path_append_filename(cart_fns[c], usr_path, p); - path_normalize(cart_fns[c]); + if (load_image_file(cart_fns[c], p, NULL)) + fatal("Configuration: Length of cartridge_%02i_fn is more than 511\n", c + 1); } for (int i = 0; i < MAX_PREV_IMAGES; i++) { @@ -1151,16 +1206,9 @@ load_storage_controllers(void) sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of cartridge_%02i_image_history_%02i " - "is more than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(cart_image_history[c][i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(cart_image_history[c][i]); + if (load_image_file(cart_image_history[c][i], p, NULL)) + fatal("Configuration: Length of cartridge_%02i_image_history_%02i " + "is more than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } } @@ -1324,17 +1372,15 @@ load_hard_disks(void) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of hdd_%02i_fn is more " - "than 511\n", c + 1); - else - strncpy(hdd[c].fn, p, 511); - } else - path_append_filename(hdd[c].fn, usr_path, p); - path_normalize(hdd[c].fn); + if (load_image_file(hdd[c].fn, p, NULL)) + fatal("Configuration: Length of hdd_%02i_fn is more than 511\n", c + 1); } +#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) + if (*p != '\0') + config_log("HDD%d: %ls\n", c, hdd[c].fn); +#endif + sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1); hdd[c].vhd_blocksize = ini_section_get_int(cat, temp, 0); @@ -1422,6 +1468,7 @@ load_floppy_and_cdrom_drives(void) if (*p != '\0') config_log("Floppy%d: %ls\n", c, floppyfns[c]); #endif + sprintf(temp, "fdd_%02i_turbo", c + 1); fdd_set_turbo(c, !!ini_section_get_int(cat, temp, 0)); sprintf(temp, "fdd_%02i_check_bpb", c + 1); @@ -1493,7 +1540,7 @@ load_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_type", c + 1); p = ini_section_get_string(cat, temp, cdrom[c].bus_type == CDROM_BUS_MKE ? "cr563" : "86cd"); /* TODO: Configuration migration, remove when no longer needed. */ - int cdrom_type = cdrom_get_from_internal_name(p); + int cdrom_type = cdrom_get_from_internal_name(!strcmp(p, "goldstar") ? "goldstar_r560b" : p); if (cdrom_type == -1) { cdrom_type = cdrom_get_from_name(p); if (cdrom_type == -1) @@ -1577,31 +1624,23 @@ load_floppy_and_cdrom_drives(void) p[0] = 0x00; if (p[0] != 0x00) { - if (path_abs(p)) { - if (strlen(p) > 511) - fatal("Configuration: Length of cdrom_%02i_image_path is more than 511\n", c + 1); - else - strncpy(cdrom[c].image_path, p, 511); - } else - path_append_filename(cdrom[c].image_path, usr_path, p); - path_normalize(cdrom[c].image_path); + if (load_image_file(cdrom[c].image_path, p, NULL)) + fatal("Configuration: Length of cdrom_%02i_image_path is more than 511\n", c + 1); } +#if defined(ENABLE_CONFIG_LOG) && (ENABLE_CONFIG_LOG == 2) + if (*p != '\0') + config_log("CD-ROM%d: %ls\n", c, cdrom[c].image_path); +#endif + for (int i = 0; i < MAX_PREV_IMAGES; i++) { cdrom[c].image_history[i] = (char *) calloc((MAX_IMAGE_PATH_LEN + 1) << 1, sizeof(char)); sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); p = ini_section_get_string(cat, temp, NULL); if (p) { - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("Configuration: Length of cdrom_%02i_image_history_%02i is more " - "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); - else - snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s", p); - } else - snprintf(cdrom[c].image_history[i], MAX_IMAGE_PATH_LEN, "%s%s%s", usr_path, - path_get_slash(usr_path), p); - path_normalize(cdrom[c].image_history[i]); + if (load_image_file(cdrom[c].image_history[i], p, NULL)) + fatal("Configuration: Length of cdrom_%02i_image_history_%02i is more " + "than %i\n", c + 1, i + 1, MAX_IMAGE_PATH_LEN - 1); } } @@ -2702,7 +2741,7 @@ save_input_devices(void) { ini_section_t cat = ini_find_or_create_section(config, "Input devices"); char temp[512]; - char tmp2[512]; + char tmp2[32]; ini_section_set_string(cat, "keyboard_type", keyboard_get_internal_name(keyboard_type)); @@ -2713,20 +2752,25 @@ save_input_devices(void) ini_section_delete_var(cat, "joystick_type"); for (int js = 0; js < MAX_PLAT_JOYSTICKS; js++) { - sprintf(tmp2, "joystick_%i_nr", js); - ini_section_delete_var(cat, tmp2); + sprintf(temp, "joystick_%i_nr", js); + ini_section_delete_var(cat, temp); + // --- Save Axis Mappings --- for (int axis_nr = 0; axis_nr < MAX_JOY_AXES; axis_nr++) { - sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr); - ini_section_delete_var(cat, tmp2); + sprintf(temp, "joystick_%i_axis_%i", js, axis_nr); + ini_section_delete_var(cat, temp); } + + // --- Save Button Mappings --- for (int button_nr = 0; button_nr < MAX_JOY_BUTTONS; button_nr++) { - sprintf(tmp2, "joystick_%i_button_%i", js, button_nr); - ini_section_delete_var(cat, tmp2); + sprintf(temp, "joystick_%i_button_%i", js, button_nr); + ini_section_delete_var(cat, temp); } + + // --- Save POV (Hat Switch) Mappings --- for (int pov_nr = 0; pov_nr < MAX_JOY_POVS; pov_nr++) { - sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr); - ini_section_delete_var(cat, tmp2); + sprintf(temp, "joystick_%i_pov_%i", js, pov_nr); + ini_section_delete_var(cat, temp); } } } else { @@ -2735,33 +2779,37 @@ save_input_devices(void) ini_section_set_string(cat, "joystick_type", joystick_get_internal_name(joystick_type[joy_insn])); for (int js = 0; js < joystick_get_max_joysticks(joystick_type[joy_insn]); js++) { - sprintf(tmp2, "joystick_%i_nr", js); - ini_section_set_int(cat, tmp2, joystick_state[gp][js].plat_joystick_nr); + sprintf(temp, "joystick_%i_nr", js); + ini_section_set_int(cat, temp, joystick_state[gp][js].plat_joystick_nr); if (joystick_state[gp][js].plat_joystick_nr) { + // --- Save Axis Mappings --- for (int axis_nr = 0; axis_nr < joystick_get_axis_count(joystick_type[joy_insn]); axis_nr++) { - sprintf(tmp2, "joystick_%i_axis_%i", js, axis_nr); - ini_section_set_int(cat, tmp2, joystick_state[gp][js].axis_mapping[axis_nr]); + sprintf(temp, "joystick_%i_axis_%i", js, axis_nr); + ini_section_set_int(cat, temp, joystick_state[gp][js].axis_mapping[axis_nr]); } + + // --- Save Button Mappings --- for (int button_nr = 0; button_nr < joystick_get_button_count(joystick_type[joy_insn]); button_nr++) { - sprintf(tmp2, "joystick_%i_button_%i", js, button_nr); - ini_section_set_int(cat, tmp2, joystick_state[gp][js].button_mapping[button_nr]); + sprintf(temp, "joystick_%i_button_%i", js, button_nr); + ini_section_set_int(cat, temp, joystick_state[gp][js].button_mapping[button_nr]); } + + // --- Save POV (Hat Switch) Mappings --- for (int pov_nr = 0; pov_nr < joystick_get_pov_count(joystick_type[joy_insn]); pov_nr++) { - sprintf(tmp2, "joystick_%i_pov_%i", js, pov_nr); - sprintf(temp, "%i, %i", joystick_state[gp][js].pov_mapping[pov_nr][0], - joystick_state[gp][js].pov_mapping[pov_nr][1]); - ini_section_set_string(cat, tmp2, temp); + sprintf(temp, "joystick_%i_pov_%i", js, pov_nr); + sprintf(tmp2, "%i, %i", joystick_state[gp][js].pov_mapping[pov_nr][0], + joystick_state[gp][js].pov_mapping[pov_nr][1]); + ini_section_set_string(cat, temp, tmp2); } } } } - if (tablet_tool_type != 1) { + if (tablet_tool_type != 1) ini_section_set_int(cat, "tablet_tool_type", tablet_tool_type); - } else { + else ini_section_delete_var(cat, "tablet_tool_type"); - } ini_delete_section_if_empty(config, cat); } @@ -3035,6 +3083,14 @@ save_image_file(char *cat, char *var, char *src) { char temp[2048] = { 0 }; char *prefix = ""; + char *slash = NULL; + char *above = NULL; + + if ((slash = memrmem(usr_path + strlen(usr_path) - 2, usr_path, "/")) != NULL) { + slash++; + above = (char *) calloc(1, slash - usr_path + 1); + memcpy(above, usr_path, slash - usr_path); + } path_normalize(src); @@ -3043,12 +3099,21 @@ save_image_file(char *cat, char *var, char *src) prefix = "wp://"; } - if (!strnicmp(src, usr_path, strlen(usr_path))) + if (strstr(src, "ioctl://") == src) + sprintf(temp, "%s", src); + else if (!strnicmp(src, usr_path, strlen(usr_path))) sprintf(temp, "%s%s", prefix, &src[strlen(usr_path)]); + else if ((above != NULL) && !strnicmp(src, above, strlen(above))) + sprintf(temp, "../%s%s", prefix, &src[strlen(above)]); + else if (!strnicmp(src, exe_path, strlen(exe_path))) + sprintf(temp, "/%s%s", prefix, &src[strlen(exe_path)]); else sprintf(temp, "%s%s", prefix, src); ini_section_set_string(cat, var, temp); + + if (above != NULL) + free(above); } /* Save "Storage Controllers" section. */ @@ -3168,25 +3233,15 @@ save_storage_controllers(void) if (strlen(cart_fns[c]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(cart_fns[c]); - if (!strnicmp(cart_fns[c], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cart_fns[c][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cart_fns[c]); - } + else + save_image_file(cat, temp, cart_fns[c]); for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "cartridge_%02i_image_history_%02i", c + 1, i + 1); if ((cart_image_history[c][i] == 0) || strlen(cart_image_history[c][i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(cart_image_history[c][i]); - if (!strnicmp(cart_image_history[c][i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cart_image_history[c][i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cart_image_history[c][i]); - } + else + save_image_file(cat, temp, cart_image_history[c][i]); } } @@ -3357,13 +3412,9 @@ save_hard_disks(void) } sprintf(temp, "hdd_%02i_fn", c + 1); - if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) { - path_normalize(hdd[c].fn); - if (!strnicmp(hdd[c].fn, usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &hdd[c].fn[strlen(usr_path)]); - else - ini_section_set_string(cat, temp, hdd[c].fn); - } else + if (hdd_is_valid(c) && (strlen(hdd[c].fn) != 0)) + save_image_file(cat, temp, hdd[c].fn); + else ini_section_delete_var(cat, temp); sprintf(temp, "hdd_%02i_vhd_blocksize", c + 1); @@ -3524,25 +3575,15 @@ save_floppy_and_cdrom_drives(void) sprintf(temp, "cdrom_%02i_image_path", c + 1); if ((cdrom[c].bus_type == 0) || (strlen(cdrom[c].image_path) == 0)) ini_section_delete_var(cat, temp); - else { - path_normalize(cdrom[c].image_path); - if (!strnicmp(cdrom[c].image_path, usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cdrom[c].image_path[strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cdrom[c].image_path); - } + else + save_image_file(cat, temp, cdrom[c].image_path); for (int i = 0; i < MAX_PREV_IMAGES; i++) { sprintf(temp, "cdrom_%02i_image_history_%02i", c + 1, i + 1); if ((cdrom[c].image_history[i] == 0) || strlen(cdrom[c].image_history[i]) == 0) ini_section_delete_var(cat, temp); - else { - path_normalize(cdrom[c].image_history[i]); - if (!strnicmp(cdrom[c].image_history[i], usr_path, strlen(usr_path))) - ini_section_set_string(cat, temp, &cdrom[c].image_history[i][strlen(usr_path)]); - else - ini_section_set_string(cat, temp, cdrom[c].image_history[i]); - } + else + save_image_file(cat, temp, cdrom[c].image_history[i]); } } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 23f3f1e3514..ff729e4cfe4 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -242,6 +242,20 @@ static uint64_t tsc_old = 0; int32_t acycs = 0; # endif +int +codegen_mmx_enter(void) +{ + MMX_ENTER(); + return 0; +} + +int +codegen_fp_enter(void) +{ + FP_ENTER(); + return 0; +} + void update_tsc(void) { @@ -405,7 +419,7 @@ exec386_dynarec_dyn(void) uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); # ifdef USE_NEW_DYNAREC int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ULL << (PAGE_BYTE_MASK_MASK & 0x3f); + uint64_t byte_mask = 1ULL << (phys_addr & PAGE_BYTE_MASK_MASK); if ((page->code_present_mask & mask) || ((page->mem != page_ff) && (page->byte_code_present_mask[byte_offset] & byte_mask))) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index bdd93ec5b7b..8d00da512c9 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1550,7 +1550,7 @@ cpu_set(void) if ((cpu_s->cpu_type == CPU_Cx6x86L) || (cpu_s->cpu_type == CPU_Cx6x86MX)) ccr4 = 0x80; - else if (CPU_Cx6x86) + else if (cpu_s->cpu_type == CPU_Cx6x86) CPUID = 0; /* Disabled on powerup by default */ break; diff --git a/src/device.c b/src/device.c index cd5adfee07a..98d4794cfed 100644 --- a/src/device.c +++ b/src/device.c @@ -396,143 +396,69 @@ device_available(const device_t *dev) return ret; } -uint8_t -device_get_bios_type(const device_t *dev, const char *internal_name) +static const device_config_bios_t * +device_get_bios(const device_t *dev, const char *internal_name) { if (dev != NULL) { const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - if (!strcmp(internal_name, bios->internal_name)) - return bios->bios_type; - bios++; - } + while (config && (config->type != CONFIG_END)) { + if (config->type == CONFIG_BIOS) { + const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; + + /* Go through the ROMs in the device configuration. */ + while ((bios != NULL) && + (bios->name != NULL) && + (bios->internal_name != NULL) && + (bios->files_no != 0)) { + if (!strcmp(internal_name, bios->internal_name)) + return bios; + bios++; } - config++; + + /* Unknown value, fall back to the default ROMs. */ + if (strcmp(internal_name, config->default_string)) + return device_get_bios(dev, config->default_string); } + config++; } } - return 0; + return NULL; } uint8_t -device_get_bios_num_files(const device_t *dev, const char *internal_name) +device_get_bios_type(const device_t *dev, const char *internal_name) { - if (dev != NULL) { - const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - if (!strcmp(internal_name, bios->internal_name)) - return bios->files_no; - bios++; - } - } - config++; - } - } - } + const device_config_bios_t *bios = device_get_bios(dev, internal_name); + return bios ? bios->bios_type : 0; +} - return 0; +uint8_t +device_get_bios_num_files(const device_t *dev, const char *internal_name) +{ + const device_config_bios_t *bios = device_get_bios(dev, internal_name); + return bios ? bios->files_no : 0; } uint32_t device_get_bios_local(const device_t *dev, const char *internal_name) { - if (dev != NULL) { - const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - if (!strcmp(internal_name, bios->internal_name)) - return bios->local; - bios++; - } - } - config++; - } - } - } - - return 0; + const device_config_bios_t *bios = device_get_bios(dev, internal_name); + return bios ? bios->local : 0; } uint32_t device_get_bios_file_size(const device_t *dev, const char *internal_name) { - if (dev != NULL) { - const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - - /* Go through the ROM's in the device configuration. */ - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - if (!strcmp(internal_name, bios->internal_name)) - return bios->size; - bios++; - } - } - config++; - } - } - } - - return 0; + const device_config_bios_t *bios = device_get_bios(dev, internal_name); + return bios ? bios->size : 0; } const char * -device_get_bios_file(const device_t *dev, const char *internal_name, int file_no) +device_get_bios_file(const device_t *dev, const char *internal_name, unsigned int file_no) { - if (dev != NULL) { - const device_config_t *config = dev->config; - if (config != NULL) { - while (config->type != CONFIG_END) { - if (config->type == CONFIG_BIOS) { - const device_config_bios_t *bios = (const device_config_bios_t *) config->bios; - - /* Go through the ROM's in the device configuration. */ - while ((bios != NULL) && - (bios->name != NULL) && - (bios->internal_name != NULL) && - (bios->files_no != 0)) { - if (!strcmp(internal_name, bios->internal_name)) { - if (file_no < bios->files_no) - return bios->files[file_no]; - else - return NULL; - } - bios++; - } - } - config++; - } - } - } - - /* A NULL device is never available. */ - return (NULL); + const device_config_bios_t *bios = device_get_bios(dev, internal_name); + return (bios && (file_no < bios->files_no)) ? bios->files[file_no] : NULL; } int diff --git a/src/device/isamem.c b/src/device/isamem.c index f895127791d..0cd5fddeaac 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -115,6 +115,10 @@ #define RAM_UMAMEM (384 << 10) /* upper memory block */ #define RAM_EXTMEM (1024 << 10) /* start of high memory */ +#define EV159_BASE_MEM (128 << 10) /* size of EV-159 base memory in cs8220 mode*/ +#define EV159_EXT_1536 (1536 << 10) /* start of EV-159 high memory in cs8220 mode*/ +#define EV159_EXT_1024 (1024 << 10) /* start of EV-159 high memory in backfill mode*/ + #define EMS_MAXSIZE (2048 << 10) /* max EMS memory size */ #define EMS_EV159_MAXSIZE (3072 << 10) /* max EMS memory size for EV-159 cards */ #define EMS_LOTECH_MAXSIZE (4096 << 10) /* max EMS memory size for lotech cards */ @@ -635,6 +639,14 @@ isamem_init(const device_t *info) * so check this first. */ t = (addr < RAM_TOPMEM) ? RAM_TOPMEM - addr : 0; + + /* Check for Everex EV-159 cards in CS8220 backfill mode. */ + if ((addr == RAM_TOPMEM) && (dev->board == ISAMEM_EV159_CARD)) { + /* Reserve 128K RAM for base memory. */ + t = EV159_BASE_MEM; + addr -= t; + } + if (t > 0) { /* * We need T bytes to extend that area. @@ -669,6 +681,15 @@ isamem_init(const device_t *info) addr += t; } + /* Assign high memory address for EV-159 in backfill modes. */ + if ((addr == RAM_TOPMEM) && (dev->board == ISAMEM_EV159_CARD)) { + if (dev->start_addr == RAM_TOPMEM) { + addr = EV159_EXT_1536; + } else { + addr = EV159_EXT_1024; + } + } + /* Skip to high memory if needed. */ if ((addr == RAM_TOPMEM) && (tot >= RAM_UMAMEM)) { /* diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 3129cd1c820..56136700329 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -1196,7 +1196,7 @@ isapnp_enable_card(void *priv, uint8_t enable) if ((card->enable) && (dev->current_ld_card != NULL) && (dev->current_ld_card != card)) { dev->current_ld = NULL; dev->current_ld_card = NULL; - } if (!card->enable) { + } else if (!card->enable) { if (dev->isolated_card == card) dev->isolated_card = NULL; if ((dev->current_ld_card == card) && (old_enable != ISAPNP_CARD_FORCE_CONFIG)) { diff --git a/src/device/isartc.c b/src/device/isartc.c index 3ba092eb929..0128dff0a78 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -680,11 +680,9 @@ isartc_init(const device_t *info) case ISARTC_RTC58167: /* Multitech PC-500/PC-500+ onboard RTC */ dev->flags |= FLAG_YEARBCD; - //dev->base_addr = machine_get_config_int("rtc_port"); - dev->base_addr = 0x2c0; + dev->base_addr = machine_get_config_int("rtc_port"); dev->base_addrsz = 8; - //dev->irq = machine_get_config_int("rtc_irq"); - dev->irq = -1; + dev->irq = machine_get_config_int("rtc_irq"); dev->f_rd = rtc58167_read; dev->f_wr = rtc58167_write; dev->nvr.reset = mm67_reset; diff --git a/src/device/keyboard.c b/src/device/keyboard.c index 7806418dd63..e77a5fc1de1 100644 --- a/src/device/keyboard.c +++ b/src/device/keyboard.c @@ -372,7 +372,7 @@ keyboard_input(int down, uint16_t scan) /* kbc_at_log("Received scan code: %03X (%s)\n", scan & 0x1ff, down ? "down" : "up"); */ recv_key_ui[scan & 0x1ff] = down; - if (mouse_capture || !kbd_req_capture || video_fullscreen) { + if (mouse_capture || !kbd_req_capture || (video_fullscreen && !fullscreen_ui_visible)) { recv_key[scan & 0x1ff] = down; key_process(scan & 0x1ff, down); } diff --git a/src/device/mouse.c b/src/device/mouse.c index eb7557faf11..d4ef4c8733e 100644 --- a/src/device/mouse.c +++ b/src/device/mouse.c @@ -107,11 +107,11 @@ static mouse_t mouse_devices[] = { // clang-format on }; -static _Atomic double mouse_x; -static _Atomic double mouse_y; -static atomic_int mouse_z; -static atomic_int mouse_w; -static atomic_int mouse_buttons; +static ATOMIC_DOUBLE mouse_x; +static ATOMIC_DOUBLE mouse_y; +static ATOMIC_INT mouse_z; +static ATOMIC_INT mouse_w; +static ATOMIC_INT mouse_buttons; static int mouse_delta_b; static int mouse_old_b; @@ -208,7 +208,7 @@ mouse_scale_coord_y(double y, int mul) void mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs) { - double real_x = atomic_load(&mouse_x); + double real_x = ATOMIC_LOAD(mouse_x); double smax_x; double rsmin_x; double smin_x; @@ -266,7 +266,7 @@ mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs) if (abs) real_x -= rsmin_x; - atomic_store(&mouse_x, real_x); + ATOMIC_STORE(mouse_x, real_x); } /* It appears all host platforms give us y in the Microsoft format @@ -275,7 +275,7 @@ mouse_subtract_x(int *delta_x, int *o_x, int min, int max, int abs) void mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs) { - double real_y = atomic_load(&mouse_y); + double real_y = ATOMIC_LOAD(mouse_y); double smax_y; double rsmin_y; double smin_y; @@ -339,7 +339,7 @@ mouse_subtract_y(int *delta_y, int *o_y, int min, int max, int invert, int abs) if (invert) real_y = -real_y; - atomic_store(&mouse_y, real_y); + ATOMIC_STORE(mouse_y, real_y); } /* It appears all host platforms give us y in the Microsoft format @@ -356,7 +356,7 @@ mouse_subtract_coords(int *delta_x, int *delta_y, int *o_x, int *o_y, int mouse_wheel_moved(void) { - int ret = !!(atomic_load(&mouse_z)); + int ret = !!(ATOMIC_LOAD(mouse_z)); return ret; } @@ -364,7 +364,7 @@ mouse_wheel_moved(void) int mouse_hwheel_moved(void) { - int ret = !!(atomic_load(&mouse_w)); + int ret = !!(ATOMIC_LOAD(mouse_w)); return ret; } @@ -372,8 +372,8 @@ mouse_hwheel_moved(void) int mouse_moved(void) { - int moved_x = !!((int) floor(ABSD(mouse_scale_coord_x(atomic_load(&mouse_x), 1)))); - int moved_y = !!((int) floor(ABSD(mouse_scale_coord_y(atomic_load(&mouse_y), 1)))); + int moved_x = !!((int) floor(ABSD(mouse_scale_coord_x(ATOMIC_LOAD(mouse_x), 1)))); + int moved_y = !!((int) floor(ABSD(mouse_scale_coord_y(ATOMIC_LOAD(mouse_y), 1)))); /* Convert them to integer so we treat < 1.0 and > -1.0 as 0. */ int ret = (moved_x || moved_y); @@ -390,11 +390,12 @@ mouse_state_changed(void) int hwheel = (mouse_nbut >= 6); int ret; - b = atomic_load(&mouse_buttons); + b = ATOMIC_LOAD(mouse_buttons); mouse_delta_b = (b ^ mouse_old_b); mouse_old_b = b; - ret = mouse_moved() || ((atomic_load(&mouse_z) != 0) && wheel) || ((atomic_load(&mouse_w) != 0) && hwheel) || (mouse_delta_b & b_mask); + ret = mouse_moved() || ((ATOMIC_LOAD(mouse_z) != 0) && wheel) || ((ATOMIC_LOAD(mouse_w) != 0) && hwheel) || + (mouse_delta_b & b_mask); return ret; } @@ -421,8 +422,9 @@ mouse_timer_poll(UNUSED(void *priv)) #endif } +#if !defined(__x86_64__) && !defined(_M_X64) && !defined(__i386__) && !defined(_M_IX86) static void -atomic_double_add(_Atomic double *var, double val) +atomic_double_add(ATOMIC_DOUBLE *var, double val) { double temp = atomic_load(var); @@ -430,29 +432,30 @@ atomic_double_add(_Atomic double *var, double val) atomic_store(var, temp); } +#endif void mouse_scale_fx(double x) { - atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); + ATOMIC_DOUBLE_ADD(mouse_x, ((double) x) * mouse_sensitivity); } void mouse_scale_fy(double y) { - atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); + ATOMIC_DOUBLE_ADD(mouse_y, ((double) y) * mouse_sensitivity); } void mouse_scale_x(int x) { - atomic_double_add(&mouse_x, ((double) x) * mouse_sensitivity); + ATOMIC_DOUBLE_ADD(mouse_x, ((double) x) * mouse_sensitivity); } void mouse_scale_y(int y) { - atomic_double_add(&mouse_y, ((double) y) * mouse_sensitivity); + ATOMIC_DOUBLE_ADD(mouse_y, ((double) y) * mouse_sensitivity); } void @@ -481,31 +484,31 @@ mouse_scale_axis(int axis, int val) void mouse_set_z(int z) { - atomic_fetch_add(&mouse_z, z); + ATOMIC_ADD(mouse_z, z); } void mouse_clear_z(void) { - atomic_store(&mouse_z, 0); + ATOMIC_STORE(mouse_z, 0); } void mouse_set_w(int w) { - atomic_fetch_add(&mouse_w, w); + ATOMIC_ADD(mouse_w, w); } void mouse_clear_w(void) { - atomic_store(&mouse_w, 0); + ATOMIC_STORE(mouse_w, 0); } void mouse_subtract_z(int *delta_z, int min, int max, int invert) { - int z = atomic_load(&mouse_z); + int z = ATOMIC_LOAD(mouse_z); int real_z = invert ? -z : z; if (real_z > max) { @@ -519,13 +522,13 @@ mouse_subtract_z(int *delta_z, int min, int max, int invert) real_z = 0; } - atomic_store(&mouse_z, invert ? -real_z : real_z); + ATOMIC_STORE(mouse_z, invert ? -real_z : real_z); } void mouse_subtract_w(int *delta_w, int min, int max, int invert) { - int w = atomic_load(&mouse_w); + int w = ATOMIC_LOAD(mouse_w); int real_w = invert ? -w : w; if (real_w > max) { @@ -539,19 +542,19 @@ mouse_subtract_w(int *delta_w, int min, int max, int invert) real_w = 0; } - atomic_store(&mouse_w, invert ? -real_w : real_w); + ATOMIC_STORE(mouse_w, invert ? -real_w : real_w); } void mouse_set_buttons_ex(int b) { - atomic_store(&mouse_buttons, b); + ATOMIC_STORE(mouse_buttons, b); } int mouse_get_buttons_ex(void) { - return atomic_load(&mouse_buttons); + return ATOMIC_LOAD(mouse_buttons); } void diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index cd54f981a52..52f7154a04a 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -481,7 +481,7 @@ bm_poll(void *priv) int xor; int b = mouse_get_buttons_ex(); - if (!mouse_capture && !video_fullscreen) + if (!mouse_capture && !(video_fullscreen && !fullscreen_ui_visible)) return 1; if (!(dev->flags & FLAG_ENABLED)) @@ -543,7 +543,7 @@ bm_update_data(mouse_t *dev) int xor; /* If the counters are not frozen, update them. */ - if ((mouse_capture || video_fullscreen) && !(dev->flags & FLAG_HOLD)) { + if ((mouse_capture || (video_fullscreen && !fullscreen_ui_visible)) && !(dev->flags & FLAG_HOLD)) { /* Update the deltas and the delays. */ mouse_subtract_coords(&delta_x, &delta_y, NULL, NULL, -128, 127, 0, 0); diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index 80d9f38760c..9034d9322ad 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -332,7 +332,7 @@ ps2_poll(void *priv) atkbc_dev_t *dev = (atkbc_dev_t *) priv; int packet_size = (dev->flags & FLAG_INTMODE) ? 4 : 3; - int cond = (mouse_capture || video_fullscreen) && mouse_scan && (dev->mode == MODE_STREAM) && + int cond = (mouse_capture || (video_fullscreen && !fullscreen_ui_visible)) && mouse_scan && (dev->mode == MODE_STREAM) && mouse_state_changed() && (kbc_at_dev_queue_pos(dev, 1) < (FIFO_SIZE - packet_size)); if (cond) diff --git a/src/device/serial.c b/src/device/serial.c index 63f20cbee0a..38220485f92 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -141,7 +141,7 @@ serial_update_ints(serial_t *dev) } } - serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || (dev->type == SERIAL_8250_PCJR))); + serial_do_irq(dev, !(dev->iir & 0x01) && ((dev->mctrl & 8) || ((dev->type == SERIAL_8250_PCJR_3F8) || (dev->type == SERIAL_8250_PCJR_2F8)))); } static void @@ -971,15 +971,20 @@ serial_init(const device_t *info) serial_setup(dev, COM4_ADDR, COM4_IRQ); else if (next_inst == 2) serial_setup(dev, COM3_ADDR, COM3_IRQ); - else if ((next_inst == 1) || (info->local == SERIAL_8250_PCJR)) + else if ((next_inst == 1) || (info->local == SERIAL_8250_PCJR_2F8)) serial_setup(dev, COM2_ADDR, COM2_IRQ); + // TODO +#if 0 + else if ((next_inst == 1) || (info->local == SERIAL_8250_PCJR_3F8)) + serial_setup(dev, COM1_ADDR, COM1_IRQ); +#endif else if (next_inst == 0) serial_setup(dev, COM1_ADDR, COM1_IRQ); /* Default to 1200,N,7. */ dev->dlab = 96; dev->fcr = 0x06; - if (info->local == SERIAL_8250_PCJR) + if ((info->local == SERIAL_8250_PCJR_3F8) || (info->local == SERIAL_8250_PCJR_2F8)) dev->clock_src = 1789500.0; else dev->clock_src = 1843200.0; @@ -1039,11 +1044,25 @@ const device_t ns8250_device = { .config = NULL }; -const device_t ns8250_pcjr_device = { - .name = "National Semiconductor 8250(-compatible) UART for PCjr", - .internal_name = "ns8250_pcjr", +const device_t ns8250_pcjr_3f8_device = { + .name = "National Semiconductor 8250(-compatible) UART for PCjr (0x3f8)", + .internal_name = "ns8250_pcjr_3f8", + .flags = 0, + .local = SERIAL_8250_PCJR_3F8, + .init = serial_init, + .close = serial_close, + .reset = serial_reset, + .available = NULL, + .speed_changed = serial_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ns8250_pcjr_2f8_device = { + .name = "National Semiconductor 8250(-compatible) UART for PCjr (0x2f8)", + .internal_name = "ns8250_pcjr_2f8", .flags = 0, - .local = SERIAL_8250_PCJR, + .local = SERIAL_8250_PCJR_2F8, .init = serial_init, .close = serial_close, .reset = serial_reset, diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index 09886d6f8c0..c1bf0461895 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -1312,14 +1312,8 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) fdc->step = 1; } else { fdc->st0 = 0x20 | (fdc->params[0] & 3); - if (fdc->flags & FDC_FLAG_PCJR) { - fdc->fintr = 1; - fdc->interrupt = -4; - } else { - timer_disable(&fdc->timer); - fdc->interrupt = -3; - fdc_callback(fdc); - } + fdc->fintr = 1; + fdc->interrupt = -4; break; } } else { @@ -1327,14 +1321,9 @@ fdc_write(uint16_t addr, uint8_t val, void *priv) if ((fdc->params[1] - fdc->pcn[fdc->params[0] & 3]) == 0) { fdc_log("Failed seek\n"); fdc->st0 = 0x20 | (fdc->params[0] & 3); - if (fdc->flags & FDC_FLAG_PCJR) { - fdc->fintr = 1; - fdc->interrupt = -4; - } else { - timer_disable(&fdc->timer); - fdc->interrupt = -3; - fdc_callback(fdc); - } + /* Always use the PCjr code, so both 386BSD and 1B/V3 work. */ + fdc->fintr = 1; + fdc->interrupt = -4; break; } if (fdc->params[1] > fdc->pcn[fdc->params[0] & 3]) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index e36b2ac307a..164c0b03701 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -390,10 +390,7 @@ fdd_seek(int drive, int track_diff) else { /* Trigger appropriate audio for track movements */ int actual_track_diff = abs(old_track - fdd[drive].track); - if (actual_track_diff == 1) { - /* Single track movement */ - fdd_audio_play_single_track_step(drive, old_track, fdd[drive].track); - } else if (actual_track_diff > 1) { + if (actual_track_diff > 0) { /* Multi-track seek */ fdd_audio_play_multi_track_seek(drive, old_track, fdd[drive].track); } @@ -409,12 +406,15 @@ fdd_seek(int drive, int track_diff) timer_add(&(fdd_seek_timer[drive]), fdd_seek_complete_callback, &drives[drive], 0); } - /* Get seek timings from audio profile configuration */ - double initial_seek_time = fdd_audio_get_seek_time(drive, 1, actual_track_diff); - double track_seek_time = fdd_audio_get_seek_time(drive, 0, actual_track_diff); - fdd_log("Seek timing for drive %d: initial %.2f ms, per track %.2f ms\n", drive, initial_seek_time, track_seek_time); - uint64_t seek_time_us = (initial_seek_time + (abs(actual_track_diff) * track_seek_time)) * TIMER_USEC; - timer_set_delay_u64(&fdd_seek_timer[drive], seek_time_us); + /* Determine seek direction - seeking down means moving toward track 0 */ + int is_seek_down = (fdd[drive].track < old_track); + + /* Get seek timings from audio profile configuration with direction awareness */ + double seek_time_us = fdd_audio_get_seek_time(drive, actual_track_diff, is_seek_down); + fdd_log("Seek timing for drive %d: %.2f µs (%s)\n", + drive, seek_time_us, is_seek_down ? "DOWN" : "UP"); + uint64_t seek_delay_us = seek_time_us * TIMER_USEC; + timer_set_delay_u64(&fdd_seek_timer[drive], seek_delay_us); } } @@ -430,6 +430,15 @@ fdd_track0(int drive) return !fdd[drive].track; } +int +fdd_get_type_max_track(int type) +{ + if (type < 0 || type >= (sizeof(drive_types) / sizeof(drive_types[0]))) + return 0; + + return drive_types[type].max_track; +} + int fdd_current_track(int drive) { diff --git a/src/floppy/fdd_audio.c b/src/floppy/fdd_audio.c index 19d4cb0d938..5fe5e6358a3 100644 --- a/src/floppy/fdd_audio.c +++ b/src/floppy/fdd_audio.c @@ -36,14 +36,14 @@ /* Global audio profile configurations */ static fdd_audio_profile_config_t audio_profiles[FDD_AUDIO_PROFILE_MAX]; -static int audio_profile_count = 0; +static int audio_profile_count = 0; /* Audio sample structure */ typedef struct { - char filename[512]; + char filename[512]; int16_t *buffer; - int samples; - float volume; + int samples; + float volume; } audio_sample_t; typedef struct { @@ -58,6 +58,7 @@ typedef struct { int duration_samples; int from_track; int to_track; + int track_diff; } multi_seek_state_t; /* Drive type specific audio samples */ @@ -65,8 +66,9 @@ typedef struct { audio_sample_t spindlemotor_start; audio_sample_t spindlemotor_loop; audio_sample_t spindlemotor_stop; - audio_sample_t single_track_step; - audio_sample_t multi_track_seek; + /* Individual seek samples for each track count (indexed 0-78 for 1-79 tracks) */ + audio_sample_t seek_up[MAX_SEEK_SAMPLES]; + audio_sample_t seek_down[MAX_SEEK_SAMPLES]; } drive_audio_samples_t; /* Dynamic sample storage for each profile */ @@ -78,20 +80,18 @@ static motor_state_t spindlemotor_state[FDD_NUM] = {}; static float spindlemotor_fade_volume[FDD_NUM] = {}; static int spindlemotor_fade_samples_remaining[FDD_NUM] = {}; -/* Single step audio state for each drive */ -static single_step_state_t single_step_state[FDD_NUM] = {}; - /* Multi-track seek audio state for each drive */ -static multi_seek_state_t multi_seek_state[FDD_NUM] = {}; +static multi_seek_state_t seek_state[FDD_NUM][MAX_CONCURRENT_SEEKS] = {}; extern uint64_t motoron[FDD_NUM]; +extern char exe_path[2048]; extern int fdd_get_audio_profile(int drive); /* Forward declaration */ static int16_t *load_wav(const char *filename, int *sample_count); -#ifdef ENABLE_FDD_LOG +# ifdef ENABLE_FDD_LOG int fdc_do_log = ENABLE_FDD_LOG; static void @@ -111,7 +111,7 @@ fdd_log(const char *fmt, ...) /* Logging function for audio profile parameters */ static void -fdd_audio_log_profile_params(int drive, const fdd_audio_profile_config_t* profile) +fdd_audio_log_profile_params(int drive, const fdd_audio_profile_config_t *profile) { if (!profile) { fdd_log("FDD Audio Drive %d: No profile assigned\n", drive); @@ -122,26 +122,30 @@ fdd_audio_log_profile_params(int drive, const fdd_audio_profile_config_t* profil fdd_log(" Profile ID: %d\n", profile->id); fdd_log(" Profile Name: %s\n", profile->name); fdd_log(" Internal Name: %s\n", profile->internal_name); - + fdd_log(" Sample Files:\n"); - fdd_log(" Spindle Start: %s (volume: %.2f)\n", - profile->spindlemotor_start.filename, profile->spindlemotor_start.volume); - fdd_log(" Spindle Loop: %s (volume: %.2f)\n", - profile->spindlemotor_loop.filename, profile->spindlemotor_loop.volume); - fdd_log(" Spindle Stop: %s (volume: %.2f)\n", - profile->spindlemotor_stop.filename, profile->spindlemotor_stop.volume); - fdd_log(" Single Step: %s (volume: %.2f)\n", - profile->single_track_step.filename, profile->single_track_step.volume); - fdd_log(" Multi Seek: %s (volume: %.2f)\n", - profile->multi_track_seek.filename, profile->multi_track_seek.volume); - - fdd_log(" Timing Parameters:\n"); - fdd_log(" Samples Per Track: %d samples\n", profile->samples_per_track); - fdd_log(" Total Tracks: %d\n", profile->total_tracks); - fdd_log(" Initial Seek Time: %.1f µs\n", profile->initial_seek_time); - fdd_log(" Initial Seek Time (PCjr): %.1f µs\n", profile->initial_seek_time_pcjr); - fdd_log(" Track Seek Time: %.1f µs\n", profile->track_seek_time); - fdd_log(" Track Seek Time (PCjr): %.1f µs\n", profile->track_seek_time_pcjr); + fdd_log(" Spindle Start: %s (volume: %.2f)\n", + profile->spindlemotor_start.filename, profile->spindlemotor_start.volume); + fdd_log(" Spindle Loop: %s (volume: %.2f)\n", + profile->spindlemotor_loop.filename, profile->spindlemotor_loop.volume); + fdd_log(" Spindle Stop: %s (volume: %.2f)\n", + profile->spindlemotor_stop.filename, profile->spindlemotor_stop.volume); + + /* Log a few sample seek files as examples */ + int max_tracks = (profile->total_tracks == 40) ? 39 : 79; + fdd_log(" Individual seek samples (up to %d tracks):\n", max_tracks); + for (int i = 0; i < max_tracks && i < 5; i++) { + if (profile->seek_up[i].filename[0]) { + fdd_log(" Seek up %d track(s): %s (volume: %.2f)\n", + i + 1, profile->seek_up[i].filename, profile->seek_up[i].volume); + } + if (profile->seek_down[i].filename[0]) { + fdd_log(" Seek down %d track(s): %s (volume: %.2f)\n", + i + 1, profile->seek_down[i].filename, profile->seek_down[i].volume); + } + } + if (max_tracks > 5) + fdd_log(" ... and %d more seek samples\n", (max_tracks - 5) * 2); } /* Log audio profile parameters for a specific drive */ @@ -153,9 +157,9 @@ fdd_audio_log_drive_profile(int drive) return; } - int profile_id = fdd_get_audio_profile(drive); - const fdd_audio_profile_config_t* profile = fdd_audio_get_profile(profile_id); - + int profile_id = fdd_get_audio_profile(drive); + const fdd_audio_profile_config_t *profile = fdd_audio_get_profile(profile_id); + fdd_log("FDD Audio Drive %d: Using profile %d\n", drive, profile_id); fdd_audio_log_profile_params(drive, profile); } @@ -165,25 +169,25 @@ static void fdd_audio_log_active_profiles(void) { fdd_log("FDD Audio: Checking active drive configurations...\n"); - int active_drive_count = 0; - + int active_drive_count = 0; + for (int drive = 0; drive < FDD_NUM; drive++) { if (fdd_get_type(drive) == 0) continue; - + active_drive_count++; - int profile_id = fdd_get_audio_profile(drive); + int profile_id = fdd_get_audio_profile(drive); if (profile_id >= 0 && profile_id < audio_profile_count) { fdd_log("FDD Audio: Drive %d (configured) uses profile %d\n", drive, profile_id); fdd_audio_log_profile_params(drive, &audio_profiles[profile_id]); } } - + if (active_drive_count == 0) { fdd_log("FDD Audio: No drives configured - no audio profiles to log\n"); return; } - + fdd_log("FDD Audio: Active audio profiles for %d configured drive(s):\n", active_drive_count); } @@ -191,10 +195,17 @@ void fdd_audio_load_profiles(void) { ini_t profiles_ini; + char cfg_fn[1024] = { 0 }; - profiles_ini = ini_read_ex("roms/floppy/fdd_audio_profiles.cfg", 1); + int ret = asset_getfile("assets/sounds/fdd/fdd_audio_profiles.cfg", cfg_fn, 1024); + if (!ret) { + fdd_log("FDD Audio: Could not find profiles\n"); + return; + } + + profiles_ini = ini_read_ex(cfg_fn, 1); if (profiles_ini == NULL) { - fdd_log("FDD Audio: Could not load profiles from %s\n", config_path); + fdd_log("FDD Audio: Could not load profiles\n"); return; } @@ -236,121 +247,137 @@ fdd_audio_load_profiles(void) profile->spindlemotor_stop.filename[sizeof(profile->spindlemotor_stop.filename) - 1] = '\0'; profile->spindlemotor_stop.volume = ini_section_get_double(section, "spindlemotor_stop_volume", 1.0); - filename = ini_section_get_string(section, "single_track_step_file", ""); - strncpy(profile->single_track_step.filename, filename, sizeof(profile->single_track_step.filename) - 1); - profile->single_track_step.filename[sizeof(profile->single_track_step.filename) - 1] = '\0'; - profile->single_track_step.volume = ini_section_get_double(section, "single_track_step_volume", 1.0); - - filename = ini_section_get_string(section, "multi_track_seek_file", ""); - strncpy(profile->multi_track_seek.filename, filename, sizeof(profile->multi_track_seek.filename) - 1); - profile->multi_track_seek.filename[sizeof(profile->multi_track_seek.filename) - 1] = '\0'; - profile->multi_track_seek.volume = ini_section_get_double(section, "multi_track_seek_volume", 1.0); + /* Load seek samples and seek times for each track count */ + for (int track_count = 1; track_count <= MAX_SEEK_SAMPLES; track_count++) { + char key[128]; + + /* Seek up samples */ + snprintf(key, sizeof(key), "seek_up_%dtrack_file", track_count); + filename = ini_section_get_string(section, key, ""); + strncpy(profile->seek_up[track_count - 1].filename, filename, + sizeof(profile->seek_up[track_count - 1].filename) - 1); + profile->seek_up[track_count - 1].filename[sizeof(profile->seek_up[track_count - 1].filename) - 1] = '\0'; + + snprintf(key, sizeof(key), "seek_up_%dtrack_volume", track_count); + profile->seek_up[track_count - 1].volume = ini_section_get_double(section, key, 1.0); + + /* Seek down samples */ + snprintf(key, sizeof(key), "seek_down_%dtrack_file", track_count); + filename = ini_section_get_string(section, key, ""); + strncpy(profile->seek_down[track_count - 1].filename, filename, + sizeof(profile->seek_down[track_count - 1].filename) - 1); + profile->seek_down[track_count - 1].filename[sizeof(profile->seek_down[track_count - 1].filename) - 1] = '\0'; + + snprintf(key, sizeof(key), "seek_down_%dtrack_volume", track_count); + profile->seek_down[track_count - 1].volume = ini_section_get_double(section, key, 1.0); + + /* Seek time in milliseconds - used for FDC timing, not sample playback */ + snprintf(key, sizeof(key), "seek_%dtrack_time_ms", track_count); + profile->seek_time_ms[track_count - 1] = ini_section_get_double(section, key, 6.0 * track_count); + } /* Load timing configurations */ - profile->samples_per_track = ini_section_get_int(section, "samples_per_track", 297); - profile->total_tracks = ini_section_get_int(section, "total_tracks", 80); - profile->initial_seek_time = ini_section_get_double(section, "initial_seek_time", 15000.0); - profile->initial_seek_time_pcjr = ini_section_get_double(section, "initial_seek_time_pcjr", 40000.0); - profile->track_seek_time = ini_section_get_double(section, "track_seek_time", 6000.0); - profile->track_seek_time_pcjr = ini_section_get_double(section, "track_seek_time_pcjr", 10000.0); + profile->total_tracks = ini_section_get_int(section, "total_tracks", 80); audio_profile_count++; } } - + ini_close(profiles_ini); - - fdd_log("FDD Audio: Loaded %d audio profiles from %s\n", audio_profile_count, config_path); + + fdd_log("FDD Audio: Loaded %d audio profiles\n", audio_profile_count); } -static void load_profile_samples(int profile_id) { +void +load_profile_samples(int profile_id) +{ if (profile_id <= 0 || profile_id >= audio_profile_count) return; - - fdd_audio_profile_config_t *config = &audio_profiles[profile_id]; - drive_audio_samples_t *samples = &profile_samples[profile_id]; - - fdd_log("FDD Audio: Loading samples for profile %d (%s)\n", - profile_id, config->name); - + + fdd_audio_profile_config_t *config = &audio_profiles[profile_id]; + drive_audio_samples_t *samples = &profile_samples[profile_id]; + + fdd_log("FDD Audio: Loading samples for profile %d (%s)\n", + profile_id, config->name); + /* Load samples if not already loaded */ if (samples->spindlemotor_start.buffer == NULL && config->spindlemotor_start.filename[0]) { strcpy(samples->spindlemotor_start.filename, config->spindlemotor_start.filename); samples->spindlemotor_start.volume = config->spindlemotor_start.volume; - samples->spindlemotor_start.buffer = load_wav(config->spindlemotor_start.filename, - &samples->spindlemotor_start.samples); + samples->spindlemotor_start.buffer = load_wav(config->spindlemotor_start.filename, + &samples->spindlemotor_start.samples); if (samples->spindlemotor_start.buffer) { - fdd_log(" Loaded spindlemotor_start: %s (%d samples, volume %.2f)\n", - config->spindlemotor_start.filename, - samples->spindlemotor_start.samples, - config->spindlemotor_start.volume); + fdd_log(" Loaded spindlemotor_start: %s (%d samples, volume %.2f)\n", + config->spindlemotor_start.filename, + samples->spindlemotor_start.samples, + config->spindlemotor_start.volume); } else { - fdd_log(" Failed to load spindlemotor_start: %s\n", - config->spindlemotor_start.filename); + fdd_log(" Failed to load spindlemotor_start: %s\n", + config->spindlemotor_start.filename); } } - + if (samples->spindlemotor_loop.buffer == NULL && config->spindlemotor_loop.filename[0]) { strcpy(samples->spindlemotor_loop.filename, config->spindlemotor_loop.filename); samples->spindlemotor_loop.volume = config->spindlemotor_loop.volume; - samples->spindlemotor_loop.buffer = load_wav(config->spindlemotor_loop.filename, - &samples->spindlemotor_loop.samples); + samples->spindlemotor_loop.buffer = load_wav(config->spindlemotor_loop.filename, + &samples->spindlemotor_loop.samples); if (samples->spindlemotor_loop.buffer) { - fdd_log(" Loaded spindlemotor_loop: %s (%d samples, volume %.2f)\n", - config->spindlemotor_loop.filename, - samples->spindlemotor_loop.samples, - config->spindlemotor_loop.volume); + fdd_log(" Loaded spindlemotor_loop: %s (%d samples, volume %.2f)\n", + config->spindlemotor_loop.filename, + samples->spindlemotor_loop.samples, + config->spindlemotor_loop.volume); } else { - fdd_log(" Failed to load spindlemotor_loop: %s\n", - config->spindlemotor_loop.filename); + fdd_log(" Failed to load spindlemotor_loop: %s\n", + config->spindlemotor_loop.filename); } } - + if (samples->spindlemotor_stop.buffer == NULL && config->spindlemotor_stop.filename[0]) { strcpy(samples->spindlemotor_stop.filename, config->spindlemotor_stop.filename); samples->spindlemotor_stop.volume = config->spindlemotor_stop.volume; - samples->spindlemotor_stop.buffer = load_wav(config->spindlemotor_stop.filename, - &samples->spindlemotor_stop.samples); + samples->spindlemotor_stop.buffer = load_wav(config->spindlemotor_stop.filename, + &samples->spindlemotor_stop.samples); if (samples->spindlemotor_stop.buffer) { - fdd_log(" Loaded spindlemotor_stop: %s (%d samples, volume %.2f)\n", - config->spindlemotor_stop.filename, - samples->spindlemotor_stop.samples, - config->spindlemotor_stop.volume); + fdd_log(" Loaded spindlemotor_stop: %s (%d samples, volume %.2f)\n", + config->spindlemotor_stop.filename, + samples->spindlemotor_stop.samples, + config->spindlemotor_stop.volume); } else { - fdd_log(" Failed to load spindlemotor_stop: %s\n", - config->spindlemotor_stop.filename); + fdd_log(" Failed to load spindlemotor_stop: %s\n", + config->spindlemotor_stop.filename); } } - - if (samples->single_track_step.buffer == NULL && config->single_track_step.filename[0]) { - strcpy(samples->single_track_step.filename, config->single_track_step.filename); - samples->single_track_step.volume = config->single_track_step.volume; - samples->single_track_step.buffer = load_wav(config->single_track_step.filename, - &samples->single_track_step.samples); - if (samples->single_track_step.buffer) { - fdd_log(" Loaded single_track_step: %s (%d samples, volume %.2f)\n", - config->single_track_step.filename, - samples->single_track_step.samples, - config->single_track_step.volume); - } else { - fdd_log(" Failed to load single_track_step: %s\n", - config->single_track_step.filename); + + /* Load individual seek samples for each track count */ + int max_tracks = (config->total_tracks == 40) ? 39 : 79; + for (int track_count = 1; track_count <= max_tracks; track_count++) { + int idx = track_count - 1; + + /* Load seek up sample */ + if (samples->seek_up[idx].buffer == NULL && config->seek_up[idx].filename[0]) { + strcpy(samples->seek_up[idx].filename, config->seek_up[idx].filename); + samples->seek_up[idx].volume = config->seek_up[idx].volume; + samples->seek_up[idx].buffer = load_wav(config->seek_up[idx].filename, + &samples->seek_up[idx].samples); + if (samples->seek_up[idx].buffer) { + fdd_log(" Loaded seek_up[%d]: %s (%d samples, volume %.2f)\n", + track_count, config->seek_up[idx].filename, + samples->seek_up[idx].samples, config->seek_up[idx].volume); + } } - } - - if (samples->multi_track_seek.buffer == NULL && config->multi_track_seek.filename[0]) { - strcpy(samples->multi_track_seek.filename, config->multi_track_seek.filename); - samples->multi_track_seek.volume = config->multi_track_seek.volume; - samples->multi_track_seek.buffer = load_wav(config->multi_track_seek.filename, - &samples->multi_track_seek.samples); - if (samples->multi_track_seek.buffer) { - fdd_log(" Loaded multi_track_seek: %s (%d samples, volume %.2f)\n", - config->multi_track_seek.filename, - samples->multi_track_seek.samples, - config->multi_track_seek.volume); - } else { - fdd_log(" Failed to load multi_track_seek: %s\n", - config->multi_track_seek.filename); + + /* Load seek down sample */ + if (samples->seek_down[idx].buffer == NULL && config->seek_down[idx].filename[0]) { + strcpy(samples->seek_down[idx].filename, config->seek_down[idx].filename); + samples->seek_down[idx].volume = config->seek_down[idx].volume; + samples->seek_down[idx].buffer = load_wav(config->seek_down[idx].filename, + &samples->seek_down[idx].samples); + if (samples->seek_down[idx].buffer) { + fdd_log(" Loaded seek_down[%d]: %s (%d samples, volume %.2f)\n", + track_count, config->seek_down[idx].filename, + samples->seek_down[idx].samples, config->seek_down[idx].volume); + } } } } @@ -367,23 +394,31 @@ get_drive_samples(int drive) } /* Public API functions */ -int fdd_audio_get_profile_count(void) { +int +fdd_audio_get_profile_count(void) +{ return audio_profile_count; } -const fdd_audio_profile_config_t* fdd_audio_get_profile(int id) { +const fdd_audio_profile_config_t * +fdd_audio_get_profile(int id) +{ if (id < 0 || id >= audio_profile_count) return NULL; return &audio_profiles[id]; } -const char* fdd_audio_get_profile_name(int id) { +const char * +fdd_audio_get_profile_name(int id) +{ if (id < 0 || id >= audio_profile_count) return NULL; return audio_profiles[id].name; } -const char* fdd_audio_get_profile_internal_name(int id) { +const char * +fdd_audio_get_profile_internal_name(int id) +{ if (id < 0 || id >= audio_profile_count) return NULL; return audio_profiles[id].internal_name; @@ -405,24 +440,32 @@ fdd_audio_get_profile_by_internal_name(const char *internal_name) return 0; } -double fdd_audio_get_seek_time(int drive, int is_initial, int track_count) { +double +fdd_audio_get_seek_time(int drive, int track_count, int is_seek_down) +{ int profile_id = fdd_get_audio_profile(drive); if (profile_id <= 0 || profile_id >= audio_profile_count) { - /* Return default values */ - return is_initial ? 15000.0 : 6000.0; + return 0; } - + fdd_audio_profile_config_t *profile = &audio_profiles[profile_id]; - - /* Check if using PCjr timing */ - extern fdc_t *fdd_fdc; - int is_pcjr = (fdd_fdc && (fdd_fdc->flags & FDC_FLAG_PCJR)); - - if (is_initial) { - return is_pcjr ? profile->initial_seek_time_pcjr : profile->initial_seek_time; - } else { - return is_pcjr ? profile->track_seek_time_pcjr : profile->track_seek_time; + if (!profile) + return 0; + + /* Get the maximum available seek sample for this profile */ + int max_seek_tracks = (profile->total_tracks == 40) ? 39 : 79; + + /* Clamp track_count to maximum */ + if (track_count > max_seek_tracks) + track_count = max_seek_tracks; + + /* Return configured seek time in microseconds */ + if (track_count > 0 && track_count <= MAX_SEEK_SAMPLES) { + return profile->seek_time_ms[track_count - 1] * 1000.0; } + + /* Fallback */ + return 0; } void @@ -438,16 +481,15 @@ fdd_audio_init(void) spindlemotor_fade_volume[i] = 1.0f; spindlemotor_fade_samples_remaining[i] = 0; - /* Initialize single step state */ - single_step_state[i].position = 0; - single_step_state[i].active = 0; - - /* Initialize multi-track seek state */ - multi_seek_state[i].position = 0; - multi_seek_state[i].active = 0; - multi_seek_state[i].duration_samples = 0; - multi_seek_state[i].from_track = -1; - multi_seek_state[i].to_track = -1; + /* Initialize all concurrent seek slots */ + for (int j = 0; j < MAX_CONCURRENT_SEEKS; j++) { + seek_state[i][j].position = 0; + seek_state[i][j].active = 0; + seek_state[i][j].duration_samples = 0; + seek_state[i][j].from_track = -1; + seek_state[i][j].to_track = -1; + seek_state[i][j].track_diff = 0; + } } /* Preload audio samples for each drive's selected profile */ @@ -463,7 +505,7 @@ fdd_audio_init(void) /* Initialize sound thread */ sound_fdd_thread_init(); - + fdd_log("FDD Audio: Initialization complete\n"); } @@ -471,7 +513,7 @@ void fdd_audio_close(void) { fdd_log("FDD Audio: Shutting down audio system\n"); - + /* Free loaded profile samples */ for (int profile_id = 0; profile_id < audio_profile_count; profile_id++) { drive_audio_samples_t *samples = &profile_samples[profile_id]; @@ -491,20 +533,24 @@ fdd_audio_close(void) samples->spindlemotor_stop.buffer = NULL; samples->spindlemotor_stop.samples = 0; } - if (samples->single_track_step.buffer) { - free(samples->single_track_step.buffer); - samples->single_track_step.buffer = NULL; - samples->single_track_step.samples = 0; - } - if (samples->multi_track_seek.buffer) { - free(samples->multi_track_seek.buffer); - samples->multi_track_seek.buffer = NULL; - samples->multi_track_seek.samples = 0; + + /* Free individual seek samples */ + for (int track_count = 0; track_count < MAX_SEEK_SAMPLES; track_count++) { + if (samples->seek_up[track_count].buffer) { + free(samples->seek_up[track_count].buffer); + samples->seek_up[track_count].buffer = NULL; + samples->seek_up[track_count].samples = 0; + } + if (samples->seek_down[track_count].buffer) { + free(samples->seek_down[track_count].buffer); + samples->seek_down[track_count].buffer = NULL; + samples->seek_down[track_count].samples = 0; + } } } sound_fdd_thread_end(); - + fdd_log("FDD Audio: Shutdown complete\n"); } @@ -548,70 +594,77 @@ fdd_audio_set_motor_enable(int drive, int motor_enable) } void -fdd_audio_play_single_track_step(int drive, int from_track, int to_track) +fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track) { if (!fdd_sounds_enabled || fdd_get_turbo(drive)) return; if (drive < 0 || drive >= FDD_NUM) return; - if (abs(from_track - to_track) != 1) - return; /* Only single track movements */ - - fdd_log("FDD Audio Drive %d: Single track step %d -> %d\n", drive, from_track, to_track); - single_step_state[drive].position = 0; - single_step_state[drive].active = 1; -} + int track_diff = abs(from_track - to_track); + if (track_diff < 1) + return; -void -fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track) -{ - if (!fdd_sounds_enabled || fdd_get_turbo(drive)) + drive_audio_samples_t *samples = get_drive_samples(drive); + if (!samples) return; - if (drive < 0 || drive >= FDD_NUM) + int is_seek_down = (to_track < from_track); + + /* Get the profile to check total_tracks */ + int profile_id = fdd_get_audio_profile(drive); + if (profile_id < 1 || profile_id >= audio_profile_count) return; - int track_diff = abs(from_track - to_track); - if (track_diff <= 1) - return; /* Use single step for 1 track movements */ + fdd_audio_profile_config_t *profile = &audio_profiles[profile_id]; - drive_audio_samples_t *samples = get_drive_samples(drive); - if (!samples || !samples->multi_track_seek.buffer || samples->multi_track_seek.samples == 0) - return; /* No multi-track seek sample loaded */ + /* Determine the maximum available seek sample for this profile */ + int max_seek_tracks = (profile->total_tracks == 40) ? 39 : 79; - /* Check if a seek is already active */ - if (multi_seek_state[drive].active && - multi_seek_state[drive].from_track == from_track && - multi_seek_state[drive].to_track == to_track) { - return; + /* Clamp track_diff to the maximum available sample */ + if (track_diff > max_seek_tracks) { + fdd_log("FDD Audio Drive %d: Seek request for %d tracks exceeds maximum %d, clamping to %d\n", + drive, track_diff, max_seek_tracks, max_seek_tracks); + track_diff = max_seek_tracks; } - fdd_log("FDD Audio Drive %d: Multi-track seek %d -> %d (%d tracks)\n", - drive, from_track, to_track, track_diff); + /* Get the appropriate seek sample */ + int idx = track_diff - 1; + audio_sample_t *sample_to_use = is_seek_down ? &samples->seek_down[idx] : &samples->seek_up[idx]; - /* Get timing from configuration */ - int profile_id = fdd_get_audio_profile(drive); - int duration_samples; - - if (profile_id < 1 || profile_id >= audio_profile_count) + /* Only proceed if we have the appropriate sample */ + if (!sample_to_use || !sample_to_use->buffer || sample_to_use->samples == 0) return; - /* Use configured timing */ - duration_samples = track_diff * audio_profiles[profile_id].samples_per_track; - fdd_log("FDD Audio Drive %d: Seek duration %d samples (%d tracks * %d samples/track)\n", - drive, duration_samples, track_diff, audio_profiles[profile_id].samples_per_track); - /* Clamp to maximum available sample length */ - if (duration_samples > samples->multi_track_seek.samples) - duration_samples = samples->multi_track_seek.samples; - - /* Start new seek (or restart interrupted seek) */ - multi_seek_state[drive].position = 0; - multi_seek_state[drive].active = 1; - multi_seek_state[drive].duration_samples = duration_samples; - multi_seek_state[drive].from_track = from_track; - multi_seek_state[drive].to_track = to_track; + fdd_log("FDD Audio Drive %d: Multi-track seek %d -> %d (%d tracks, %s)\n", + drive, from_track, to_track, track_diff, is_seek_down ? "DOWN" : "UP"); + + /* Find an available seek slot */ + int slot = -1; + for (int i = 0; i < MAX_CONCURRENT_SEEKS; i++) { + if (!seek_state[drive][i].active) { + slot = i; + break; + } + } + + /* If no slot available, reuse the oldest (first) slot */ + if (slot == -1) { + fdd_log("FDD Audio Drive %d: All seek slots in use, reusing slot 0\n", drive); + slot = 0; + } + + /* Start new seek in the available slot */ + seek_state[drive][slot].position = 0; + seek_state[drive][slot].active = 1; + seek_state[drive][slot].duration_samples = sample_to_use->samples; + seek_state[drive][slot].from_track = from_track; + seek_state[drive][slot].to_track = to_track; + seek_state[drive][slot].track_diff = track_diff; + + fdd_log("FDD Audio Drive %d: Started seek in slot %d, duration %d samples\n", + drive, slot, sample_to_use->samples); } static int16_t * @@ -623,7 +676,7 @@ load_wav(const char *filename, int *sample_count) if (strstr(filename, "..") != NULL) return NULL; - FILE *f = rom_fopen(filename, "rb"); + FILE *f = asset_fopen(filename, "rb"); if (f == NULL) { fdd_log("FDD Audio: Failed to open WAV file: %s\n", filename); return NULL; @@ -645,7 +698,7 @@ load_wav(const char *filename, int *sample_count) /* Accept both mono and stereo, 16-bit PCM */ if (hdr.audio_format != 1 || hdr.bits_per_sample != 16 || (hdr.num_channels != 1 && hdr.num_channels != 2)) { fdd_log("FDD Audio: Unsupported WAV format in %s (format: %d, bits: %d, channels: %d)\n", - filename, hdr.audio_format, hdr.bits_per_sample, hdr.num_channels); + filename, hdr.audio_format, hdr.bits_per_sample, hdr.num_channels); fclose(f); return NULL; } @@ -705,15 +758,22 @@ fdd_audio_callback(int16_t *buffer, int length) { /* Clear buffer */ memset(buffer, 0, length * sizeof(int16_t)); + /* Check if any motor is running or transitioning, or any audio is active */ int any_audio_active = 0; for (int drive = 0; drive < FDD_NUM; drive++) { - if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED || - single_step_state[drive].active || - multi_seek_state[drive].active) { + if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED) { any_audio_active = 1; break; } + for (int j = 0; j < MAX_CONCURRENT_SEEKS; j++) { + if (seek_state[drive][j].active) { + any_audio_active = 1; + break; + } + } + if (any_audio_active) + break; } if (!any_audio_active) @@ -724,296 +784,297 @@ fdd_audio_callback(int16_t *buffer, int length) int samples_in_buffer = length / 2; /* Process audio for all drives */ - if (sound_is_float) for (int drive = 0; drive < FDD_NUM; drive++) { - drive_audio_samples_t *samples = get_drive_samples(drive); - if (!samples) - continue; - - for (int i = 0; i < samples_in_buffer; i++) { - float left_sample = 0.0f; - float right_sample = 0.0f; - - /* Process motor audio */ - if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED) { - switch (spindlemotor_state[drive]) { - case MOTOR_STATE_STARTING: - if (samples->spindlemotor_start.buffer && spindlemotor_pos[drive] < samples->spindlemotor_start.samples) { - /* Play start sound with volume control */ - left_sample = (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_start.volume; - right_sample = (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_start.volume; - spindlemotor_pos[drive]++; - } else { - /* Start sound finished, transition to loop */ - spindlemotor_state[drive] = MOTOR_STATE_RUNNING; - spindlemotor_pos[drive] = 0; - } - break; - - case MOTOR_STATE_RUNNING: - if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { - /* Play loop sound with volume control */ - left_sample = (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_loop.volume; - right_sample = (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_loop.volume; - spindlemotor_pos[drive]++; - - /* Loop back to beginning */ - if (spindlemotor_pos[drive] >= samples->spindlemotor_loop.samples) { - spindlemotor_pos[drive] = 0; + if (sound_is_float) { + for (int drive = 0; drive < FDD_NUM; drive++) { + drive_audio_samples_t *samples = get_drive_samples(drive); + if (!samples) + continue; + + for (int i = 0; i < samples_in_buffer; i++) { + float left_sample = 0.0f; + float right_sample = 0.0f; + + /* Process motor audio (unchanged) */ + if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED) { + switch (spindlemotor_state[drive]) { + case MOTOR_STATE_STARTING: + if (samples->spindlemotor_start.buffer && spindlemotor_pos[drive] < samples->spindlemotor_start.samples) { + left_sample = (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_start.volume; + right_sample = (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_start.volume; + spindlemotor_pos[drive]++; + } else { + spindlemotor_state[drive] = MOTOR_STATE_RUNNING; + spindlemotor_pos[drive] = 0; } - } - break; - - case MOTOR_STATE_STOPPING: - if (spindlemotor_fade_samples_remaining[drive] > 0) { - /* Mix fading loop sound with rising stop sound */ - float loop_volume = spindlemotor_fade_volume[drive]; - float stop_volume = 1.0f - loop_volume; - - float loop_left = 0.0f, loop_right = 0.0f; - float stop_left = 0.0f, stop_right = 0.0f; + break; - /* Get loop sample (continue from current position) with volume control */ + case MOTOR_STATE_RUNNING: if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { - int loop_pos = spindlemotor_pos[drive] % samples->spindlemotor_loop.samples; - loop_left = (float) samples->spindlemotor_loop.buffer[loop_pos * 2] / 131072.0f * samples->spindlemotor_loop.volume; - loop_right = (float) samples->spindlemotor_loop.buffer[loop_pos * 2 + 1] / 131072.0f * samples->spindlemotor_loop.volume; - } + left_sample = (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_loop.volume; + right_sample = (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_loop.volume; + spindlemotor_pos[drive]++; - /* Get stop sample with volume control */ - if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { - stop_left = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_stop.volume; - stop_right = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_stop.volume; + if (spindlemotor_pos[drive] >= samples->spindlemotor_loop.samples) { + spindlemotor_pos[drive] = 0; + } } + break; - /* Mix the sounds */ - left_sample = loop_left * loop_volume + stop_left * stop_volume; - right_sample = loop_right * loop_volume + stop_right * stop_volume; + case MOTOR_STATE_STOPPING: + if (spindlemotor_fade_samples_remaining[drive] > 0) { + float loop_volume = spindlemotor_fade_volume[drive]; + float stop_volume = 1.0f - loop_volume; - spindlemotor_pos[drive]++; - spindlemotor_fade_samples_remaining[drive]--; + float loop_left = 0.0f, loop_right = 0.0f; + float stop_left = 0.0f, stop_right = 0.0f; + + if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { + int loop_pos = spindlemotor_pos[drive] % samples->spindlemotor_loop.samples; + loop_left = (float) samples->spindlemotor_loop.buffer[loop_pos * 2] / 131072.0f * samples->spindlemotor_loop.volume; + loop_right = (float) samples->spindlemotor_loop.buffer[loop_pos * 2 + 1] / 131072.0f * samples->spindlemotor_loop.volume; + } + + if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { + stop_left = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_stop.volume; + stop_right = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_stop.volume; + } + + left_sample = loop_left * loop_volume + stop_left * stop_volume; + right_sample = loop_right * loop_volume + stop_right * stop_volume; - /* Update fade volume */ - spindlemotor_fade_volume[drive] = (float) spindlemotor_fade_samples_remaining[drive] / FADE_SAMPLES; - } else { - /* Fade completed, play remaining stop sound with volume control */ - if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { - left_sample = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_stop.volume; - right_sample = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_stop.volume; spindlemotor_pos[drive]++; + spindlemotor_fade_samples_remaining[drive]--; + + spindlemotor_fade_volume[drive] = (float) spindlemotor_fade_samples_remaining[drive] / FADE_SAMPLES; } else { - /* Stop sound finished */ - spindlemotor_state[drive] = MOTOR_STATE_STOPPED; - /* Note: Timer disabling is handled by fdd.c, not here */ + if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { + left_sample = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 131072.0f * samples->spindlemotor_stop.volume; + right_sample = (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 131072.0f * samples->spindlemotor_stop.volume; + spindlemotor_pos[drive]++; + } else { + spindlemotor_state[drive] = MOTOR_STATE_STOPPED; + } } - } - break; + break; - default: - break; + default: + break; + } } - } - /* Process single step audio */ - if (single_step_state[drive].active) { - if (samples->single_track_step.buffer && single_step_state[drive].position < samples->single_track_step.samples) { - /* Mix step sound with motor sound with volume control */ - float step_left = (float) samples->single_track_step.buffer[single_step_state[drive].position * 2] / 131072.0f * samples->single_track_step.volume; - float step_right = (float) samples->single_track_step.buffer[single_step_state[drive].position * 2 + 1] / 131072.0f * samples->single_track_step.volume; - - left_sample += step_left; - right_sample += step_right; - - single_step_state[drive].position++; - } else { - /* Step sound finished */ - single_step_state[drive].active = 0; - single_step_state[drive].position = 0; - } - } + /* Process all concurrent seek audio slots */ + for (int slot = 0; slot < MAX_CONCURRENT_SEEKS; slot++) { + if (!seek_state[drive][slot].active) + continue; - /* Process multi-track seek audio */ - if (multi_seek_state[drive].active) { - if (samples->multi_track_seek.buffer && - multi_seek_state[drive].position < multi_seek_state[drive].duration_samples && - multi_seek_state[drive].position < samples->multi_track_seek.samples) { - /* Mix seek sound with motor sound with volume control */ - float seek_left = (float) samples->multi_track_seek.buffer[multi_seek_state[drive].position * 2] / 131072.0f * samples->multi_track_seek.volume; - float seek_right = (float) samples->multi_track_seek.buffer[multi_seek_state[drive].position * 2 + 1] / 131072.0f * samples->multi_track_seek.volume; - - left_sample += seek_left; - right_sample += seek_right; - - multi_seek_state[drive].position++; - } else { - /* Seek sound finished */ - multi_seek_state[drive].active = 0; - multi_seek_state[drive].position = 0; - multi_seek_state[drive].duration_samples = 0; - multi_seek_state[drive].from_track = -1; - multi_seek_state[drive].to_track = -1; - } - } + int track_diff = seek_state[drive][slot].track_diff; + if (track_diff > 0 && track_diff <= MAX_SEEK_SAMPLES) { + int idx = track_diff - 1; + int is_seek_down = (seek_state[drive][slot].to_track < seek_state[drive][slot].from_track); + audio_sample_t *seek_sample = is_seek_down ? &samples->seek_down[idx] : &samples->seek_up[idx]; - /* Mix this drive's audio into the buffer */ - float_buffer[i * 2] += left_sample; - float_buffer[i * 2 + 1] += right_sample; - } - } else for (int drive = 0; drive < FDD_NUM; drive++) { - drive_audio_samples_t *samples = get_drive_samples(drive); - if (!samples) - continue; - - for (int i = 0; i < samples_in_buffer; i++) { - int16_t left_sample = 0.0f; - int16_t right_sample = 0.0f; - - /* Process motor audio */ - if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED) { - switch (spindlemotor_state[drive]) { - case MOTOR_STATE_STARTING: - if (samples->spindlemotor_start.buffer && spindlemotor_pos[drive] < samples->spindlemotor_start.samples) { - /* Play start sound with volume control */ - left_sample = (int16_t) (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_start.volume; - right_sample = (int16_t) (float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_start.volume; - spindlemotor_pos[drive]++; + if (seek_sample && seek_sample->buffer && seek_state[drive][slot].position < seek_sample->samples) { + /* Mix seek sound with existing audio */ + float seek_left = (float) seek_sample->buffer[seek_state[drive][slot].position * 2] / 131072.0f * seek_sample->volume; + float seek_right = (float) seek_sample->buffer[seek_state[drive][slot].position * 2 + 1] / 131072.0f * seek_sample->volume; + + left_sample += seek_left; + right_sample += seek_right; + + seek_state[drive][slot].position++; } else { - /* Start sound finished, transition to loop */ - spindlemotor_state[drive] = MOTOR_STATE_RUNNING; - spindlemotor_pos[drive] = 0; - } - break; - - case MOTOR_STATE_RUNNING: - if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { - /* Play loop sound with volume control */ - left_sample = (int16_t) (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_loop.volume; - right_sample = (int16_t) (float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_loop.volume; - spindlemotor_pos[drive]++; - - /* Loop back to beginning */ - if (spindlemotor_pos[drive] >= samples->spindlemotor_loop.samples) { - spindlemotor_pos[drive] = 0; - } + /* Seek sound finished */ + seek_state[drive][slot].active = 0; + seek_state[drive][slot].position = 0; + seek_state[drive][slot].duration_samples = 0; + seek_state[drive][slot].from_track = -1; + seek_state[drive][slot].to_track = -1; + seek_state[drive][slot].track_diff = 0; } - break; - - case MOTOR_STATE_STOPPING: - if (spindlemotor_fade_samples_remaining[drive] > 0) { - /* Mix fading loop sound with rising stop sound */ - float loop_volume = spindlemotor_fade_volume[drive]; - float stop_volume = 1.0f - loop_volume; + } + } - int16_t loop_left = 0x0000, loop_right = 0x0000; - int16_t stop_left = 0x0000, stop_right = 0x0000; + /* Mix this drive's audio into the buffer */ + float_buffer[i * 2] += left_sample; + float_buffer[i * 2 + 1] += right_sample; + } + } + } else { + /* int16 version - similar changes */ + for (int drive = 0; drive < FDD_NUM; drive++) { + drive_audio_samples_t *samples = get_drive_samples(drive); + if (!samples) + continue; + + for (int i = 0; i < samples_in_buffer; i++) { + int16_t left_sample = 0; + int16_t right_sample = 0; + + /* Process motor audio (same as float version but with int16) */ + if (spindlemotor_state[drive] != MOTOR_STATE_STOPPED) { + switch (spindlemotor_state[drive]) { + case MOTOR_STATE_STARTING: + if (samples->spindlemotor_start.buffer && spindlemotor_pos[drive] < samples->spindlemotor_start.samples) { + left_sample = (int16_t) ((float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_start.volume); + right_sample = (int16_t) ((float) samples->spindlemotor_start.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_start.volume); + spindlemotor_pos[drive]++; + } else { + spindlemotor_state[drive] = MOTOR_STATE_RUNNING; + spindlemotor_pos[drive] = 0; + } + break; - /* Get loop sample (continue from current position) with volume control */ + case MOTOR_STATE_RUNNING: if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { - int loop_pos = spindlemotor_pos[drive] % samples->spindlemotor_loop.samples; - loop_left = (int16_t) (float) samples->spindlemotor_loop.buffer[loop_pos * 2] / 4.0f * samples->spindlemotor_loop.volume; - loop_right = (int16_t) (float) samples->spindlemotor_loop.buffer[loop_pos * 2 + 1] / 4.0f * samples->spindlemotor_loop.volume; - } + left_sample = (int16_t) ((float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_loop.volume); + right_sample = (int16_t) ((float) samples->spindlemotor_loop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_loop.volume); + spindlemotor_pos[drive]++; - /* Get stop sample with volume control */ - if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { - stop_left = (int16_t) (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_stop.volume; - stop_right = (int16_t) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_stop.volume; + if (spindlemotor_pos[drive] >= samples->spindlemotor_loop.samples) { + spindlemotor_pos[drive] = 0; + } } + break; - /* Mix the sounds */ - left_sample = loop_left * loop_volume + stop_left * stop_volume; - right_sample = loop_right * loop_volume + stop_right * stop_volume; + case MOTOR_STATE_STOPPING: + if (spindlemotor_fade_samples_remaining[drive] > 0) { + float loop_volume = spindlemotor_fade_volume[drive]; + float stop_volume = 1.0f - loop_volume; - spindlemotor_pos[drive]++; - spindlemotor_fade_samples_remaining[drive]--; + int16_t loop_left = 0, loop_right = 0; + int16_t stop_left = 0, stop_right = 0; + + if (samples->spindlemotor_loop.buffer && samples->spindlemotor_loop.samples > 0) { + int loop_pos = spindlemotor_pos[drive] % samples->spindlemotor_loop.samples; + loop_left = (int16_t) ((float) samples->spindlemotor_loop.buffer[loop_pos * 2] / 4.0f * samples->spindlemotor_loop.volume); + loop_right = (int16_t) ((float) samples->spindlemotor_loop.buffer[loop_pos * 2 + 1] / 4.0f * samples->spindlemotor_loop.volume); + } + + if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { + stop_left = (int16_t) ((float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_stop.volume); + stop_right = (int16_t) ((float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_stop.volume); + } + + left_sample = (int16_t) (loop_left * loop_volume + stop_left * stop_volume); + right_sample = (int16_t) (loop_right * loop_volume + stop_right * stop_volume); - /* Update fade volume */ - spindlemotor_fade_volume[drive] = (int16_t) (float) spindlemotor_fade_samples_remaining[drive] / FADE_SAMPLES; - } else { - /* Fade completed, play remaining stop sound with volume control */ - if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { - left_sample = (int16_t) (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_stop.volume; - right_sample = (int16_t) (float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_stop.volume; spindlemotor_pos[drive]++; + spindlemotor_fade_samples_remaining[drive]--; + + spindlemotor_fade_volume[drive] = (float) spindlemotor_fade_samples_remaining[drive] / FADE_SAMPLES; } else { - /* Stop sound finished */ - spindlemotor_state[drive] = MOTOR_STATE_STOPPED; - /* Note: Timer disabling is handled by fdd.c, not here */ + if (samples->spindlemotor_stop.buffer && spindlemotor_pos[drive] < samples->spindlemotor_stop.samples) { + left_sample = (int16_t) ((float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2] / 4.0f * samples->spindlemotor_stop.volume); + right_sample = (int16_t) ((float) samples->spindlemotor_stop.buffer[spindlemotor_pos[drive] * 2 + 1] / 4.0f * samples->spindlemotor_stop.volume); + spindlemotor_pos[drive]++; + } else { + spindlemotor_state[drive] = MOTOR_STATE_STOPPED; + } } - } - break; + break; - default: - break; + default: + break; + } } - } - /* Process single step audio */ - if (single_step_state[drive].active) { - if (samples->single_track_step.buffer && single_step_state[drive].position < samples->single_track_step.samples) { - /* Mix step sound with motor sound with volume control */ - int16_t step_left = (int16_t) (float) samples->single_track_step.buffer[single_step_state[drive].position * 2] / 4.0f * samples->single_track_step.volume; - int16_t step_right = (int16_t) (float) samples->single_track_step.buffer[single_step_state[drive].position * 2 + 1] / 4.0f * samples->single_track_step.volume; - - left_sample += step_left; - right_sample += step_right; - - single_step_state[drive].position++; - } else { - /* Step sound finished */ - single_step_state[drive].active = 0; - single_step_state[drive].position = 0; - } - } + /* Process all concurrent seek audio slots */ + for (int slot = 0; slot < MAX_CONCURRENT_SEEKS; slot++) { + if (!seek_state[drive][slot].active) + continue; + + int track_diff = seek_state[drive][slot].track_diff; + if (track_diff > 0 && track_diff <= MAX_SEEK_SAMPLES) { + int idx = track_diff - 1; + int is_seek_down = (seek_state[drive][slot].to_track < seek_state[drive][slot].from_track); + audio_sample_t *seek_sample = is_seek_down ? &samples->seek_down[idx] : &samples->seek_up[idx]; + + if (seek_sample && seek_sample->buffer && seek_state[drive][slot].position < seek_sample->samples) { + /* Mix seek sound with existing audio */ + int16_t seek_left = (int16_t) ((float) seek_sample->buffer[seek_state[drive][slot].position * 2] / 4.0f * seek_sample->volume); + int16_t seek_right = (int16_t) ((float) seek_sample->buffer[seek_state[drive][slot].position * 2 + 1] / 4.0f * seek_sample->volume); + + left_sample += seek_left; + right_sample += seek_right; - /* Process multi-track seek audio */ - if (multi_seek_state[drive].active) { - if (samples->multi_track_seek.buffer && - multi_seek_state[drive].position < multi_seek_state[drive].duration_samples && - multi_seek_state[drive].position < samples->multi_track_seek.samples) { - /* Mix seek sound with motor sound with volume control */ - int16_t seek_left = (int16_t) (float) samples->multi_track_seek.buffer[multi_seek_state[drive].position * 2] / 4.0f * samples->multi_track_seek.volume; - int16_t seek_right = (int16_t) (float) samples->multi_track_seek.buffer[multi_seek_state[drive].position * 2 + 1] / 4.0f * samples->multi_track_seek.volume; - - left_sample += seek_left; - right_sample += seek_right; - - multi_seek_state[drive].position++; - } else { - /* Seek sound finished */ - multi_seek_state[drive].active = 0; - multi_seek_state[drive].position = 0; - multi_seek_state[drive].duration_samples = 0; - multi_seek_state[drive].from_track = -1; - multi_seek_state[drive].to_track = -1; + seek_state[drive][slot].position++; + } else { + /* Seek sound finished */ + seek_state[drive][slot].active = 0; + seek_state[drive][slot].position = 0; + seek_state[drive][slot].duration_samples = 0; + seek_state[drive][slot].from_track = -1; + seek_state[drive][slot].to_track = -1; + seek_state[drive][slot].track_diff = 0; + } + } } - } - /* Mix this drive's audio into the buffer */ - int16_buffer[i * 2] += left_sample; - int16_buffer[i * 2 + 1] += right_sample; + /* Mix this drive's audio into the buffer */ + int16_buffer[i * 2] += left_sample; + int16_buffer[i * 2 + 1] += right_sample; + } } } } #else /* Stub implementations when audio is disabled */ -void fdd_audio_load_profiles(void) {} -int fdd_audio_get_profile_count(void) { return 1; } -const fdd_audio_profile_config_t* fdd_audio_get_profile(int id) { - static fdd_audio_profile_config_t none_profile = {0, "None", "none"}; - return (id == 0) ? &none_profile : NULL; +void +fdd_audio_load_profiles(void) +{ +} +int +fdd_audio_get_profile_count(void) +{ + return 1; +} +const fdd_audio_profile_config_t * +fdd_audio_get_profile(int id) +{ + static fdd_audio_profile_config_t none_profile = { 0, "None", "none" }; + return (id == 0) ? &none_profile : NULL; +} +const char * +fdd_audio_get_profile_name(int id) +{ + return (id == 0) ? "None" : NULL; +} +const char * +fdd_audio_get_profile_internal_name(int id) +{ + return (id == 0) ? "none" : NULL; +} +int +fdd_audio_get_profile_by_internal_name(const char *internal_name) +{ + return 0; +} +double +fdd_audio_get_seek_time(int drive, int track_count, int is_seek_down) +{ + return 0; +} +void +fdd_audio_init(void) +{ +} +void +fdd_audio_close(void) +{ } -const char* fdd_audio_get_profile_name(int id) { return (id == 0) ? "None" : NULL; } -const char* fdd_audio_get_profile_internal_name(int id) { return (id == 0) ? "none" : NULL; } -int fdd_audio_get_profile_by_internal_name(const char* internal_name) { return 0; } -double fdd_audio_get_seek_time(int drive, int is_initial, int track_count) { - return is_initial ? 15000.0 : 6000.0; +void +fdd_audio_set_motor_enable(int drive, int motor_enable) +{ +} +void +fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track) +{ } -void fdd_audio_init(void) {} -void fdd_audio_close(void) {} -void fdd_audio_set_motor_enable(int drive, int motor_enable) {} -void fdd_audio_play_single_track_step(int drive, int from_track, int to_track) {} -void fdd_audio_play_multi_track_seek(int drive, int from_track, int to_track) {} -void fdd_audio_callback(int16_t *buffer, int length) { memset(buffer, 0, length * sizeof(int16_t)); } - -#endif /* DISABLE_FDD_AUDIO */ \ No newline at end of file +void +fdd_audio_callback(int16_t *buffer, int length) +{ + memset(buffer, 0, length * sizeof(int16_t)); +} + +#endif /* DISABLE_FDD_AUDIO */ diff --git a/src/game/gameport.c b/src/game/gameport.c index 88ff5cc8af8..d7ecadec43b 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -88,27 +88,52 @@ static const joystick_t joystick_none = { static const struct { const joystick_t *joystick; } joysticks[] = { - { &joystick_none }, - { &joystick_2axis_2button }, - { &joystick_2button_gamepad }, - { &joystick_2button_flight_yoke }, - { &joystick_2axis_4button }, - { &joystick_4button_gamepad }, - { &joystick_4button_flight_yoke }, - { &joystick_2axis_6button }, - { &joystick_2axis_8button }, - { &joystick_3axis_2button }, - { &joystick_2button_yoke_throttle }, - { &joystick_3axis_4button }, - { &joystick_steering_wheel_4_button }, - { &joystick_4button_yoke_throttle }, - { &joystick_4axis_4button }, - { &joystick_ch_flightstick_pro }, - { &joystick_ch_flightstick_pro_ch_pedals }, - { &joystick_sw_pad }, - { &joystick_tm_fcs }, - { &joystick_tm_fcs_rcs }, - { NULL } + { &joystick_none }, + { &joystick_generic_paddle }, + { &joystick_2axis_1button }, + { &joystick_2axis_2button }, + { &joystick_2axis_3button }, + { &joystick_2axis_4button }, + { &joystick_2axis_6button }, + { &joystick_2axis_8button }, + { &joystick_3axis_2button }, + { &joystick_3axis_3button }, + { &joystick_3axis_4button }, + { &joystick_4axis_2button }, + { &joystick_4axis_3button }, + { &joystick_4axis_4button }, + { &joystick_2button_gamepad }, + { &joystick_3button_gamepad }, + { &joystick_4button_gamepad }, + { &joystick_6button_gamepad }, + { &joystick_gravis_gamepad }, + { &joystick_2button_flight_yoke }, + { &joystick_3button_flight_yoke }, + { &joystick_4button_flight_yoke }, + { &joystick_2button_yoke_throttle }, + { &joystick_3button_yoke_throttle }, + { &joystick_4button_yoke_throttle }, + { &joystick_steering_wheel_2_button }, + { &joystick_steering_wheel_3_button }, + { &joystick_steering_wheel_4_button }, + { &joystick_ch_flightstick }, + { &joystick_ch_flightstick_ch_pedals }, + { &joystick_ch_flightstick_ch_pedals_pro }, + { &joystick_ch_flightstick_pro }, + { &joystick_ch_flightstick_pro_ch_pedals }, + { &joystick_ch_flightstick_pro_ch_pedals_pro }, + { &joystick_ch_virtual_pilot }, + { &joystick_ch_virtual_pilot_ch_pedals }, + { &joystick_ch_virtual_pilot_ch_pedals_pro }, + { &joystick_ch_virtual_pilot_pro }, + { &joystick_ch_virtual_pilot_pro_ch_pedals }, + { &joystick_ch_virtual_pilot_pro_ch_pedals_pro }, + { &joystick_sw_pad }, + { &joystick_tm_fcs }, + { &joystick_tm_fcs_rcs }, + { &joystick_tm_formula_t1t2 }, + { &joystick_tm_formula_t1t2wa }, + { NULL } }; static joystick_instance_t *joystick_instance[GAMEPORT_MAX] = { NULL, NULL }; diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 84dc5a380ee..dc82feb8b3b 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -44,18 +44,7 @@ #include <86box/timer.h> #include <86box/gameport.h> #include <86box/plat_unused.h> - -static void * -ch_flightstick_pro_init(void) -{ - return NULL; -} - -static void -ch_flightstick_pro_close(UNUSED(void *priv)) -{ - // -} +#include <86box/joystick.h> static uint8_t ch_flightstick_pro_read(UNUSED(void *priv)) @@ -72,114 +61,299 @@ ch_flightstick_pro_read(UNUSED(void *priv)) ret &= ~0x40; if (joystick_state[gp][0].button[3]) ret &= ~0x80; + // POV Hat if (joystick_state[gp][0].pov[0] != -1) { // POV Up if ((joystick_state[gp][0].pov[0] > 315) || (joystick_state[gp][0].pov[0] < 45)) - ret &= ~0xf0; + ret &= ~0xf0; // 1, 2, 3, 4 // POV Right - else if ((joystick_state[gp][0].pov[0]) >= 45 && (joystick_state[gp][0].pov[0] < 135)) - ret &= ~0xb0; + else if ((joystick_state[gp][0].pov[0] >= 45) && (joystick_state[gp][0].pov[0] < 135)) + ret &= ~0xb0; // 1, 2, 4 // POV Down - else if ((joystick_state[gp][0].pov[0]) >= 135 && (joystick_state[gp][0].pov[0] < 225)) - ret &= ~0x70; + else if ((joystick_state[gp][0].pov[0] >= 135) && (joystick_state[gp][0].pov[0] < 225)) + ret &= ~0x70; // 1, 2, 3 // POV Left - else if ((joystick_state[gp][0].pov[0]) >= 225 && (joystick_state[gp][0].pov[0] < 315)) - ret &= ~0x30; + else if ((joystick_state[gp][0].pov[0] >= 225) && (joystick_state[gp][0].pov[0] < 315)) + ret &= ~0x30; // 1, 2 } } return ret; } -static void -ch_flightstick_pro_write(UNUSED(void *priv)) +static uint8_t +ch_virtual_pilot_pro_read(UNUSED(void *priv)) { - // -} + uint8_t gp = 0; + uint8_t ret = 0xf0; -static int -ch_flightstick_pro_read_axis(UNUSED(void *priv), int axis) -{ - uint8_t gp = 0; - - if (!JOYSTICK_PRESENT(gp, 0)) - return AXIS_NOT_PRESENT; - - switch (axis) { - case 0: - return joystick_state[gp][0].axis[0]; - case 1: - return joystick_state[gp][0].axis[1]; - case 2: - return 0; - case 3: - return joystick_state[gp][0].axis[2]; - default: - return 0; - } -} + if (JOYSTICK_PRESENT(gp, 0)) { + if (joystick_state[gp][0].button[0]) // 1 + ret &= ~0x10; + if (joystick_state[gp][0].button[1]) // 2 + ret &= ~0x20; + if (joystick_state[gp][0].button[2]) // 3 + ret &= ~0x40; + if (joystick_state[gp][0].button[3]) // 4 + ret &= ~0x80; + if (joystick_state[gp][0].button[4]) // 1, 3 + ret &= ~0x50; + if (joystick_state[gp][0].button[5]) // 1, 4 + ret &= ~0x90; -static int -ch_flightstick_pro_ch_pedals_read_axis(UNUSED(void *priv), int axis) -{ - uint8_t gp = 0; - - if (!JOYSTICK_PRESENT(gp, 0)) - return AXIS_NOT_PRESENT; - - switch (axis) { - case 0: - return joystick_state[gp][0].axis[0]; - case 1: - return joystick_state[gp][0].axis[1]; - case 2: - return joystick_state[gp][0].axis[3]; - case 3: - return joystick_state[gp][0].axis[2]; - default: - return 0; + // Right POV Hat + uint8_t pov_id = 0; + + if (joystick_state[gp][0].pov[pov_id] != -1) { + // POV Up + if ((joystick_state[gp][0].pov[pov_id] > 315) || (joystick_state[gp][0].pov[pov_id] < 45)) + ret &= ~0xf0; // 1, 2, 3, 4 + // POV Right + else if ((joystick_state[gp][0].pov[pov_id] >= 45) && (joystick_state[gp][0].pov[pov_id] < 135)) + ret &= ~0xb0; // 1, 2, 4 + // POV Down + else if ((joystick_state[gp][0].pov[pov_id] >= 135) && (joystick_state[gp][0].pov[pov_id] < 225)) + ret &= ~0x70; // 1, 2, 3 + // POV Left + else if ((joystick_state[gp][0].pov[pov_id] >= 225) && (joystick_state[gp][0].pov[pov_id] < 315)) + ret &= ~0x30; // 1, 2 + } + + // Left POV Hat + pov_id = 1; + + if (joystick_state[gp][0].pov[pov_id] != -1) { + // POV Up + if ((joystick_state[gp][0].pov[pov_id] > 315) || (joystick_state[gp][0].pov[pov_id] < 45)) + ret &= ~0xe0; // 2, 3, 4 + // POV Right + else if ((joystick_state[gp][0].pov[pov_id] >= 45) && (joystick_state[gp][0].pov[pov_id] < 135)) + ret &= ~0xa0; // 2, 4 + // POV Down + else if ((joystick_state[gp][0].pov[pov_id] >= 135) && (joystick_state[gp][0].pov[pov_id] < 225)) + ret &= ~0x60; // 2, 3 + // POV Left + else if ((joystick_state[gp][0].pov[pov_id] >= 225) && (joystick_state[gp][0].pov[pov_id] < 315)) + ret &= ~0xc0; // 3, 4 + } } -} -static void -ch_flightstick_pro_a0_over(UNUSED(void *priv)) -{ - // + return ret; } +const joystick_t joystick_ch_flightstick = { + .name = "CH Flightstick", + .internal_name = "ch_flightstick", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_ch_flightstick_ch_pedals = { + .name = "CH Flightstick + CH Pedals", + .internal_name = "ch_flightstick_ch_pedals", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle", "Rudder (Yaw)" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_ch_flightstick_ch_pedals_pro = { + .name = "CH Flightstick + CH Pedals Pro", + .internal_name = "ch_flightstick_ch_pedals_pro", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Left Pedal", "Right Pedal" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + const joystick_t joystick_ch_flightstick_pro = { .name = "CH Flightstick Pro", .internal_name = "ch_flightstick_pro", - .init = ch_flightstick_pro_init, - .close = ch_flightstick_pro_close, + .init = joystick_standard_init, + .close = joystick_standard_close, .read = ch_flightstick_pro_read, - .write = ch_flightstick_pro_write, - .read_axis = ch_flightstick_pro_read_axis, - .a0_over = ch_flightstick_pro_a0_over, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, .axis_count = 3, .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = { "X axis", "Y axis", "Throttle" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, .pov_names = { "POV" } }; const joystick_t joystick_ch_flightstick_pro_ch_pedals = { .name = "CH Flightstick Pro + CH Pedals", .internal_name = "ch_flightstick_pro_ch_pedals", - .init = ch_flightstick_pro_init, - .close = ch_flightstick_pro_close, + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = ch_flightstick_pro_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 4, + .pov_count = 1, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle", "Rudder (Yaw)" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, + .pov_names = { "POV" } +}; + +const joystick_t joystick_ch_flightstick_pro_ch_pedals_pro = { + .name = "CH Flightstick Pro + CH Pedals Pro", + .internal_name = "ch_flightstick_pro_ch_pedals_pro", + .init = joystick_standard_init, + .close = joystick_standard_close, .read = ch_flightstick_pro_read, - .write = ch_flightstick_pro_write, - .read_axis = ch_flightstick_pro_ch_pedals_read_axis, - .a0_over = ch_flightstick_pro_a0_over, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, .axis_count = 4, .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = { "X axis", "Y axis", "Throttle", "Rudder" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Left Pedal", "Right Pedal" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, .pov_names = { "POV" } }; + +const joystick_t joystick_ch_virtual_pilot = { + .name = "CH Virtual Pilot", + .internal_name = "ch_virtual_pilot", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_ch_virtual_pilot_ch_pedals = { + .name = "CH Virtual Pilot + CH Pedals", + .internal_name = "ch_virtual_pilot_ch_pedals", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle", "Rudder (Yaw)" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_ch_virtual_pilot_ch_pedals_pro = { + .name = "CH Virtual Pilot + CH Pedals Pro", + .internal_name = "ch_virtual_pilot_ch_pedals_pro", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Left Pedal", "Right Pedal" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_ch_virtual_pilot_pro = { + .name = "CH Virtual Pilot Pro", + .internal_name = "ch_virtual_pilot_pro", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = ch_virtual_pilot_pro_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 6, + .pov_count = 2, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, + .pov_names = { "Right POV", "Left POV" } +}; + +const joystick_t joystick_ch_virtual_pilot_pro_ch_pedals = { + .name = "CH Virtual Pilot Pro + CH Pedals", + .internal_name = "ch_virtual_pilot_pro_ch_pedals", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = ch_virtual_pilot_pro_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 6, + .pov_count = 2, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Throttle", "Rudder (Yaw)" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, + .pov_names = { "Right POV", "Left POV" } +}; + +const joystick_t joystick_ch_virtual_pilot_pro_ch_pedals_pro = { + .name = "CH Virtual Pilot Pro + CH Pedals Pro", + .internal_name = "ch_virtual_pilot_pro_ch_pedals_pro", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = ch_virtual_pilot_pro_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 4, + .button_count = 6, + .pov_count = 2, + .max_joysticks = 1, + .axis_names = { "X axis (Roll)", "Y axis (Pitch)", "Left Pedal", "Right Pedal" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, + .pov_names = { "Right POV", "Left POV" } +}; diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index 60ea4b57d80..c62611663a8 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -45,18 +45,39 @@ #include <86box/gameport.h> #include <86box/plat_unused.h> -static void * +void * joystick_standard_init(void) { return NULL; } -static void +void joystick_standard_close(UNUSED(void *priv)) { // } +static uint8_t +joystick_paddle_read(UNUSED(void *priv)) +{ + uint8_t gp = 0; + uint8_t ret = 0xf0; + + if ((JOYSTICK_PRESENT(gp, 0)) && (joystick_state[gp][0].button[0])) + ret &= ~0x10; + + if ((JOYSTICK_PRESENT(gp, 2)) && (joystick_state[gp][2].button[0])) + ret &= ~0x20; + + if ((JOYSTICK_PRESENT(gp, 1)) && (joystick_state[gp][1].button[0])) + ret &= ~0x40; + + if ((JOYSTICK_PRESENT(gp, 3)) && (joystick_state[gp][3].button[0])) + ret &= ~0x80; + + return ret; +} + static uint8_t joystick_standard_read(UNUSED(void *priv)) { @@ -80,7 +101,41 @@ joystick_standard_read(UNUSED(void *priv)) return ret; } +uint8_t +joystick_standard_read_2button(UNUSED(void *priv)) +{ + uint8_t gp = 0; + uint8_t ret = 0xf0; + + if (JOYSTICK_PRESENT(gp, 0)) { + if (joystick_state[gp][0].button[0]) + ret &= ~0x10; + if (joystick_state[gp][0].button[1]) + ret &= ~0x20; + } + + return ret; +} + static uint8_t +joystick_standard_read_3button(UNUSED(void *priv)) +{ + uint8_t gp = 0; + uint8_t ret = 0xf0; + + if (JOYSTICK_PRESENT(gp, 0)) { + if (joystick_state[gp][0].button[0]) + ret &= ~0x10; + if (joystick_state[gp][0].button[1]) + ret &= ~0x20; + if (joystick_state[gp][0].button[2]) + ret &= ~0x40; + } + + return ret; +} + +uint8_t joystick_standard_read_4button(UNUSED(void *priv)) { uint8_t gp = 0; @@ -100,12 +155,39 @@ joystick_standard_read_4button(UNUSED(void *priv)) return ret; } -static void +void joystick_standard_write(UNUSED(void *priv)) { // } +static int +joystick_paddle_read_axis(UNUSED(void *priv), int axis) +{ + uint8_t gp = 0; + + switch (axis) { + case 0: + if (!JOYSTICK_PRESENT(gp, 0)) + return AXIS_NOT_PRESENT; + return joystick_state[gp][0].axis[0]; + case 1: + if (!JOYSTICK_PRESENT(gp, 2)) + return AXIS_NOT_PRESENT; + return joystick_state[gp][2].axis[0]; + case 2: + if (!JOYSTICK_PRESENT(gp, 1)) + return AXIS_NOT_PRESENT; + return joystick_state[gp][1].axis[0]; + case 3: + if (!JOYSTICK_PRESENT(gp, 3)) + return AXIS_NOT_PRESENT; + return joystick_state[gp][3].axis[0]; + default: + return 0; + } +} + static int joystick_standard_read_axis(UNUSED(void *priv), int axis) { @@ -134,7 +216,7 @@ joystick_standard_read_axis(UNUSED(void *priv), int axis) } static int -joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) +joystick_standard_read_axis_2axis(UNUSED(void *priv), int axis) { uint8_t gp = 0; @@ -153,6 +235,26 @@ joystick_standard_read_axis_4button(UNUSED(void *priv), int axis) } } +static int +joystick_standard_read_axis_2axis_t1t2wa(UNUSED(void *priv), int axis) +{ + uint8_t gp = 0; + + if (!JOYSTICK_PRESENT(gp, 0)) + return AXIS_NOT_PRESENT; + + switch (axis) { + case 0: + return joystick_state[gp][0].axis[0]; + case 2: + return joystick_state[gp][0].axis[1]; + case 1: + case 3: + default: + return 0; + } +} + #if 0 // For later use static int @@ -168,7 +270,7 @@ joystick_standard_read_axis_with_pov(UNUSED(void *priv), int axis) return joystick_state[gp][0].axis[0]; case 1: // Y-axis return joystick_state[gp][0].axis[1]; - case 2: // POV Hat (mapped to the 3rd logical axis, index 2) + case 2: // POV Hat if (joystick_state[gp][0].pov[0] == -1) return 32767; // Centered/No input (as per tm_fcs_rcs_read_axis example) if (joystick_state[gp][0].pov[0] > 315 || joystick_state[gp][0].pov[0] < 45) @@ -179,9 +281,8 @@ joystick_standard_read_axis_with_pov(UNUSED(void *priv), int axis) return 0; // Right/Left (example, matches tm_fcs_rcs_read_axis) if (joystick_state[gp][0].pov[0] >= 225 && joystick_state[gp][0].pov[0] < 315) return 16384; // Down-Left (example value, matches tm_fcs_rcs_read_axis) - return 0; // Fallback - case 3: // This case might be used for a Z-axis if present, or can return 0 if not. - // For gamepads with only X/Y and POV, this will likely be unused or return 0. + return 0; + case 3: return 0; default: return 0; @@ -202,16 +303,16 @@ joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis) return joystick_state[gp][0].axis[0]; case 1: return joystick_state[gp][0].axis[1]; - case 2: + case 2: // Rudder Axis return joystick_state[gp][0].axis[2]; - case 3: + case 3: // Throttle Axis default: return 0; } } -static int -joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) +int +joystick_standard_read_axis_3axis_throttle(UNUSED(void *priv), int axis) { uint8_t gp = 0; @@ -223,10 +324,31 @@ joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) return joystick_state[gp][0].axis[0]; case 1: return joystick_state[gp][0].axis[1]; - case 2: + case 3: // Throttle Axis return joystick_state[gp][0].axis[2]; - case 3: + case 2: // Rudder Axis + default: + return 0; + } +} + +int +joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis) +{ + uint8_t gp = 0; + + if (!JOYSTICK_PRESENT(gp, 0)) + return AXIS_NOT_PRESENT; + + switch (axis) { + case 0: + return joystick_state[gp][0].axis[0]; + case 1: + return joystick_state[gp][0].axis[1]; + case 2: // Rudder Axis return joystick_state[gp][0].axis[3]; + case 3: // Throttle Axis + return joystick_state[gp][0].axis[2]; default: return 0; } @@ -283,15 +405,33 @@ joystick_standard_read_axis_8button(UNUSED(void *priv), int axis) } } -static void +void joystick_standard_a0_over(UNUSED(void *priv)) { // } -const joystick_t joystick_2axis_2button = { - .name = "2-axis, 2-button joystick(s)", - .internal_name = "2axis_2button", +const joystick_t joystick_generic_paddle = { + .name = "Generic paddle controller(s)", + .internal_name = "generic_paddle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_paddle_read, + .write = joystick_standard_write, + .read_axis = joystick_paddle_read_axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 1, + .button_count = 1, + .pov_count = 0, + .max_joysticks = 4, + .axis_names = { "X axis" }, + .button_names = { "Button 1" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_2axis_1button = { + .name = "2-axis, 1-button joystick(s)", + .internal_name = "2axis_1button", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read, @@ -299,17 +439,17 @@ const joystick_t joystick_2axis_2button = { .read_axis = joystick_standard_read_axis, .a0_over = joystick_standard_a0_over, .axis_count = 2, - .button_count = 2, + .button_count = 1, .pov_count = 0, .max_joysticks = 2, .axis_names = { "X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2" }, + .button_names = { "Button 1" }, .pov_names = { NULL } }; -const joystick_t joystick_2button_gamepad = { - .name = "2-button gamepad(s)", - .internal_name = "2button_gamepad", +const joystick_t joystick_2axis_2button = { + .name = "2-axis, 2-button joystick(s)", + .internal_name = "2axis_2button", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read, @@ -325,21 +465,21 @@ const joystick_t joystick_2button_gamepad = { .pov_names = { NULL } }; -const joystick_t joystick_2button_flight_yoke = { - .name = "2-button flight yoke", - .internal_name = "2button_flight_yoke", +const joystick_t joystick_2axis_3button = { + .name = "2-axis, 3-button joystick", + .internal_name = "2axis_3button", .init = joystick_standard_init, .close = joystick_standard_close, - .read = joystick_standard_read, + .read = joystick_standard_read_3button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis, + .read_axis = joystick_standard_read_axis_2axis, .a0_over = joystick_standard_a0_over, .axis_count = 2, - .button_count = 2, + .button_count = 3, .pov_count = 0, - .max_joysticks = 2, - .axis_names = { "Roll axis", "Pitch axis" }, - .button_names = { "Trigger", "Button 2" }, + .max_joysticks = 1, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3" }, .pov_names = { NULL } }; @@ -350,7 +490,7 @@ const joystick_t joystick_2axis_4button = { .close = joystick_standard_close, .read = joystick_standard_read_4button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_4button, + .read_axis = joystick_standard_read_axis_2axis, .a0_over = joystick_standard_a0_over, .axis_count = 2, .button_count = 4, @@ -361,39 +501,39 @@ const joystick_t joystick_2axis_4button = { .pov_names = { NULL } }; -const joystick_t joystick_4button_gamepad = { - .name = "4-button gamepad", - .internal_name = "4button_gamepad", +const joystick_t joystick_2axis_6button = { + .name = "2-axis, 6-button joystick", + .internal_name = "2axis_6button", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read_4button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_4button, + .read_axis = joystick_standard_read_axis_6button, .a0_over = joystick_standard_a0_over, .axis_count = 2, - .button_count = 4, + .button_count = 6, .pov_count = 0, .max_joysticks = 1, .axis_names = { "X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, .pov_names = { NULL } }; -const joystick_t joystick_4button_flight_yoke = { - .name = "4-button flight yoke", - .internal_name = "4button_flight_yoke", +const joystick_t joystick_2axis_8button = { + .name = "2-axis, 8-button joystick", + .internal_name = "2axis_8button", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read_4button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_4button, + .read_axis = joystick_standard_read_axis_8button, .a0_over = joystick_standard_a0_over, .axis_count = 2, - .button_count = 4, + .button_count = 8, .pov_count = 0, .max_joysticks = 1, - .axis_names = { "Roll axis", "Pitch axis" }, - .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, .pov_names = { NULL } }; @@ -402,9 +542,9 @@ const joystick_t joystick_3axis_2button = { .internal_name = "3axis_2button", .init = joystick_standard_init, .close = joystick_standard_close, - .read = joystick_standard_read, + .read = joystick_standard_read_2button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_3axis, + .read_axis = joystick_standard_read_axis_3axis_throttle, .a0_over = joystick_standard_a0_over, .axis_count = 3, .button_count = 2, @@ -415,21 +555,21 @@ const joystick_t joystick_3axis_2button = { .pov_names = { NULL } }; -const joystick_t joystick_2button_yoke_throttle = { - .name = "2-button flight yoke with throttle", - .internal_name = "2button_yoke_throttle", +const joystick_t joystick_3axis_3button = { + .name = "3-axis, 3-button joystick", + .internal_name = "3axis_3button", .init = joystick_standard_init, .close = joystick_standard_close, - .read = joystick_standard_read, + .read = joystick_standard_read_3button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_3axis, + .read_axis = joystick_standard_read_axis_3axis_throttle, .a0_over = joystick_standard_a0_over, .axis_count = 3, - .button_count = 2, + .button_count = 3, .pov_count = 0, .max_joysticks = 1, - .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, - .button_names = { "Trigger", "Button 2" }, + .axis_names = { "X axis", "Y axis", "Z axis" }, + .button_names = { "Button 1", "Button 2", "Button 3" }, .pov_names = { NULL } }; @@ -440,7 +580,7 @@ const joystick_t joystick_3axis_4button = { .close = joystick_standard_close, .read = joystick_standard_read_4button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_3axis, + .read_axis = joystick_standard_read_axis_3axis_throttle, .a0_over = joystick_standard_a0_over, .axis_count = 3, .button_count = 4, @@ -451,39 +591,39 @@ const joystick_t joystick_3axis_4button = { .pov_names = { NULL } }; -const joystick_t joystick_4button_yoke_throttle = { - .name = "4-button flight yoke with throttle", - .internal_name = "4button_yoke_throttle", +const joystick_t joystick_4axis_2button = { + .name = "4-axis, 2-button joystick", + .internal_name = "4axis_2button", .init = joystick_standard_init, .close = joystick_standard_close, - .read = joystick_standard_read_4button, + .read = joystick_standard_read_2button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_3axis, + .read_axis = joystick_standard_read_axis_4axis, .a0_over = joystick_standard_a0_over, - .axis_count = 3, - .button_count = 4, + .axis_count = 4, + .button_count = 2, .pov_count = 0, .max_joysticks = 1, - .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .axis_names = { "X axis", "Y axis", "Z axis", "zX axis" }, + .button_names = { "Button 1", "Button 2" }, .pov_names = { NULL } }; -const joystick_t joystick_steering_wheel_4_button = { - .name = "Steering Wheel (3-axis, 4-button)", - .internal_name = "steering_wheel_4_button", +const joystick_t joystick_4axis_3button = { + .name = "4-axis, 3-button joystick", + .internal_name = "4axis_3button", .init = joystick_standard_init, .close = joystick_standard_close, - .read = joystick_standard_read_4button, + .read = joystick_standard_read_3button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_3axis, + .read_axis = joystick_standard_read_axis_4axis, .a0_over = joystick_standard_a0_over, - .axis_count = 3, - .button_count = 4, + .axis_count = 4, + .button_count = 3, .pov_count = 0, .max_joysticks = 1, - .axis_names = { "Steering axis", "Accelerator axis", "Brake axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .axis_names = { "X axis", "Y axis", "Z axis", "zX axis" }, + .button_names = { "Button 1", "Button 2", "Button 3" }, .pov_names = { NULL } }; @@ -505,9 +645,63 @@ const joystick_t joystick_4axis_4button = { .pov_names = { NULL } }; -const joystick_t joystick_2axis_6button = { - .name = "2-axis, 6-button joystick", - .internal_name = "2axis_6button", +const joystick_t joystick_2button_gamepad = { + .name = "2-button gamepad(s)", + .internal_name = "2button_gamepad", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 2, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_3button_gamepad = { + .name = "3-button gamepad", + .internal_name = "3button_gamepad", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_3button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 3, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_4button_gamepad = { + .name = "4-button gamepad", + .internal_name = "4button_gamepad", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_6button_gamepad = { + .name = "6-button gamepad", + .internal_name = "6button_gamepad", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read_4button, @@ -523,20 +717,220 @@ const joystick_t joystick_2axis_6button = { .pov_names = { NULL } }; -const joystick_t joystick_2axis_8button = { - .name = "2-axis, 8-button joystick", - .internal_name = "2axis_8button", +const joystick_t joystick_gravis_gamepad = { + .name = "Gravis PC GamePad", + .internal_name = "gravis_gamepad", .init = joystick_standard_init, .close = joystick_standard_close, .read = joystick_standard_read_4button, .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_8button, + .read_axis = joystick_standard_read_axis_2axis, .a0_over = joystick_standard_a0_over, .axis_count = 2, - .button_count = 8, + .button_count = 4, .pov_count = 0, .max_joysticks = 1, .axis_names = { "X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, + // TODO: Check this + .button_names = { "Button 1 (Red)", "Button 2 (Blue)", "Button 3 (Yellow)", "Button 4 (Green)" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_2button_flight_yoke = { + .name = "2-button flight yoke", + .internal_name = "2button_flight_yoke", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 2, + .axis_names = { "Roll axis", "Pitch axis" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_3button_flight_yoke = { + .name = "3-button flight yoke", + .internal_name = "3button_flight_yoke", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_3button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 3, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis" }, + .button_names = { "Trigger", "Button 2", "Button 3" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_4button_flight_yoke = { + .name = "4-button flight yoke", + .internal_name = "4button_flight_yoke", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_2button_yoke_throttle = { + .name = "2-button flight yoke with throttle", + .internal_name = "2button_yoke_throttle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, + .button_names = { "Trigger", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_3button_yoke_throttle = { + .name = "3-button flight yoke with throttle", + .internal_name = "3button_yoke_throttle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_3button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 3, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, + .button_names = { "Trigger", "Button 2", "Button 3" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_4button_yoke_throttle = { + .name = "4-button flight yoke with throttle", + .internal_name = "4button_yoke_throttle", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis_throttle, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Roll axis", "Pitch axis", "Throttle axis" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_steering_wheel_2_button = { + .name = "Steering wheel (3-axis, 2-button)", + .internal_name = "steering_wheel_2_button", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_2button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 2, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator axis", "Brake axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_steering_wheel_3_button = { + .name = "Steering wheel (3-axis, 3-button)", + .internal_name = "steering_wheel_3_button", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_3button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 3, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator axis", "Brake axis" }, + .button_names = { "Button 1", "Button 2", "Button 3" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_steering_wheel_4_button = { + .name = "Steering wheel (3-axis, 4-button)", + .internal_name = "steering_wheel_4_button", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_3axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 3, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator axis", "Brake axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } +}; + +const joystick_t joystick_tm_formula_t1t2 = { + .name = "Thrustmaster Formula T1/T2 with adapter", + .internal_name = "thrustmaster_formula_t1t2", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator/Brake axis" }, + .button_names = { "Shifter Up", "Shifter Down", "Top Console Switch", "Bottom Console Switch" }, + .pov_names = { NULL } +}; + +// TODO Validate this +const joystick_t joystick_tm_formula_t1t2wa = { + .name = "Thrustmaster Formula T1/T2 without adapter", + .internal_name = "thrustmaster_formula_t1t2wa", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_2axis_t1t2wa, + .a0_over = joystick_standard_a0_over, + .axis_count = 2, + .button_count = 4, + .pov_count = 0, + .max_joysticks = 1, + .axis_names = { "Steering axis", "Accelerator/Brake axis" }, + .button_names = { "Shifter Up", "Shifter Down", "Top Console Switch", "Bottom Console Switch" }, .pov_names = { NULL } }; diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index c8368612db4..1f420ef0c55 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -44,44 +44,7 @@ #include <86box/timer.h> #include <86box/gameport.h> #include <86box/plat_unused.h> - -static void * -tm_fcs_init(void) -{ - return NULL; -} - -static void -tm_fcs_close(UNUSED(void *priv)) -{ - // -} - -static uint8_t -tm_fcs_read(UNUSED(void *priv)) -{ - uint8_t gp = 0; - uint8_t ret = 0xf0; - - if (JOYSTICK_PRESENT(gp, 0)) { - if (joystick_state[gp][0].button[0]) - ret &= ~0x10; - if (joystick_state[gp][0].button[1]) - ret &= ~0x20; - if (joystick_state[gp][0].button[2]) - ret &= ~0x40; - if (joystick_state[gp][0].button[3]) - ret &= ~0x80; - } - - return ret; -} - -static void -tm_fcs_write(UNUSED(void *priv)) -{ - // -} +#include <86box/joystick.h> static int tm_fcs_read_axis(UNUSED(void *priv), int axis) @@ -96,8 +59,6 @@ tm_fcs_read_axis(UNUSED(void *priv), int axis) return joystick_state[gp][0].axis[0]; case 1: return joystick_state[gp][0].axis[1]; - case 2: - return 0; case 3: if (joystick_state[gp][0].pov[0] == -1) return 32767; @@ -110,6 +71,7 @@ tm_fcs_read_axis(UNUSED(void *priv), int axis) if (joystick_state[gp][0].pov[0] >= 225 && joystick_state[gp][0].pov[0] < 315) return 16384; return 0; + case 2: default: return 0; } @@ -147,44 +109,38 @@ tm_fcs_rcs_read_axis(UNUSED(void *priv), int axis) } } -static void -tm_fcs_a0_over(UNUSED(void *priv)) -{ - // -} - const joystick_t joystick_tm_fcs = { .name = "Thrustmaster Flight Control System", .internal_name = "thrustmaster_fcs", - .init = tm_fcs_init, - .close = tm_fcs_close, - .read = tm_fcs_read, - .write = tm_fcs_write, + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, .read_axis = tm_fcs_read_axis, - .a0_over = tm_fcs_a0_over, + .a0_over = joystick_standard_a0_over, .axis_count = 2, .button_count = 4, .pov_count = 1, .max_joysticks = 1, .axis_names = { "X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, .pov_names = { "POV" } }; const joystick_t joystick_tm_fcs_rcs = { .name = "Thrustmaster FCS + Rudder Control System", .internal_name = "thrustmaster_fcs_rcs", - .init = tm_fcs_init, - .close = tm_fcs_close, - .read = tm_fcs_read, - .write = tm_fcs_write, + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, .read_axis = tm_fcs_rcs_read_axis, - .a0_over = tm_fcs_a0_over, + .a0_over = joystick_standard_a0_over, .axis_count = 3, .button_count = 4, .pov_count = 1, .max_joysticks = 1, .axis_names = { "X axis", "Y axis", "Rudder" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .button_names = { "Trigger", "Button 2", "Button 3", "Button 4" }, .pov_names = { "POV" } }; diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index 6c924e03174..12eb5dbb5b6 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -98,6 +98,48 @@ # define LIKELY(x) (x) #endif +/* Platform-specific atomic handling */ +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) + /* On x86/x64, aligned int/uint32_t accesses are naturally atomic */ + /* Use volatile for performance, as the original code did */ + #define ATOMIC_INT volatile int + #define ATOMIC_UINT volatile uint32_t + #define ATOMIC_DOUBLE volatile double + #define ATOMIC_LOAD(var) (var) + #define ATOMIC_STORE(var, val) ((var) = (val)) + #define ATOMIC_INC(var) (++(var)) + #define ATOMIC_DEC(var) (--(var)) + #define ATOMIC_ADD(var, val) ((var) += (val)) + #define ATOMIC_SUB(var, val) ((var) -= (val)) + #define ATOMIC_DOUBLE_ADD(var, val) ((var) += (val)) +#else + /* On ARM and other architectures, use proper atomics */ +#ifdef failing_code + #ifdef __cplusplus + # include + using atomic_int = std::atomic; + using atomic_uint = std::atomic; + #else + # include + #endif +#else + #ifndef __cplusplus + # include + #endif +#endif + + #define ATOMIC_INT atomic_int + #define ATOMIC_UINT atomic_uint + #define ATOMIC_DOUBLE _Atomic double + #define ATOMIC_LOAD(var) atomic_load(&(var)) + #define ATOMIC_STORE(var, val) atomic_store(&(var), (val)) + #define ATOMIC_INC(var) atomic_fetch_add(&(var), 1) + #define ATOMIC_DEC(var) atomic_fetch_sub(&(var), 1) + #define ATOMIC_ADD(var, val) atomic_fetch_add(&(var), val) + #define ATOMIC_SUB(var, val) atomic_fetch_sub(&(var), val) + #define ATOMIC_DOUBLE_ADD(var, val) atomic_double_add(&(var), val) +#endif + #ifdef __cplusplus extern "C" { #endif @@ -288,7 +330,7 @@ struct accelKey { char desc[64]; char seq[64]; }; -#define NUM_ACCELS 8 +#define NUM_ACCELS 9 extern struct accelKey acc_keys[NUM_ACCELS]; extern struct accelKey def_acc_keys[NUM_ACCELS]; extern int FindAccelerator(const char *name); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 5ddb2400f8b..409e303bc25 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -142,9 +142,10 @@ static const struct cdrom_drive_types_s { /* TODO: Find an IDENTIFY and/or INQUIRY dump. */ { "GOLDSTAR", "GCD-R560B", "1.00", "goldstar_r560b", BUS_TYPE_IDE, 0, 6, 36, 0, 0, { 4, 2, 2, -1 } }, { "HITACHI", "CDR-8130", "0020", "hitachi_r8130", BUS_TYPE_IDE, 0, 16, 36, 0, 0, { 4, 2, 2, -1 } }, - { "HITACHI", "GD-7500", "A1 ", "hitachi_7500", BUS_TYPE_IDE, 0, 40, 36, 0, 0, { 4, 2, 2, 2 } }, /* DVD. */ + { "HITACHI", "CDR-8435", "0010", "hitachi_r8435", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 4, 2, 2, -1 } }, + { "HITACHI", "GD-7500", "A1 ", "hitachi_7500", BUS_TYPE_IDE, 0, 40, 36, 0, 1, { 4, 2, 2, 2 } }, /* DVD. */ { "HL-DT-ST", "CD-ROM GCR-8526B", "1.01", "hldtst_8526b", BUS_TYPE_IDE, 0, 52, 36, 0, 0, { 4, 2, 2, 2 } }, - { "HL-DT-ST", "DVDRAM GSA-4160", "A302", "hldtst_4160", BUS_TYPE_IDE, 0, 40, 36, 0, 0, { 4, 2, 2, 2 } }, + { "HL-DT-ST", "DVDRAM GSA-4160", "A302", "hldtst_4160", BUS_TYPE_IDE, 0, 40, 36, 0, 1, { 4, 2, 2, 2 } }, { "KENWOOD", "CD-ROM UCR-421", "208E", "kenwood_421", BUS_TYPE_IDE, 0, 72, 36, 0, 0, { 4, 2, 2, 4 } }, /* This is a laptop/notebook drive, as is also evident from the name: @@ -182,6 +183,7 @@ static const struct cdrom_drive_types_s { { "TEAC", "CD-532E", "2.0A", "teac_532e", BUS_TYPE_IDE, 0, 32, 36, 0, 0, { 3, 2, 2, -1 } }, { "TOSHIBA", "CD-ROM XM-5302TA", "0305", "toshiba_5302ta", BUS_TYPE_IDE, 0, 4, 96, 0, 0, { 0, -1, -1, -1 } }, { "TOSHIBA", "CD-ROM XM-5702B", "TA70", "toshiba_5702b", BUS_TYPE_IDE, 0, 12, 96, 0, 0, { 3, 2, 1, -1 } }, + { "TOSHIBA", "CD-ROM XM-6102B", "WA70", "toshiba_6102b", BUS_TYPE_IDE, 0, 24, 96, 0, 0, { 4, 2, 2, -1 } }, { "TOSHIBA", "CD-ROM XM-6202B", "1512", "toshiba_6202b", BUS_TYPE_IDE, 0, 32, 96, 0, 0, { 4, 2, 2, -1 } }, { "TOSHIBA", "CD-ROM XM-6402B", "1008", "toshiba_6402b", BUS_TYPE_IDE, 0, 32, 96, 0, 0, { 4, 2, 2, 2 } }, { "TOSHIBA", "CD-ROM XM-6702B", "1007", "toshiba_6720b", BUS_TYPE_IDE, 0, 48, 96, 0, 0, { 4, 2, 2, 2 } }, diff --git a/src/include/86box/device.h b/src/include/86box/device.h index c3892d27c35..b6e78f41c8f 100644 --- a/src/include/86box/device.h +++ b/src/include/86box/device.h @@ -213,7 +213,7 @@ extern uint8_t device_get_bios_type(const device_t *dev, const char *interna extern uint8_t device_get_bios_num_files(const device_t *dev, const char *internal_name); extern uint32_t device_get_bios_local(const device_t *dev, const char *internal_name); extern uint32_t device_get_bios_file_size(const device_t *dev, const char *internal_name); -extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, int file_no); +extern const char *device_get_bios_file(const device_t *dev, const char *internal_name, unsigned int file_no); extern int device_is_valid(const device_t *, int mch); diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index 81ab4dd155b..b10c3485489 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -36,6 +36,7 @@ extern void fdd_do_seek(int drive, int track); extern void fdd_forced_seek(int drive, int track_diff); extern void fdd_seek(int drive, int track_diff); extern int fdd_track0(int drive); +extern int fdd_get_type_max_track(int type); extern int fdd_getrpm(int drive); extern void fdd_set_densel(int densel); extern int fdd_can_read_medium(int drive); diff --git a/src/include/86box/fdd_audio.h b/src/include/86box/fdd_audio.h index 8e8b50f0675..1d1b52d1494 100644 --- a/src/include/86box/fdd_audio.h +++ b/src/include/86box/fdd_audio.h @@ -23,6 +23,12 @@ extern "C" { #ifndef DISABLE_FDD_AUDIO +/* Maximum number of seek samples (for 80-track drives: 1-79 tracks) */ +#define MAX_SEEK_SAMPLES 79 + +/* Maximum number of simultaneous seek sounds per drive */ +#define MAX_CONCURRENT_SEEKS 8 + /* Audio sample configuration structure */ typedef struct { char filename[512]; @@ -37,14 +43,10 @@ typedef struct { audio_sample_config_t spindlemotor_start; audio_sample_config_t spindlemotor_loop; audio_sample_config_t spindlemotor_stop; - audio_sample_config_t single_track_step; - audio_sample_config_t multi_track_seek; - int total_tracks; - int samples_per_track; - double initial_seek_time; - double initial_seek_time_pcjr; - double track_seek_time; - double track_seek_time_pcjr; + audio_sample_config_t seek_up[MAX_SEEK_SAMPLES]; + audio_sample_config_t seek_down[MAX_SEEK_SAMPLES]; + double seek_time_ms[MAX_SEEK_SAMPLES]; /* Seek time in milliseconds for each track count */ + int total_tracks; /* 40 or 80 */ } fdd_audio_profile_config_t; #define FDD_AUDIO_PROFILE_MAX 64 @@ -84,8 +86,9 @@ extern int fdd_audio_get_profile_count(void); extern const fdd_audio_profile_config_t* fdd_audio_get_profile(int id); extern const char* fdd_audio_get_profile_name(int id); extern const char* fdd_audio_get_profile_internal_name(int id); -extern int fdd_audio_get_profile_by_internal_name(const char* internal_name); -extern double fdd_audio_get_seek_time(int drive, int is_initial, int track_count); +extern int fdd_audio_get_profile_by_internal_name(const char *internal_name); +extern double fdd_audio_get_seek_time(int drive, int track_count, int is_seek_down); +extern void load_profile_samples(int profile_id); #else diff --git a/src/include/86box/gameport.h b/src/include/86box/gameport.h index 1b86c05673b..a1bec69fb46 100644 --- a/src/include/86box/gameport.h +++ b/src/include/86box/gameport.h @@ -172,29 +172,73 @@ extern void gameport_update_joystick_type(uint8_t gp); extern void gameport_remap(void *priv, uint16_t address); extern void *gameport_add(const device_t *gameport_type); +// Paddle Controllers +extern const joystick_t joystick_generic_paddle; + +// 2 axis Generic Joysticks +extern const joystick_t joystick_2axis_1button; extern const joystick_t joystick_2axis_2button; -extern const joystick_t joystick_2button_gamepad; -extern const joystick_t joystick_2button_flight_yoke; +extern const joystick_t joystick_2axis_3button; extern const joystick_t joystick_2axis_4button; +extern const joystick_t joystick_2axis_6button; +extern const joystick_t joystick_2axis_8button; + +// 3 axis Generic Joysticks +extern const joystick_t joystick_3axis_2button; +extern const joystick_t joystick_3axis_3button; +extern const joystick_t joystick_3axis_4button; + +// 4 axis Generic Joysticks +extern const joystick_t joystick_4axis_2button; +extern const joystick_t joystick_4axis_3button; +extern const joystick_t joystick_4axis_4button; + +// Generic Gamepads +extern const joystick_t joystick_2button_gamepad; +extern const joystick_t joystick_3button_gamepad; extern const joystick_t joystick_4button_gamepad; +extern const joystick_t joystick_6button_gamepad; + +extern const joystick_t joystick_gravis_gamepad; + +// Generic Steering Wheels +extern const joystick_t joystick_steering_wheel_2_button; +extern const joystick_t joystick_steering_wheel_3_button; +extern const joystick_t joystick_steering_wheel_4_button; + +// Generic Flight Yokes +extern const joystick_t joystick_2button_flight_yoke; extern const joystick_t joystick_4button_flight_yoke; -extern const joystick_t joystick_3axis_2button; +extern const joystick_t joystick_3button_flight_yoke; + extern const joystick_t joystick_2button_yoke_throttle; -extern const joystick_t joystick_3axis_4button; +extern const joystick_t joystick_3button_yoke_throttle; extern const joystick_t joystick_4button_yoke_throttle; -extern const joystick_t joystick_steering_wheel_4_button; -extern const joystick_t joystick_4axis_4button; -extern const joystick_t joystick_2axis_6button; -extern const joystick_t joystick_2axis_8button; + +extern const joystick_t joystick_ch_flightstick; +extern const joystick_t joystick_ch_flightstick_ch_pedals; +extern const joystick_t joystick_ch_flightstick_ch_pedals_pro; extern const joystick_t joystick_ch_flightstick_pro; extern const joystick_t joystick_ch_flightstick_pro_ch_pedals; +extern const joystick_t joystick_ch_flightstick_pro_ch_pedals_pro; + +extern const joystick_t joystick_ch_virtual_pilot; +extern const joystick_t joystick_ch_virtual_pilot_ch_pedals; +extern const joystick_t joystick_ch_virtual_pilot_ch_pedals_pro; + +extern const joystick_t joystick_ch_virtual_pilot_pro; +extern const joystick_t joystick_ch_virtual_pilot_pro_ch_pedals; +extern const joystick_t joystick_ch_virtual_pilot_pro_ch_pedals_pro; extern const joystick_t joystick_sw_pad; extern const joystick_t joystick_tm_fcs; extern const joystick_t joystick_tm_fcs_rcs; +extern const joystick_t joystick_tm_formula_t1t2; +extern const joystick_t joystick_tm_formula_t1t2wa; + #ifdef __cplusplus } #endif diff --git a/src/include/86box/isartc.h b/src/include/86box/isartc.h index ef2d7a92148..65309c6257e 100644 --- a/src/include/86box/isartc.h +++ b/src/include/86box/isartc.h @@ -55,6 +55,10 @@ extern int isartc_get_from_internal_name(const char *str); extern const device_t *isartc_get_device(int t); extern int isartc_has_config(int board); +/* On-board RTC devices */ +extern const device_t vendex_xt_rtc_onboard_device; +extern const device_t rtc58167_device; + #ifdef __cplusplus } #endif diff --git a/src/include/86box/joystick.h b/src/include/86box/joystick.h new file mode 100644 index 00000000000..c8cbf32d1a8 --- /dev/null +++ b/src/include/86box/joystick.h @@ -0,0 +1,27 @@ +/* + * 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 analog joystick handlers. + * + * Authors: Jasmine Iwanek, + * + * Copyright 2025 Jasmine Iwanek. + */ +#ifndef EMU_JOYSTICK_H +#define EMU_JOYSTICK_H + +void *joystick_standard_init(void); +void joystick_standard_close(UNUSED(void *priv)); +uint8_t joystick_standard_read_2button(UNUSED(void *priv)); +uint8_t joystick_standard_read_4button(UNUSED(void *priv)); +void joystick_standard_write(UNUSED(void *priv)); +int joystick_standard_read_axis_3axis_throttle(UNUSED(void *priv), int axis); +int joystick_standard_read_axis_4axis(UNUSED(void *priv), int axis); +void joystick_standard_a0_over(UNUSED(void *priv)); + +#endif /*EMU_JOYSTICK_H*/ diff --git a/src/include/86box/m_pcjr.h b/src/include/86box/m_pcjr.h index 6fb0ee2edfc..f1a31954d2b 100644 --- a/src/include/86box/m_pcjr.h +++ b/src/include/86box/m_pcjr.h @@ -66,6 +66,11 @@ typedef struct pcjr_s { int serial_pos; uint8_t pa; uint8_t pb; + + uint8_t option_modem; + uint8_t option_fdc; + uint8_t option_ir; + pc_timer_t send_delay_timer; } pcjr_t; diff --git a/src/include/86box/m_tandy.h b/src/include/86box/m_tandy.h index 15fab6cc027..8856b830e5d 100644 --- a/src/include/86box/m_tandy.h +++ b/src/include/86box/m_tandy.h @@ -33,6 +33,13 @@ typedef struct t1kvid_t { uint8_t planar_ctrl; uint8_t lp_strobe; + uint8_t baseline_hsyncpos; + uint8_t baseline_vsyncpos; + bool baseline_ready; + int hsync_offset; + int vsync_offset; + int vsync_offset_pending; + int linepos; int displine; int scanline; @@ -51,6 +58,7 @@ typedef struct t1kvid_t { uint64_t dispontime; uint64_t dispofftime; pc_timer_t timer; + pc_timer_t calib_timer; int firstline; int lastline; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ee8b7eafc0b..941286e0fb4 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -635,6 +635,9 @@ extern int machine_at_tandy4000_init(const machine_t *); extern int machine_at_ecs386v_init(const machine_t *); /* OPTi 391 */ +#ifdef EMU_DEVICE_H +extern const device_t dataexpert386wb_device; +#endif extern int machine_at_dataexpert386wb_init(const machine_t *); /* OPTi 495SLC */ @@ -866,6 +869,9 @@ extern const device_t v12p_device; #endif extern int machine_at_v12p_init(const machine_t *); extern int machine_at_excaliburpci_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t p5mp3_device; +#endif extern int machine_at_p5mp3_init(const machine_t *); extern int machine_at_opti560l_init(const machine_t *); extern void machine_at_award_common_init(const machine_t *); @@ -916,7 +922,11 @@ extern int machine_at_tek932_init(const machine_t *); extern int machine_at_acerv30_init(const machine_t *); extern int machine_at_apollo_init(const machine_t *); extern int machine_at_optiplexgxl_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pt2000_device; +#endif extern int machine_at_pt2000_init(const machine_t *); +extern int machine_at_morrison32_init(const machine_t *); extern int machine_at_pc330_65x6_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t zappa_device; @@ -961,6 +971,12 @@ extern const device_t p54tp4xe_device; #endif extern int machine_at_p54tp4xe_init(const machine_t *); extern int machine_at_exp8551_init(const machine_t *); +extern int machine_at_hpholly_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t vectra52_device; +#endif +extern int machine_at_vectra52_init(const machine_t *); +extern int machine_at_vectra500mt_init(const machine_t *); extern int machine_at_vectra54_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t thor_device; @@ -975,9 +991,15 @@ extern int machine_at_atlantis_init(const machine_t *); extern const device_t monaco_device; #endif extern int machine_at_monaco_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms5119_device; +#endif extern int machine_at_ms5119_init(const machine_t *); extern int machine_at_pb640_init(const machine_t *); extern int machine_at_mb500n_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t fmb_device; +#endif extern int machine_at_fmb_init(const machine_t *); /* i430HX */ @@ -1004,7 +1026,11 @@ extern int machine_at_amis727_init(const machine_t *); extern const device_t ap5s_device; #endif extern int machine_at_ap5s_init(const machine_t *); +extern int machine_at_fm562_init(const machine_t *); extern int machine_at_pc140_6260_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms5124_device; +#endif extern int machine_at_ms5124_init(const machine_t *); /* VLSI Wildcat */ @@ -1018,6 +1044,7 @@ extern int machine_at_p55t2p4_init(const machine_t *); extern void machine_at_p65up5_common_init(const machine_t *, const device_t *northbridge); #endif extern int machine_at_p65up5_cp55t2d_init(const machine_t *); +extern int machine_at_rubyusb_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t cu430hx_device; #endif @@ -1042,6 +1069,9 @@ extern int machine_at_8500tvxa_init(const machine_t *); extern int machine_at_presario2240_init(const machine_t *); extern int machine_at_presario4500_init(const machine_t *); extern int machine_at_dellhannibalp_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t p5vxb_device; +#endif extern int machine_at_p5vxb_init(const machine_t *); extern int machine_at_p55va_init(const machine_t *); extern int machine_at_gw2kte_init(const machine_t *); @@ -1082,6 +1112,9 @@ extern int machine_at_via809ds_init(const machine_t *); /* SiS 5571 */ extern int machine_at_cb52xsi_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms5146_device; +#endif extern int machine_at_ms5146_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t r534f_device; @@ -1116,6 +1149,9 @@ extern int machine_at_g5x_init(const machine_t *); /* VIA MVP3 */ extern int machine_at_ax59pro_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t delhi3_device; +#endif extern int machine_at_delhi3_init(const machine_t *); extern int machine_at_mvp3_init(const machine_t *); extern int machine_at_ficva503a_init(const machine_t *); @@ -1139,6 +1175,7 @@ extern int machine_at_acerv60n_init(const machine_t *); extern int machine_at_p65up5_cp6nd_init(const machine_t *); extern int machine_at_8600ttc_init(const machine_t *); extern int machine_at_686nx_init(const machine_t *); +extern uint32_t machine_ap440fx_vs440fx_gpio_handler(uint8_t write, uint32_t val); extern int machine_at_ap440fx_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t vs440fx_device; @@ -1175,6 +1212,9 @@ extern int machine_at_bf6_init(const machine_t *); extern const device_t bx6_device; #endif extern int machine_at_bx6_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ax6bc_device; +#endif extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); @@ -1190,10 +1230,19 @@ extern int machine_at_ms6119_init(const machine_t *); extern const device_t ms6147_device; #endif extern int machine_at_ms6147_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t p6sba_device; +#endif extern int machine_at_p6sba_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t s1846_device; +#endif extern int machine_at_s1846_init(const machine_t *); /* i440ZX */ +#ifdef EMU_DEVICE_H +extern const device_t vei8_device; +#endif extern int machine_at_vei8_init(const machine_t *); extern int machine_at_ms6168_init(const machine_t *); extern int machine_at_borapro_init(const machine_t *); @@ -1206,6 +1255,10 @@ extern int machine_at_ficka6130_init(const machine_t *); /* VIA Apollo Pro 133 */ extern int machine_at_p3v133_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms6199va_device; +#endif +extern int machine_at_ms6199va_init(const machine_t *); /* VIA Apollo Pro 133A */ extern int machine_at_p3v4x_init(const machine_t *); @@ -1221,6 +1274,9 @@ extern int machine_at_fw6400gx_init(const machine_t *); /* m_at_slot1_socket370.c */ /* i440BX */ +#ifdef EMU_DEVICE_H +extern const device_t prosignias31x_device; +#endif extern int machine_at_prosignias31x_bx_init(const machine_t *); extern int machine_at_s1857_init(const machine_t *); @@ -1244,6 +1300,9 @@ extern int machine_at_cubx_init(const machine_t *); /* i440ZX */ extern int machine_at_63a1_init(const machine_t *); +/* SiS 600 */ +extern int machine_at_7sbb_init(const machine_t *); + /* SMSC VictoryBX-66 */ extern int machine_at_atc7020bxii_init(const machine_t *); extern int machine_at_m773_init(const machine_t *); @@ -1257,9 +1316,11 @@ extern int machine_at_p6bap_init(const machine_t *); /* VIA Apollo Pro 133A */ extern int machine_at_6via90ap_init(const machine_t *); extern int machine_at_cuv4xls_init(const machine_t *); - -/* SiS 600 */ -extern int machine_at_7sbb_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms6318_device; +#endif +extern int machine_at_ms6318_init(const machine_t *); +extern int machine_at_cairo5_init(const machine_t *); /* m_at_misc.c */ extern int machine_at_vpc2007_init(const machine_t *); @@ -1401,6 +1462,10 @@ extern int machine_xt_pb8810_init(const machine_t *); extern int machine_xt_sansx16_init(const machine_t *); extern int machine_xt_pcxt_init(const machine_t *); #ifdef EMU_DEVICE_H +extern const device_t to16_device; +#endif +extern int machine_xt_to16_init(const machine_t *); +#ifdef EMU_DEVICE_H extern const device_t vendex_device; #endif extern int machine_xt_vendex_init(const machine_t *); diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index e18aa707ba9..dcf7e4d5306 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -132,6 +132,7 @@ extern int update_icons; extern int kbd_req_capture; extern int hide_status_bar; extern int hide_tool_bar; +extern int fullscreen_ui_visible; /* System-related functions. */ extern FILE *plat_fopen(const char *path, const char *mode); @@ -146,6 +147,7 @@ extern void plat_get_global_data_dir(char *outbuf, size_t len); extern void plat_get_temp_dir(char *outbuf, uint8_t len); extern void plat_get_vmm_dir(char *outbuf, size_t len); extern void plat_init_rom_paths(void); +extern void plat_init_asset_paths(void); extern int plat_dir_check(char *path); extern int plat_file_check(const char *path); extern int plat_dir_create(char *path); diff --git a/src/include/86box/rom.h b/src/include/86box/rom.h index 6865277c6e0..0caee9e1f07 100644 --- a/src/include/86box/rom.h +++ b/src/include/86box/rom.h @@ -42,6 +42,9 @@ typedef struct rom_path_t { } rom_path_t; extern rom_path_t rom_paths; +extern rom_path_t asset_paths; + +extern void asset_add_path(const char *path); extern void rom_add_path(const char *path); @@ -53,8 +56,14 @@ extern void rom_write(uint32_t addr, uint8_t val, void *priv); extern void rom_writew(uint32_t addr, uint16_t val, void *priv); extern void rom_writel(uint32_t addr, uint32_t val, void *priv); +extern void asset_get_full_path(char *dest, const char *fn); + extern void rom_get_full_path(char *dest, const char *fn); +extern FILE *asset_fopen(const char *fn, char *mode); +extern int asset_getfile(const char *fn, char *s, int size); +extern int asset_present(const char *fn); + extern FILE *rom_fopen(const char *fn, char *mode); extern int rom_getfile(const char *fn, char *s, int size); extern int rom_present(const char *fn); diff --git a/src/include/86box/serial.h b/src/include/86box/serial.h index 5231c491abf..816672825f2 100644 --- a/src/include/86box/serial.h +++ b/src/include/86box/serial.h @@ -20,14 +20,15 @@ #ifndef EMU_SERIAL_H #define EMU_SERIAL_H -#define SERIAL_8250 0 -#define SERIAL_8250_PCJR 1 -#define SERIAL_16450 2 -#define SERIAL_16550 3 -#define SERIAL_16650 4 -#define SERIAL_16750 5 -#define SERIAL_16850 6 -#define SERIAL_16950 7 +#define SERIAL_8250 0 +#define SERIAL_8250_PCJR_3F8 1 +#define SERIAL_8250_PCJR_2F8 2 +#define SERIAL_16450 3 +#define SERIAL_16550 4 +#define SERIAL_16650 5 +#define SERIAL_16750 6 +#define SERIAL_16850 7 +#define SERIAL_16950 8 #define SERIAL_FIFO_SIZE 16 @@ -151,7 +152,8 @@ extern int serial_get_ri(serial_t *dev); extern uint8_t serial_get_shadow(serial_t *dev); extern const device_t ns8250_device; -extern const device_t ns8250_pcjr_device; +extern const device_t ns8250_pcjr_3f8_device; +extern const device_t ns8250_pcjr_2f8_device; extern const device_t ns16450_device; extern const device_t ns16550_device; extern const device_t ns16650_device; diff --git a/src/include/86box/snd_ac97.h b/src/include/86box/snd_ac97.h index 3af68d2c8e3..0bad4efa032 100644 --- a/src/include/86box/snd_ac97.h +++ b/src/include/86box/snd_ac97.h @@ -8,9 +8,11 @@ * * Definitions for AC'97 audio emulation. * + * + * * Authors: RichardG, * - * Copyright 2021 RichardG. + * Copyright 2021-2025 RichardG. */ #ifndef SOUND_AC97_H #define SOUND_AC97_H @@ -19,23 +21,26 @@ /* Misc support bits (misc_flags). Most of these are not part of any registers, but control enabling/disabling of registers and bits. */ -#define AC97_MASTER_6B (1 << 0) /* register 02 bits [13,5] (ML5/MR5) */ -#define AC97_AUXOUT (1 << 1) /* register 04 */ -#define AC97_AUXOUT_6B (1 << 2) /* register 04 bits [13,5] (ML5/MR5) */ -#define AC97_MONOOUT (1 << 3) /* register 06 */ -#define AC97_MONOOUT_6B (1 << 4) /* register 06 bit 5 (MM5) */ -#define AC97_PCBEEP (1 << 5) /* register 0A */ -#define AC97_PCBEEP_GEN (1 << 6) /* register 0A bits [12:5] (F[7:0]) */ -#define AC97_PHONE (1 << 9) /* register 0C */ -#define AC97_VIDEO (1 << 10) /* register 14 */ -#define AC97_AUXIN (1 << 11) /* register 16 */ +#define AC97_AUDIO (1 << 0) /* audio codec */ +#define AC97_MODEM (1 << 1) /* modem codec */ +#define AC97_MASTER_6B (1 << 2) /* register 02 bits [13,5] (ML5/MR5) */ +#define AC97_AUXOUT (1 << 3) /* register 04 */ +#define AC97_AUXOUT_6B (1 << 4) /* register 04 bits [13,5] (ML5/MR5) */ +#define AC97_MONOOUT (1 << 5) /* register 06 */ +#define AC97_MONOOUT_6B (1 << 6) /* register 06 bit 5 (MM5) */ +#define AC97_PCBEEP (1 << 9) /* register 0A */ +#define AC97_PCBEEP_GEN (1 << 10) /* register 0A bits [12:5] (F[7:0]) */ +#define AC97_PHONE (1 << 11) /* register 0C */ +#define AC97_VIDEO (1 << 12) /* register 14 */ +#define AC97_AUXIN (1 << 13) /* register 16 */ #define AC97_POP (1 << 15) /* register 20 bit 15 (POP) - definition shared with General Purpose bits */ #define AC97_MS (1 << 8) /* register 20 bit 8 (MS) - definition shared with General Purpose bits */ #define AC97_LPBK (1 << 7) /* register 20 bit 7 (LPBK) - definition shared with General Purpose bits */ -#define AC97_DSA (1 << 12) /* register 28 bits [5:4] (DSA[1:0]) */ -#define AC97_LFE_6B (1 << 13) /* register 36 bit 13 (LFE5) */ -#define AC97_CENTER_6B (1 << 14) /* register 36 bit 5 (CNT5) */ -#define AC97_SURR_6B (1 << 16) /* register 38 bits [13,5] (LSR5/RSR5) */ +#define AC97_DSA (1 << 14) /* register 28 bits [5:4] (DSA[1:0]) */ +#define AC97_LFE_6B (1 << 16) /* register 36 bit 13 (LFE5) */ +#define AC97_CENTER_6B (1 << 17) /* register 36 bit 5 (CNT5) */ +#define AC97_SURR_6B (1 << 18) /* register 38 bits [13,5] (LSR5/RSR5) */ +#define AC97_GAIN_3B (1 << 19) /* registers [1C:1E] (audio) or [46:4A] (modem) bits [8,0] are always 0 (spec violation?) if this is set */ /* Reset bits (reset_flags), register 00. */ #define AC97_MICPCM (1 << 0) @@ -89,6 +94,14 @@ #define AC97_PRK (1 << 13) #define AC97_PRL (1 << 14) +/* Extended Modem ID bits, register 3C. */ +#define AC97_LIN1 (1 << 0) +#define AC97_LIN2 (1 << 1) +#define AC97_HSET (1 << 2) +#define AC97_CID1 (1 << 3) +#define AC97_CID2 (1 << 4) +#define AC97_CIDR (1 << 7) /* special case: not part of register 3C, but rather 56 bit 13 */ + /* Codec IDs. */ #define AC97_CODEC_AD1881 AC97_VENDOR_ID('A', 'D', 'S', 0x40) #define AC97_CODEC_AK4540 AC97_VENDOR_ID('A', 'D', 'S', 0x40) @@ -100,6 +113,7 @@ #define AC97_CODEC_TR28023 AC97_VENDOR_ID('T', 'R', 'A', 0x03) #define AC97_CODEC_W83971D AC97_VENDOR_ID('W', 'E', 'C', 0x01) #define AC97_CODEC_WM9701A AC97_VENDOR_ID('W', 'M', 'L', 0x00) +#define AC97_CODEC_SI3036 AC97_VENDOR_ID('S', 'I', 'L', 0x22) typedef struct ac97_vendor_reg_t { uint8_t page; /* for paged registers [60:6F], 0 otherwise */ @@ -115,6 +129,8 @@ typedef struct ac97_codec_t { uint8_t vendor_reg_page_max; const ac97_vendor_reg_t *vendor_regs; uint16_t *vendor_reg_pages; + uint16_t gpi; + uint16_t gpo; } ac97_codec_t; extern uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg); @@ -122,22 +138,21 @@ extern void ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_ extern void ac97_codec_reset(void *priv); extern void ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r); extern uint32_t ac97_codec_getrate(void *priv, uint8_t reg); +extern void ac97_codec_setgpi(void *priv, uint16_t gpi); +extern void ac97_codec_setgpo(void *priv, uint16_t gpo); extern const device_t *ac97_codec_get(uint32_t id); extern void ac97_via_set_slot(void *priv, int slot, int irq_pin); -extern uint8_t ac97_via_read_status(void *priv, uint8_t modem); -extern void ac97_via_write_control(void *priv, uint8_t modem, uint8_t val); +extern uint8_t ac97_via_read_status(void *priv); +extern void ac97_via_write_control(void *priv, uint8_t val); extern void ac97_via_remap_audio_sgd(void *priv, uint16_t new_io_base, uint8_t enable); extern void ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable); extern void ac97_via_remap_audio_codec(void *priv, uint16_t new_io_base, uint8_t enable); extern void ac97_via_remap_modem_codec(void *priv, uint16_t new_io_base, uint8_t enable); extern ac97_codec_t **ac97_codec; -extern ac97_codec_t **ac97_modem_codec; extern int ac97_codec_count; -extern int ac97_modem_codec_count; extern int ac97_codec_id; -extern int ac97_modem_codec_id; #ifdef EMU_DEVICE_H extern const device_t ad1881_device; @@ -151,6 +166,9 @@ extern const device_t stac9721_device; extern const device_t tr28023_device; extern const device_t w83971d_device; extern const device_t wm9701a_device; +#ifdef USE_SOFTMODEM +extern const device_t si3036_device; +#endif extern const device_t ac97_via_device; #endif diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 99525807c72..1ff5bc1d7f4 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -22,11 +22,12 @@ enum { AD1848_TYPE_DEFAULT = 0, AD1848_TYPE_CS4248 = 1, - AD1848_TYPE_CS4231 = 2, - AD1848_TYPE_CS4232 = 3, - AD1848_TYPE_CS4236 = 4, - AD1848_TYPE_CS4236B = 5, - AD1848_TYPE_CS4235 = 6 + AD1848_TYPE_OPTI930 = 2, + AD1848_TYPE_CS4231 = 3, + AD1848_TYPE_CS4232 = 4, + AD1848_TYPE_CS4236 = 5, + AD1848_TYPE_CS4236B = 6, + AD1848_TYPE_CS4235 = 7 }; enum { @@ -44,6 +45,7 @@ typedef struct ad1848_t { uint8_t regs[32]; uint8_t xregs[32]; uint8_t status; /* 16 original registers + 16 CS4231A extensions + 32 CS4236 extensions */ + uint8_t opti930_mode2; int count; uint8_t trd; diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 2280824e443..6d4767ed0c6 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -177,6 +177,8 @@ extern const device_t sb_awe64_ide_device; extern const device_t sb_awe64_gold_device; /* Crystal CS423x */ +extern const device_t cs4232_device; +extern const device_t cs4232_onboard_device; extern const device_t cs4235_device; extern const device_t cs4235_onboard_device; extern const device_t cs4236_onboard_device; @@ -220,6 +222,9 @@ extern const device_t entertainer_device; /* Mindscape Music Board */ extern const device_t mmb_device; +/* OPTi 82c930 */ +extern const device_t opti_82c930_device; + /* Pro Audio Spectrum Plus, 16, and 16D */ extern const device_t pasplus_device; extern const device_t pas16_device; diff --git a/src/include/86box/unix_osd.h b/src/include/86box/unix_osd.h new file mode 100644 index 00000000000..a71b0ec74c0 --- /dev/null +++ b/src/include/86box/unix_osd.h @@ -0,0 +1,25 @@ +#ifndef _UNIX_OSD_H +#define _UNIX_OSD_H + +#include + +// state management +extern void osd_init(void); +extern void osd_deinit(void); +extern int osd_open(SDL_Event event); +extern int osd_close(SDL_Event event); + +// keyboard event handler +extern int osd_handle(SDL_Event event); + +// draw the osd interface, if it's open +extern void osd_present(void); + +// future ui +extern void osd_ui_sb_update_icon_state(int tag, int state); +extern void osd_ui_sb_update_icon(int tag, int active); +extern void osd_ui_sb_update_icon_write(int tag, int active); +extern void osd_ui_sb_update_icon_wp(int tag, int state); + +#endif /*_UNIX_OSD_H*/ + diff --git a/src/include/86box/unix_osd_font.h b/src/include/86box/unix_osd_font.h new file mode 100644 index 00000000000..412d367c795 --- /dev/null +++ b/src/include/86box/unix_osd_font.h @@ -0,0 +1,4109 @@ +#ifndef UNIX_OSD_FONT_H_INCLUDED +#define UNIX_OSD_FONT_H_INCLUDED + +unsigned char _________font_bmp[] = { + 0x42, 0x4d, 0x36, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa +}; +unsigned int _________font_bmp_len = 49206; + +#endif // UNIX_OSD_FONT_H_INCLUDED diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 61a5697d537..252463af714 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -29,6 +29,7 @@ # define FLAG_512K_MASK 512 # define FLAG_NO_SHIFT3 1024 /* Needed for Bochs VBE. */ # define FLAG_PRECISETIME 2048 /* Needed for Copper demo if on dynarec. */ +# define FLAG_PANNING_ATI 4096 struct monitor_t; typedef struct hwcursor_t { @@ -136,6 +137,7 @@ typedef struct svga_t { int ps_bit_bug; int ati_4color; int vblankend; + int panning_blank; int render_line_offset; int start_retrace_latch; int vga_mode; @@ -449,6 +451,8 @@ extern void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine); extern float ibm_rgb528_getclock(int clock, void *priv); extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float ref_clock); +extern float icd2047_getclock(int clock, void *priv); + extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); extern void icd2061_set_ref_clock(void *priv, float ref_clock); @@ -457,8 +461,13 @@ extern void icd2061_set_ref_clock(void *priv, float ref_clock); # define ics9161_write icd2061_write # define ics9161_getclock icd2061_getclock +extern float ics1494_getclock(int clock, void *priv); + extern float ics2494_getclock(int clock, void *priv); +extern float ics90c64a_vclk_getclock(int clock, void *priv); +extern float ics90c64a_mclk_getclock(int clock, void *priv); + extern void ics2595_write(void *priv, int strobe, int dat); extern double ics2595_getclock(void *priv); extern void ics2595_setclock(void *priv, double clock); @@ -474,6 +483,7 @@ extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern float sdac_getclock(int clock, void *priv); +extern void sdac_set_ref_clock(void *priv, float ref_clock); extern void stg_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga); @@ -506,7 +516,10 @@ extern const device_t att20c505_ramdac_device; extern const device_t bt485a_ramdac_device; extern const device_t gendac_ramdac_device; extern const device_t ibm_rgb528_ramdac_device; +extern const device_t ics1494m_540_device; +extern const device_t ics1494m_540_radius_ht209_device; extern const device_t ics2494an_305_device; +extern const device_t ics2494an_324_device; extern const device_t ati18810_28800_device; extern const device_t ati18811_0_28800_device; extern const device_t ati18811_1_28800_device; @@ -514,7 +527,9 @@ extern const device_t ati18810_mach32_device; extern const device_t ati18811_0_mach32_device; extern const device_t ati18811_1_mach32_device; extern const device_t ics2595_device; +extern const device_t icd2047_20_device; extern const device_t icd2061_device; +extern const device_t ics90c64a_903_device; extern const device_t ics9161_device; extern const device_t sc11483_ramdac_device; extern const device_t sc11487_ramdac_device; @@ -523,7 +538,8 @@ extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; extern const device_t sc1502x_rs2_ramdac_device; extern const device_t sdac_ramdac_device; -extern const device_t stg_ramdac_device; +extern const device_t stg1702_ramdac_device; +extern const device_t stg1703_ramdac_device; extern const device_t tkd8001_ramdac_device; extern const device_t tseng_ics5301_ramdac_device; extern const device_t tseng_ics5341_ramdac_device; diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index 26dcd5a1e54..d87c1f73192 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -29,13 +29,6 @@ #define TEX_CACHE_MAX 64 -#ifdef __cplusplus -# include -using atomic_int = std::atomic; -#else -# include -#endif - enum { VOODOO_1 = 0, VOODOO_SB50, @@ -230,8 +223,8 @@ typedef struct voodoo_params_t { typedef struct texture_t { uint32_t base; uint32_t tLOD; - atomic_int refcount; - atomic_int refcount_r[4]; + ATOMIC_INT refcount; + ATOMIC_INT refcount_r[4]; int is16; uint32_t palette_checksum; uint32_t addr_start[4]; @@ -400,16 +393,16 @@ typedef struct voodoo_t { int type; fifo_entry_t fifo[FIFO_SIZE]; - atomic_int fifo_read_idx; - atomic_int fifo_write_idx; - atomic_int cmd_read; - atomic_int cmd_written; - atomic_int cmd_written_fifo; - atomic_int cmd_written_fifo_2; + ATOMIC_INT fifo_read_idx; + ATOMIC_INT fifo_write_idx; + ATOMIC_INT cmd_read; + ATOMIC_INT cmd_written; + ATOMIC_INT cmd_written_fifo; + ATOMIC_INT cmd_written_fifo_2; voodoo_params_t params_buffer[PARAM_SIZE]; - atomic_int params_read_idx[4]; - atomic_int params_write_idx; + ATOMIC_INT params_read_idx[4]; + ATOMIC_INT params_write_idx; uint32_t cmdfifo_base; uint32_t cmdfifo_end; @@ -418,9 +411,9 @@ typedef struct voodoo_t { int cmdfifo_ret_addr; int cmdfifo_in_sub; int cmdfifo_in_agp; - atomic_int cmdfifo_depth_rd; - atomic_int cmdfifo_depth_wr; - atomic_int cmdfifo_enabled; + ATOMIC_INT cmdfifo_depth_rd; + ATOMIC_INT cmdfifo_depth_wr; + ATOMIC_INT cmdfifo_enabled; uint32_t cmdfifo_amin; uint32_t cmdfifo_amax; int cmdfifo_holecount; @@ -432,14 +425,14 @@ typedef struct voodoo_t { int cmdfifo_ret_addr_2; int cmdfifo_in_sub_2; int cmdfifo_in_agp_2; - atomic_int cmdfifo_depth_rd_2; - atomic_int cmdfifo_depth_wr_2; - atomic_int cmdfifo_enabled_2; + ATOMIC_INT cmdfifo_depth_rd_2; + ATOMIC_INT cmdfifo_depth_wr_2; + ATOMIC_INT cmdfifo_enabled_2; uint32_t cmdfifo_amin_2; uint32_t cmdfifo_amax_2; int cmdfifo_holecount_2; - atomic_uint cmd_status, cmd_status_2; + ATOMIC_UINT cmd_status, cmd_status_2; uint32_t sSetupMode; vert_t verts[4]; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index 840b952493d..acaf7cdc4f4 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -436,20 +436,20 @@ extern const device_t et4000_kasan_isa_device; extern const device_t et4000_mca_device; /* Tseng ET4000-W32x */ -extern const device_t et4000w32_device; +extern const device_t et4000w32_machspeed_vga_gui_2400s_isa_device; +extern const device_t et4000w32_machspeed_vga_gui_2400s_vlb_device; extern const device_t et4000w32_onboard_device; -extern const device_t et4000w32i_isa_device; -extern const device_t et4000w32i_vlb_device; +extern const device_t et4000w32i_axis_microdevice_isa_device; +extern const device_t et4000w32i_hercules_dynamite_pro_vlb_device; extern const device_t et4000w32p_videomagic_revb_vlb_device; -extern const device_t et4000w32p_videomagic_revb_pci_device; -extern const device_t et4000w32p_revc_vlb_device; -extern const device_t et4000w32p_revc_pci_device; -extern const device_t et4000w32p_vlb_device; -extern const device_t et4000w32p_pci_device; -extern const device_t et4000w32p_noncardex_vlb_device; -extern const device_t et4000w32p_noncardex_pci_device; -extern const device_t et4000w32p_cardex_vlb_device; -extern const device_t et4000w32p_cardex_pci_device; +extern const device_t et4000w32p_cardex_revc_vlb_device; +extern const device_t et4000w32p_cardex_revc_pci_device; +extern const device_t et4000w32p_cardex_revd_vlb_device; +extern const device_t et4000w32p_cardex_revd_pci_device; +extern const device_t et4000w32p_diamond_revd_vlb_device; +extern const device_t et4000w32p_diamond_revd_pci_device; +extern const device_t et4000w32p_generic_revd_vlb_device; +extern const device_t et4000w32p_generic_revd_pci_device; /* MDSI Genius VHR */ extern const device_t genius_device; diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index 20baec312fc..499f0653ac1 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -345,14 +345,14 @@ static const device_config_t pc900_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "pc900_v207a", + .default_string = "pc900", .default_int = 0, .file_filter = "", .spinner = { 0 }, .bios = { { .name = "BIOS V2.07A", - .internal_name = "pc900_v207a", + .internal_name = "pc900", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -367,7 +367,26 @@ static const device_config_t pc900_config[] = { .local = 0, .size = 32768, .files = { "roms/machines/pc900/cbm_pc40_v207a_xc.bin", "" } - } + }, + { + .name = "BIOS V2.07B", + .internal_name = "pc900_v207b", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/pc900/mpf_pc900_v207b.bin", "" } + }, + { + .name = "BIOS V3.01B", + .internal_name = "pc900_v301b", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/pc900/cbm_pc40_v301b.bin", "" } + }, + { .files_no = 0 } }, }, { .name = "", .description = "", .type = CONFIG_END } diff --git a/src/machine/m_at_386dx.c b/src/machine/m_at_386dx.c index 5816204ed13..3a90f801df8 100644 --- a/src/machine/m_at_386dx.c +++ b/src/machine/m_at_386dx.c @@ -332,17 +332,71 @@ machine_at_ecs386v_init(const machine_t *model) } /* OPTi 391 */ +static const device_config_t dataexpert386wb_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "dataexpert386wb", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 050591", + .internal_name = "dataexpert386wb_050591", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 65536, + .files = { "roms/machines/dataexpert386wb/386-OPTI-386WB-10.BIN", "" } + }, + { + .name = "MR BIOS V1.26", + .internal_name = "dataexpert386wb", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 65536, + .files = { "roms/machines/dataexpert386wb/st0386-wb-ver2-0-618f078c738cb397184464.bin", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t dataexpert386wb_device = { + .name = "DataExpert 386C", + .internal_name = "dataexpert386wb_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = dataexpert386wb_config +}; + int machine_at_dataexpert386wb_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/dataexpert386wb/st0386-wb-ver2-0-618f078c738cb397184464.bin", - 0x000f0000, 65536, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000f0000, 65536, 0); + machine_at_common_init(model); device_add(&opti391_device); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 0ed20583f79..0c4be22497f 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -168,15 +168,16 @@ static const device_config_t lx6_config[] = { .bios = { { .name = "Award Modular BIOS v4.51PG - Revision LY", - .internal_name = "lx6", .bios_type = BIOS_NORMAL, + .internal_name = "lx6", + .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, - .files = { "roms/machines/lx6/LX6C_LY.BIN", "" } + .files = { "roms/machines/lx6/LX6C_LY.bin", "" } }, { .name = "Award Modular BIOS v4.51PG - Revision PZ (Beta)", - .internal_name = "lx6_beta", + .internal_name = "lx6_pz", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -571,17 +572,81 @@ machine_at_p3bf_init(const machine_t *model) return ret; } +static const device_config_t ax6bc_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ax6bc", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.51PGM - Revision R1.10", + .internal_name = "ax6bc_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ax6bc/ax6bc110.bin", "" } + }, + { + .name = "Award Modular BIOS v4.60PGMA - Revision R2.20 (RM Accelerator 350P2XB/450P3XB)", + .internal_name = "ax6bc_rm", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ax6bc/ax6bc220.bin", "" } + }, + { + .name = "Award Modular BIOS v4.60PGMA - Revision R2.59", + .internal_name = "ax6bc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ax6bc/AX6BC_R2.59.bin", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ax6bc_device = { + .name = "AOpen AX6BC", + .internal_name = "ax6bc_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ax6bc_config +}; + int machine_at_ax6bc_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/ax6bc/AX6BC_R2.59.bin", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -710,7 +775,7 @@ static const device_config_t ms6119_config[] = { .bios = { { .name = "AMIBIOS 6 (071595) - Revision 1.72 (Packard Bell Tacoma with logo)", - .internal_name = "tacoma_logo", + .internal_name = "tacoma_172", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -821,6 +886,15 @@ static const device_config_t ms6147_config[] = { .spinner = { 0 }, .selection = { { 0 } }, .bios = { + { + .name = "Award Modular BIOS v4.51PG - Revision 1.2 (Fujitsu ErgoPro e368)", + .internal_name = "ergoproe368", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6147/W647F412.BIN", "" } + }, { .name = "Award Modular BIOS v4.51PG - Revision 1.8", .internal_name = "ms6147", @@ -848,7 +922,7 @@ static const device_config_t ms6147_config[] = { const device_t ms6147_device = { .name = "MSI MS-6147", - .internal_name = "ms6147_device", + .internal_name = "ms6147", .flags = 0, .local = 0, .init = NULL, @@ -899,17 +973,72 @@ machine_at_ms6147_init(const machine_t *model) return ret; } +static const device_config_t p6sba_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "p6sba", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision R3.1", + .internal_name = "p6sba", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/p6sba/SBAB21.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.60PGA - Revision 05/07/1999 (Leadtek WinFast 8000BX)", + .internal_name = "8000bx", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/p6sba/leadtek-8000bx-80000507.bin", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t p6sba_device = { + .name = "Supermicro P6SBA", + .internal_name = "p6sba_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = p6sba_config +}; + int machine_at_p6sba_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/p6sba/SBAB21.ROM", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -928,26 +1057,78 @@ machine_at_p6sba_init(const machine_t *model) device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&intel_flash_bxt_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); - device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2? */ - hwm_values.fans[1] = 0; /* no CPU2 fan */ - hwm_values.temperatures[0] = 0; /* unused */ - hwm_values.temperatures[2] = 0; /* CPU2? */ - /* no CPU2 voltage */ + device_add(&w83781d_device); /* fans: CPU1, CPU2, Thermal Control; temperatures: unused, CPU1, CPU2 */ + hwm_values.voltages[1] = 3300; /* Seems to be the I/O voltage, reported as "CPUi/o" in the Leadtek BIOS and "CPU2" in the SuperMicro BIOS */ return ret; } +static const device_config_t s1846_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "s1846", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 2.00.04", + .internal_name = "s1846", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/s1846/bx46200f.rom", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 2.00.0x (Tulip Vision Line TP90)", + .internal_name = "tp90", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/s1846/1846TP90.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t s1846_device = { + .name = "Tyan Tsunami ATX", + .internal_name = "s1846_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = s1846_config +}; + int machine_at_s1846_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/s1846/bx46200f.rom", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -975,18 +1156,73 @@ machine_at_s1846_init(const machine_t *model) return ret; } +static const device_config_t vei8_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "vei8", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v6.00PG - Revision QHW.10.01 (HP Sherwood-B)", + .internal_name = "vei8", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/vei8/QHW1001.BIN", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision R804", + .internal_name = "6110zu", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/vei8/r804.bin", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t vei8_device = { + .name = "MiTAC/Trigon 6110Zu", + .internal_name = "vei8_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = vei8_config +}; + /* i440ZX */ int machine_at_vei8_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/vei8/QHW1001.BIN", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -1172,6 +1408,119 @@ machine_at_p3v133_init(const machine_t *model) return ret; } +static const device_config_t ms6199va_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms6199va", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.51PG - Revision 3.5", + .internal_name = "ms6199va", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6199va/w6199vms.350", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 2.0 (Compaq OEM)", + .internal_name = "ms6199va_200", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6199va/W6199VC8.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 2.0 (Compaq OEM) [patched for large drives]", + .internal_name = "ms6199va_200p", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6199va/W6199VC8.PCD", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 3.7 (Packard Bell OEM)", + .internal_name = "ms6199va_370", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6199va/w6199VP2.370", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms6199va_device = { + .name = "MSI MS-6199VA", + .internal_name = "ms6199va_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms6199va_config +}; + +int +machine_at_ms6199va_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUND, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x12, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 4, 3); + pci_register_slot(0x14, PCI_CARD_NORMAL, 2, 1, 4, 3); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&via_apro133a_device); + device_add(&via_vt82c596b_device); + device_add_params(&w83977_device, (void *) (W83977EF | W83977_AMI | W83977_NO_NVR)); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 512); + device_add(&w83782d_device); /* fans: Chassis, Power, CPU; temperatures: System, CPU, unused */ + hwm_values.temperatures[2] = 0; /* unused */ + + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(machine_get_snd_device(machine)); + device_add(&w83971d_device); + } + + return ret; +} + /* VIA Apollo Pro 133A */ int machine_at_p3v4x_init(const machine_t *model) diff --git a/src/machine/m_at_slot1_socket370.c b/src/machine/m_at_slot1_socket370.c index cf689fd08e6..a9006c5e733 100644 --- a/src/machine/m_at_slot1_socket370.c +++ b/src/machine/m_at_slot1_socket370.c @@ -39,17 +39,81 @@ #include <86box/snd_ac97.h> /* i440BX */ +static const device_config_t prosignias31x_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "prosignias31x_bx", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.51PG - Revision 5.3", + .internal_name = "p6bxt", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/prosignias31x_bx/bxt53s.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 5.5 (Compaq ProSignia/Deskpro 440BX)", + .internal_name = "prosignias31x_bx", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/prosignias31x_bx/p6bxt-ap-092600.bin", "" } + }, + { + .name = "Phoenix - AwardBIOS v6.00PG - Unofficial Version 6.0 (by rushieda)", + .internal_name = "p6bxt_600pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/prosignias31x_bx/p6bxtap-600-67b8bfdce5de3470118202.bin", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t prosignias31x_device = { + .name = "ECS P6BXT-A+", + .internal_name = "prosignias31x_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = prosignias31x_config +}; + int machine_at_prosignias31x_bx_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/prosignias31x_bx/p6bxt-ap-092600.bin", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/m_at_socket2.c b/src/machine/m_at_socket2.c index b7cf93d927b..8ea151f5300 100644 --- a/src/machine/m_at_socket2.c +++ b/src/machine/m_at_socket2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #define HAVE_STDARG_H @@ -333,11 +334,13 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 int ret; ret = bios_load_linear("roms/machines/valuepoint433/$IMAGEP.FLH", - 0x000e0000, 131072, 0); + 0x000c0000, 262144, 0); if (bios_only || !ret) return ret; + memcpy(&rom[0x00020000], rom, 131072); + machine_at_common_ide_init(model); device_add(&sis_85c461_device); if (gfxcard[0] == VID_INTERNAL) @@ -350,6 +353,13 @@ machine_at_valuepoint433_init(const machine_t *model) // hangs without the PS/2 if (fdc_current[0] == FDC_INTERNAL) device_add(&fdc_at_device); + if (gfxcard[0] != VID_INTERNAL) { + for (uint16_t i = 0; i < 32768; i++) + rom[i] = mem_readb_phys(0x000c0000 + i); + } + mem_mapping_set_addr(&bios_mapping, 0x0c0000, 0x40000); + mem_mapping_set_exec(&bios_mapping, rom); + return ret; } diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index f902a7fa99a..ee75752db90 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -215,6 +215,35 @@ machine_at_63a1_init(const machine_t *model) return ret; } +/* SiS 600 */ +int +machine_at_7sbb_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/7sbb/sbb12aa2.bin", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&sis_5600_device); + device_add(&it8661f_device); + device_add(&sst_flash_29ee020_device); /* assumed */ + + return ret; +} + /* SMSC VictoryBX-66 */ int machine_at_atc7020bxii_init(const machine_t *model) @@ -434,13 +463,168 @@ machine_at_cuv4xls_init(const machine_t *model) return ret; } -/* SiS 600 */ +static const device_config_t ms6318_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms6318", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v6.00PG - Revision 1.1", + .internal_name = "ms6318_110", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/w6318vms.110", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 1.2", + .internal_name = "ms6318", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/w6318vms.120", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 7.1B5E (Elonex OEM)", + .internal_name = "ms6318_715", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/w6318ve1.715", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 1.0B9 (Fujitsu-Siemens OEM)", + .internal_name = "ms6318_109", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/ms-6318-ver5.bin", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 1.8 (HP OEM)", + .internal_name = "ms6318_180", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/med2000v2.bin", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 1.9 (HP OEM)", + .internal_name = "ms6318_190", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/med2000.bin", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 2.02 (HP OEM)", + .internal_name = "ms6318_202", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/ms6318hp.bin", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 1.3 (Medion OEM)", + .internal_name = "ms6318_130", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/ms6318.bin", "" } + }, + { + .name = "Award Modular BIOS v6.00PG - Revision 7.51 (Medion OEM)", + .internal_name = "ms6318_751", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/ms6318/bios.rom", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms6318_device = { + .name = "MSI MS-6318", + .internal_name = "ms6318_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms6318_config +}; + int -machine_at_7sbb_init(const machine_t *model) +machine_at_ms6318_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0C, PCI_CARD_SOUND, 3, 4, 1, 2); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); /* fans: CPU1, CPU2; temperatures: CPU, System, unused */ + device_add(&sst_flash_39sf020_device); /* assumed */ + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); + hwm_values.temperatures[0] += 2; /* CPU offset */ + hwm_values.temperatures[1] += 2; /* System offset */ + hwm_values.temperatures[2] = 0; /* unused */ + + if (sound_card_current[0] == SOUND_INTERNAL) { + device_add(machine_get_snd_device(machine)); + device_add(&stac9708_device); + } + + return ret; +} + +int +machine_at_cairo5_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/7sbb/sbb12aa2.bin", + ret = bios_load_linear("roms/machines/cairo5/08BV.BIN", 0x000c0000, 262144, 0); if (bios_only || !ret) @@ -448,17 +632,20 @@ machine_at_7sbb_init(const machine_t *model) machine_at_common_init_ex(model, 2); - pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); - pci_register_slot(0x0F, PCI_CARD_NORMAL, 1, 2, 3, 4); - pci_register_slot(0x10, PCI_CARD_NORMAL, 2, 3, 4, 1); - pci_register_slot(0x11, PCI_CARD_NORMAL, 3, 4, 1, 2); - pci_register_slot(0x02, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 1, 2, 3, 0); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 2, 3, 0, 1); + pci_register_slot(0x10, PCI_CARD_NORMAL, 3, 0, 1, 2); + pci_register_slot(0x11, PCI_CARD_NORMAL, 0, 1, 2, 3); + pci_register_slot(0x12, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x01, PCI_CARD_AGPBRIDGE, 1, 2, 3, 4); - device_add(&sis_5600_device); - device_add(&it8661f_device); - device_add(&sst_flash_29ee020_device); /* assumed */ + device_add(&via_apro133a_device); + device_add(&via_vt82c686b_device); + device_add(&winbond_flash_w29c020_device); + spd_register(SPD_TYPE_SDRAM, 0x7, 1024); return ret; -} +} \ No newline at end of file diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index d518ac5dde0..991ff9cab6b 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -158,17 +158,72 @@ machine_at_excaliburpci_init(const machine_t *model) return ret; } +static const device_config_t p5mp3_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "p5mp3", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.50 - Revision 0205", + .internal_name = "p5mp3", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/p5mp3/0205.bin", "" } + }, + { + .name = "Award Modular BIOS v4.51G - Revision 0402 (Beta)", + .internal_name = "p5mp3_0402", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/p5mp3/0402.001", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t p5mp3_device = { + .name = "ASUS P/I-P5MP3", + .internal_name = "p5mp3_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = p5mp3_config +}; + int machine_at_p5mp3_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/p5mp3/0205.bin", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_2 | PCI_NO_IRQ_STEERING); diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index 409beee248d..adfdfbacd4a 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -427,6 +427,79 @@ machine_at_optiplexgxl_init(const machine_t *model) return ret; } + +static void +machine_at_morrison32_gpio_init(void) +{ + uint32_t gpio = 0xffffe2ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = No onboard audio, 1 = Onboard audio present. */ + /* Bit 1: 0 = Soft Off capable power supply, 1 = Standard power supply. */ + /* Bit 0: 2x multiplier, 1 = 1.5x multiplier (Switch 6). */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff00ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff08ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff10ff; + + if (cpu_dmulti <= 1.5) + gpio |= 0xffff01ff; + else + gpio |= 0xffff00ff; + + if (sound_card_current[0] == SOUND_INTERNAL) + gpio |= 0xffff04ff; + + machine_set_gpio_default(gpio); +} + +int +machine_at_morrison32_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/morrison32/1011BT0L.BIO", + "roms/machines/morrison32/1011BT0L.BI1", + 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + machine_at_morrison32_gpio_init(); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + /* Some stuff taken from Monaco */ static void machine_at_morrison64_gpio_init(void) @@ -552,17 +625,72 @@ machine_at_zappa_gpio_init(void) machine_set_gpio_default(gpio); } +static const device_config_t pt2000_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pt2000", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.50GP - Revision T1.01", + .internal_name = "pt2000", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ficpt2000/PT2000_v1.01.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 3.072C806", + .internal_name = "pt2000_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ficpt2000/3072c806.bin", "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pt2000_device = { + .name = "FIC PT-2000", + .internal_name = "pt2000_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pt2000_config +}; + int machine_at_pt2000_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/ficpt2000/PT2000_v1.01.BIN", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); @@ -743,6 +871,9 @@ machine_at_powermatev_init(const machine_t *model) pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); device_add(&i430fx_device); device_add(&piix_device); diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 3bd4f8a95b0..4715e72eb64 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -143,6 +143,77 @@ machine_at_p65up5_cp55t2d_init(const machine_t *model) return ret; } +static void +machine_at_rubyusb_gpio_init(void) +{ + uint32_t gpio = 0xffffe3ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = On-board audio absent, 1 = On-board audio present. */ + /* Bit 1: 0 = Soft-off capable power supply present, 1 = Soft-off capable power supply absent. */ + /* Bit 0: 0 = Reserved. */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff10ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff18ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff00ff; + + if (sound_card_current[0] == SOUND_INTERNAL) + gpio |= 0xffff04ff; + + machine_set_gpio_default(gpio); +} + +int +machine_at_rubyusb_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear_combined2("roms/machines/rubyusb/1005DL0L.BIO", + "roms/machines/rubyusb/1005DL0L.BI1", + "roms/machines/rubyusb/1005DL0L.BI2", + "roms/machines/rubyusb/1005DL0L.BI3", + "roms/machines/rubyusb/1005DL0L.RCV", + /*NULL,*/ + 0x3a000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + machine_at_rubyusb_gpio_init(); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&i430hx_device); + device_add(&piix3_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + static const device_config_t cu430hx_config[] = { // clang-format off { @@ -813,17 +884,72 @@ machine_at_dellhannibalp_init(const machine_t *model) return ret; } +static const device_config_t p5vxb_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "p5vxb", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Award Modular BIOS v4.50PG - Revision 1.0", + .internal_name = "p5vxb", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/p5vxb/P5VXB10.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 1.5c", + .internal_name = "p5vxb_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/p5vxb/P5VXB15C.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t p5vxb_device = { + .name = "ECS P5VX-B", + .internal_name = "p5vxb_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = p5vxb_config +}; + int machine_at_p5vxb_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/p5vxb/P5VXB10.BIN", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); @@ -1422,24 +1548,39 @@ machine_at_ma23c_init(const machine_t *model) static const device_config_t an430tx_config[] = { // clang-format off { - .name = "bios", - .description = "BIOS Version", - .type = CONFIG_BIOS, - .default_string = "pb79x", - .default_int = 0, - .file_filter = "", - .spinner = { 0 }, - .bios = { - { .name = "PhoenixBIOS 4.0 Release 6.0 - Revision P02-0011 (Sony Vaio PCV-130/150)", .internal_name = "vaio150", .bios_type = BIOS_NORMAL, - .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/an430tx/P02-0011.BIO", "roms/machines/an430tx/P02-0011.BI1", - "roms/machines/an430tx/P02-0011.BI2", "roms/machines/an430tx/P02-0011.BI3", - "roms/machines/an430tx/P02-0011.RCV", "" } }, - { .name = "PhoenixBIOS 4.0 Release 6.0 - Revision P09-0006 (Packard Bell PB79x)", .internal_name = "pb79x", .bios_type = BIOS_NORMAL, - .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/an430tx/ANP0911A.BIO", "roms/machines/an430tx/ANP0911A.BI1", - "roms/machines/an430tx/ANP0911A.BI2", "roms/machines/an430tx/ANP0911A.BI3", - "roms/machines/an430tx/ANP0911A.RCV", "" } }, + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "an430tx", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "PhoenixBIOS 4.0 Release 6.0 - Revision P02-0011 (Sony Vaio PCV-130/150)", + .internal_name = "pcv150", + .bios_type = BIOS_NORMAL, + .files_no = 5, + .local = 0, + .size = 262144, + .files = { "roms/machines/an430tx/P02-0011.BIO", "roms/machines/an430tx/P02-0011.BI1", + "roms/machines/an430tx/P02-0011.BI2", "roms/machines/an430tx/P02-0011.BI3", + "roms/machines/an430tx/P02-0011.RCV", "" } + }, + { + .name = "PhoenixBIOS 4.0 Release 6.0 - Revision P09-0006 (Packard Bell PB79x)", + .internal_name = "an430tx", + .bios_type = BIOS_NORMAL, + .files_no = 5, + .local = 0, + .size = 262144, + .files = { "roms/machines/an430tx/ANP0911A.BIO", "roms/machines/an430tx/ANP0911A.BI1", + "roms/machines/an430tx/ANP0911A.BI2", "roms/machines/an430tx/ANP0911A.BI3", + "roms/machines/an430tx/ANP0911A.RCV", "" } + }, { .files_no = 0 } - }, + } }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on @@ -1755,17 +1896,72 @@ machine_at_cb52xsi_init(const machine_t *model) return ret; } +static const device_config_t ms5146_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms5146", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 1.1", + .internal_name = "ms5146", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5146/A546MS11.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 2.1", + .internal_name = "ms5146_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5146/W546MS21.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms5146_device = { + .name = "MSI MS-5146", + .internal_name = "ms5146_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms5146_config +}; + int machine_at_ms5146_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/ms5146/A546MS11.ROM", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); @@ -1789,7 +1985,7 @@ static const device_config_t r534f_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "r534f", + .default_string = "r534f_1998", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, @@ -1797,7 +1993,7 @@ static const device_config_t r534f_config[] = { .bios = { { .name = "Award Modular BIOS v4.51PG - Revision 06/12/1998", - .internal_name = "r534f", + .internal_name = "r534f_1998", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -1806,7 +2002,7 @@ static const device_config_t r534f_config[] = { }, { .name = "Award Modular BIOS v4.51PG - Revision 03/13/2000 (by Unicore Software)", - .internal_name = "r534f_unicore", + .internal_name = "r534f", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index add28bd1bf1..c3672c8e618 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -157,6 +157,221 @@ machine_at_exp8551_init(const machine_t *model) return ret; } +static void +machine_at_hpholly_gpio_init(void) +{ + uint32_t gpio = 0xffffe2ff; + + /* Register 0x0079: */ + /* Bit 7: 0 = Clear password, 1 = Keep password. */ + /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ + /* Bit 5: 0 = CMOS Setup disabled, 1 = CMOS Setup enabled. */ + /* Bit 4: External CPU clock (Switch 8). */ + /* Bit 3: External CPU clock (Switch 7). */ + /* 50 MHz: Switch 7 = Off, Switch 8 = Off. */ + /* 60 MHz: Switch 7 = On, Switch 8 = Off. */ + /* 66 MHz: Switch 7 = Off, Switch 8 = On. */ + /* Bit 2: 0 = 2.5x multiplier, 1 = 1.5x/2x multiplier. */ + /* Bit 1: 0 = Soft Off capable power supply, 1 = Standard power supply. */ + /* Bit 0: 2x multiplier, 1 = 1.5x multiplier (Switch 6). */ + /* NOTE: A bit is read as 1 if switch is off, and as 0 if switch is on. */ + if (cpu_busspeed <= 50000000) + gpio |= 0xffff00ff; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0xffff08ff; + else if (cpu_busspeed > 60000000) + gpio |= 0xffff10ff; + + if (cpu_dmulti <= 1.5) + gpio |= 0xffff0500; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + gpio |= 0xffff0400; + else + gpio |= 0xffff0000; + + machine_set_gpio_default(gpio); +} + +int +machine_at_hpholly_init(const machine_t *model) /* HP Pavilion Holly, 7070/7090/5100/7100 */ +{ + int ret; + + ret = bios_load_linear_combined("roms/machines/hpholly/1005CA2L.BIO", + "roms/machines/hpholly/1005CA2L.BI1", + 0x20000, 128); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + machine_at_hpholly_gpio_init(); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x08, PCI_CARD_VIDEO, 4, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add_params(&pc87306_device, (void *) PCX730X_AMI); + device_add(&intel_flash_bxt_ami_device); + + return ret; +} + +static void +machine_at_vectra52_gpio_init(void) +{ + uint32_t gpio = 0x40; + + if (cpu_busspeed <= 40000000) + gpio |= 0x30; + else if ((cpu_busspeed > 40000000) && (cpu_busspeed <= 50000000)) + gpio |= 0x00; + else if ((cpu_busspeed > 50000000) && (cpu_busspeed <= 60000000)) + gpio |= 0x20; + else if (cpu_busspeed > 60000000) + gpio |= 0x10; + + if (cpu_dmulti <= 1.5) + gpio |= 0x82; + else if ((cpu_dmulti > 1.5) && (cpu_dmulti <= 2.0)) + gpio |= 0x02; + else if ((cpu_dmulti > 2.0) && (cpu_dmulti <= 2.5)) + gpio |= 0x00; + else if (cpu_dmulti > 2.5) + gpio |= 0x80; + + machine_set_gpio_default(gpio); +} + +static const device_config_t vectra52_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "vectra52_0705", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "GU.07.02 (01/25/96)", + .internal_name = "vectra52_0702", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/vectra52/d3653.bin", "" } + }, + { + .name = "GU.07.05 (08/06/96)", + .internal_name = "vectra52_0705", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/vectra52/GU0705US.FUL", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t vectra52_device = { + .name = "HP Vectra VE 5/xxx Series 2", + .internal_name = "vectra52", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = vectra52_config +}; + +int +machine_at_vectra52_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + machine_at_common_init_ex(model, 2); + machine_at_vectra52_gpio_init(); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + device_add(&i430fx_device); + device_add(&piix_device); + device_add_params(&pc87306_device, (void *) PCX730X_PHOENIX_42); + device_add(&intel_flash_bxt_device); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + return ret; +} +int +machine_at_vectra500mt_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/vectra500mt/GJ0718.FUL", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0F, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x0D, PCI_CARD_VIDEO, 0, 0, 0, 0); + pci_register_slot(0x06, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x08, PCI_CARD_NORMAL, 3, 4, 1, 2); + + if (gfxcard[0] == VID_INTERNAL) + device_add(machine_get_vid_device(machine)); + + device_add(&i430fx_device); + device_add(&piix_device); + device_add_params(&fdc37c93x_device, (void *) (FDC37XXX2 | FDC37C93X_NORMAL)); + device_add(&sst_flash_29ee010_device); + + return ret; +} + int machine_at_vectra54_init(const machine_t *model) { @@ -291,6 +506,9 @@ machine_at_thor_gpio_init(void) else if (cpu_busspeed > 60000000) gpio |= 0xffff1000; + if (sound_card_current[0] == SOUND_INTERNAL) + gpio |= 0xffff0400; + machine_set_gpio_default(gpio); } @@ -332,6 +550,9 @@ machine_at_thor_init(const machine_t *model) if (has_video && (gfxcard[0] == VID_INTERNAL)) device_add(machine_get_vid_device(machine)); + if (has_video && (sound_card_current[0] == SOUND_INTERNAL)) + machine_snd = device_add(machine_get_snd_device(machine)); + device_add(&i430fx_device); device_add(&piix_device); device_add_params(&pc87306_device, (void *) PCX730X_AMI); @@ -432,27 +653,6 @@ machine_at_monaco_gpio_init(void) { uint32_t gpio = 0xffffe0cf; - /* Return to this after CS4232 PnP is working. */ - /* Register 0x0078 (Undocumented): */ - /* Bit 5,4: Vibra 16S base address: 0 = 220h, 1 = 260h, 2 = 240h, 3 = 280h. */ - /*device_context(machine_get_snd_device(machine)); - addr = device_get_config_hex16("base"); - switch (addr) { - case 0x0220: - gpio |= 0xffff00cf; - break; - case 0x0240: - gpio |= 0xffff00ef; - break; - case 0x0260: - gpio |= 0xffff00df; - break; - case 0x0280: - gpio |= 0xffff00ff; - break; - } - device_context_restore();*/ - /* Register 0x0079: */ /* Bit 7: 0 = Clear password, 1 = Keep password. */ /* Bit 6: 0 = NVRAM cleared by jumper, 1 = NVRAM normal. */ @@ -538,6 +738,9 @@ machine_at_endeavor_init(const machine_t *model) return ret; } +/* The Monaco and Atlantis share the same GPIO config */ +#define machine_at_atlantis_gpio_init machine_at_monaco_gpio_init + int machine_at_atlantis_init(const machine_t *model) { @@ -551,6 +754,7 @@ machine_at_atlantis_init(const machine_t *model) return ret; machine_at_common_init_ex(model, 2); + machine_at_atlantis_gpio_init(); pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); @@ -667,17 +871,72 @@ machine_at_monaco_init(const machine_t *model) return ret; } +static const device_config_t ms5119_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms5119", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision A37EB", + .internal_name = "ms5119", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5119/A37EB.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Release 2.3 (by Rainbow)", + .internal_name = "ms5119_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5119/MS-5120.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms5119_device = { + .name = "MSI MS-5119", + .internal_name = "ms5119_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms5119_config +}; + int machine_at_ms5119_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/ms5119/A37EB.ROM", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); @@ -793,17 +1052,72 @@ machine_at_mb500n_init(const machine_t *model) return ret; } +static const device_config_t fmb_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "fmb", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 1.83", + .internal_name = "fmb", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/fmb/P5IV183.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - 2001 Release (by Rainbow)", + .internal_name = "fmb_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/fmb/P5I437FM.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t fmb_device = { + .name = "QDI FMB", + .internal_name = "fmb_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = fmb_config +}; + int machine_at_fmb_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/fmb/P5IV183.ROM", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init(model); pci_init(PCI_CONFIG_TYPE_1); @@ -1282,6 +1596,37 @@ machine_at_ap5s_init(const machine_t *model) return ret; } +int +machine_at_fm562_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/fm562/PR11_US.ROM", + 0x000e0000, 131072, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init_ex(model, 2); + + pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); + pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 1, 2, 3, 4); + pci_register_slot(0x01, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 0); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 3, 2, 4); + pci_register_slot(0x13, PCI_CARD_NORMAL, 2, 1, 3, 4); + pci_register_slot(0x0B, PCI_CARD_VIDEO, 0, 0, 0, 0); /* Onboard video */ + + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + + device_add(&sis_5511_device); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + device_add_params(&fdc37c669_device, (void *) 0); + device_add(&intel_flash_bxt_device); + + return ret; +} + int machine_at_pc140_6260_init(const machine_t *model) { @@ -1313,17 +1658,72 @@ machine_at_pc140_6260_init(const machine_t *model) return ret; } +static const device_config_t ms5124_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms5124", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMI WinBIOS (101094) - Revision AG77", + .internal_name = "ms5124", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5124/AG77.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision WG72P", + .internal_name = "ms5124_451pg", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5124/WG72P.BIN", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms5124_device = { + .name = "MSI MS-5124", + .internal_name = "ms5124_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms5124_config +}; + int machine_at_ms5124_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/ms5124/AG77.ROM", - 0x000e0000, 131072, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index ea53e5fd459..11fbcd69419 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -303,6 +303,15 @@ machine_at_686nx_init(const machine_t *model) return ret; } +uint32_t +machine_ap440fx_vs440fx_gpio_handler(uint8_t write, uint32_t val) +{ + if (!write) + return 0xff7f; + + return val; /* Writes are ignored. */ +} + int machine_at_ap440fx_init(const machine_t *model) { diff --git a/src/machine/m_at_sockets7.c b/src/machine/m_at_sockets7.c index 832cd3fdd5e..550da59b97a 100644 --- a/src/machine/m_at_sockets7.c +++ b/src/machine/m_at_sockets7.c @@ -200,7 +200,7 @@ static const device_config_t g5x_config[] = { }, { .name = "Phoenix - AwardBIOS v6.00PG - Release 4.1 (by eSupport)", - .internal_name = "5ax_esupport", + .internal_name = "5ax_600pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -298,17 +298,72 @@ machine_at_ax59pro_init(const machine_t *model) return ret; } +static const device_config_t delhi3_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "delhi3", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 1.01", + .internal_name = "delhi3_nonoem", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/delhi3/DELHI3_nonoem.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.20 (eMachines eTower 3__k)", + .internal_name = "delhi3", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/delhi3/DELHI3.ROM", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t delhi3_device = { + .name = "TriGem Delhi-III", + .internal_name = "delhi3_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = delhi3_config +}; + int machine_at_delhi3_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/delhi3/DELHI3.ROM", - 0x000c0000, 262144, 0); + int ret = 0; + const char *fn; - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index 519933b238d..78f7ba7107d 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -41,6 +41,7 @@ #include <86box/rom.h> #include <86box/fdd.h> #include <86box/fdc.h> +#include <86box/fdc_ext.h> #include <86box/sound.h> #include <86box/snd_speaker.h> #include <86box/snd_sn76489.h> @@ -652,7 +653,10 @@ kbd_read(uint16_t port, void *priv) case 0x62: ret = (pcjr->latched ? 1 : 0); - ret |= 0x02; /* Modem card not installed */ + if (!pcjr->option_modem) + ret |= 0x02; /* Modem card not installed */ + if (!pcjr->option_fdc) + ret |= 0x04; /* Diskette card not installed */ if (mem_size < 128) ret |= 0x08; /* 64k expansion card not installed */ if ((pcjr->pb & 0x08) || (cassette == NULL)) @@ -664,6 +668,8 @@ kbd_read(uint16_t port, void *priv) ret |= (pcjr->data ? 0x40 : 0); if (pcjr->data) ret |= 0x40; + if (pcjr->option_ir) + ret |= 0x80; /* Keyboard cable not connected */ break; case 0xa0: @@ -813,6 +819,30 @@ static const device_config_t pcjr_config[] = { .selection = { { 0 } }, .bios = { { 0 } } }, +#if 0 + { + .name = "modem_slot", + .description = "Enable Serial Port in Modem Slot", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "ir_receiver", + .description = "Enable IR Receiver", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, +#endif { .name = "", .description = "", .type = CONFIG_END } // clang-format on }; @@ -846,6 +876,18 @@ machine_pcjr_init(UNUSED(const machine_t *model)) pcjr = calloc(1, sizeof(pcjr_t)); +#if 0 + pcjr->option_modem = device_get_config_int("modem_slot"); +#else + pcjr->option_modem = 0; +#endif + pcjr->option_fdc = 0; +#if 0 + pcjr->option_ir = device_get_config_int("ir_receiver"); +#else + pcjr->option_ir = 0; +#endif + is_pcjr = 1; pic_init_pcjr(); @@ -865,9 +907,13 @@ machine_pcjr_init(UNUSED(const machine_t *model)) keyboard_scan = 1; key_queue_start = key_queue_end = 0; io_sethandler(0x0060, 4, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, pcjr); + kbd_read, NULL, NULL, + kbd_write, NULL, NULL, + pcjr); io_sethandler(0x00a0, 8, - kbd_read, NULL, NULL, kbd_write, NULL, NULL, pcjr); + kbd_read, NULL, NULL, + kbd_write, NULL, NULL, + pcjr); timer_add(&pcjr->send_delay_timer, kbd_poll, pcjr, 1); keyboard_set_table(scancode_pcjr); keyboard_send = kbd_adddata_ex; @@ -877,9 +923,18 @@ machine_pcjr_init(UNUSED(const machine_t *model)) nmi_mask = 0x80; - device_add(&fdc_pcjr_device); + if (fdc_current[0] == FDC_INTERNAL) { + device_add(&fdc_pcjr_device); + pcjr->option_fdc = 1; + } + + if (!pcjr->option_modem) + device_add(&ns8250_pcjr_2f8_device); + else { + device_add(&ns8250_pcjr_3f8_device); + device_add(&ns8250_pcjr_2f8_device); + } - device_add(&ns8250_pcjr_device); /* So that serial_standalone_init() won't do anything. */ serial_set_next_inst(SERIAL_MAX - 1); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 56ba5f843b0..e5906030c08 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -37,6 +37,7 @@ #include <86box/serial.h> #include <86box/sio.h> #include <86box/ibm_5161.h> +#include <86box/isartc.h> #include <86box/keyboard.h> #include <86box/rom.h> #include <86box/machine.h> @@ -45,9 +46,6 @@ #include <86box/port_6x.h> #include <86box/video.h> -extern const device_t vendex_xt_rtc_onboard_device; -extern const device_t rtc58167_device; - /* 8088 */ static void machine_xt_common_init(const machine_t *model, int fixed_floppy) @@ -902,7 +900,7 @@ static const device_config_t dtk_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "dtk_242", + .default_string = "dtk", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, @@ -919,7 +917,7 @@ static const device_config_t dtk_config[] = { }, { .name = "2.42", - .internal_name = "dtk_242", + .internal_name = "dtk", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -1251,7 +1249,7 @@ static const device_config_t pc500_config[] = { .spinner = { 0 }, .selection = { { .description = "Disabled", .value = -1 }, - { .description = "Enabled", .value = 2 }, + { .description = "IRQ 2", .value = 2 }, { .description = "" } }, .bios = { { 0 } } @@ -1259,7 +1257,7 @@ static const device_config_t pc500_config[] = { { .name = "rtc_port", .description = "RTC Port Address", - .type = CONFIG_HEX16, + .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 0, .file_filter = NULL, @@ -1310,7 +1308,7 @@ machine_xt_pc500_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&kbc_xtclone_device); + device_add(&kbc_pc82_device); machine_xt_common_init(model, 0); @@ -1326,7 +1324,7 @@ static const device_config_t pc500plus_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "pc500plus_404", + .default_string = "pc500plus", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, @@ -1342,7 +1340,7 @@ static const device_config_t pc500plus_config[] = { }, { .name = "4.04", - .internal_name = "pc500plus_404", + .internal_name = "pc500plus", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -1371,7 +1369,7 @@ static const device_config_t pc500plus_config[] = { .spinner = { 0 }, .selection = { { .description = "Disabled", .value = -1 }, - { .description = "Enabled", .value = 2 }, + { .description = "IRQ 2", .value = 2 }, { .description = "" } }, .bios = { { 0 } } @@ -1379,7 +1377,7 @@ static const device_config_t pc500plus_config[] = { { .name = "rtc_port", .description = "Onboard RTC", - .type = CONFIG_HEX16, + .type = CONFIG_SELECTION, .default_string = NULL, .default_int = 0, .file_filter = NULL, @@ -1429,9 +1427,7 @@ machine_xt_pc500plus_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&kbc_xtclone_device); - - machine_xt_common_init(model, 0); + machine_xt_clone_init(model, 0); if (rtc_port != 0) device_add(&rtc58167_device); @@ -1445,14 +1441,14 @@ static const device_config_t pc700_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "pc700_330", + .default_string = "pc700", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .bios = { { .name = "3.30", - .internal_name = "pc700_330", + .internal_name = "pc700", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, @@ -1507,7 +1503,7 @@ machine_xt_pc700_init(const machine_t *model) if (bios_only || !ret) return ret; - device_add(&kbc_pc_device); + device_add(&kbc_pc82_device); machine_xt_common_init(model, 0); @@ -1706,6 +1702,106 @@ machine_xt_pcxt_init(const machine_t *model) return ret; } +static const device_config_t to16_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "to16", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "1.03", + .internal_name = "to16", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { "roms/machines/to16/TO16_103.bin", "" } + }, + { .files_no = 0 } + }, + }, + { + .name = "rtc_port", + .description = "Onboard RTC", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Not installed", .value = 0 }, + { .description = "RTC0", .value = 0x300 }, + { .description = "RTC1", .value = 0x2c0 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { + .name = "rtc_irq", + .description = "RTC IRQ", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = -1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = -1 }, + { .description = "IRQ 2", .value = 2 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t to16_device = { + .name = "Thomson TO16", + .internal_name = "to16_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = to16_config +}; + +int +machine_xt_to16_init(const machine_t *model) +{ + int ret = 0; + int rtc_port = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + rtc_port = machine_get_config_int("rtc_port"); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000f8000, 32768, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + machine_xt_clone_init(model, 0); + + if (rtc_port != 0) + device_add(&rtc58167_device); + + return ret; +} + static const device_config_t vendex_config[] = { // clang-format off { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f6837a9df38..89f231ae5c7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -300,7 +300,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_PCJR, - .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_CARTRIDGE, + .flags = MACHINE_VIDEO_FIXED | MACHINE_KEYBOARD | MACHINE_CARTRIDGE | MACHINE_FDC, .ram = { .min = 64, .max = 640, @@ -316,7 +316,7 @@ const machine_t machines[] = { .gpio_acpi = 0xffffffff, .device = NULL, .kbd_device = NULL, - .fdc_device = NULL, + .fdc_device = &fdc_pcjr_device, .sio_device = NULL, .vid_device = &pcjr_device, .snd_device = NULL, @@ -1126,7 +1126,7 @@ const machine_t machines[] = { .nvrmask = 0, .jumpered_ecp_dma = 0, .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_pc_device, + .kbc_device = &kbc_pc82_device, .kbc_params = 0x00000000, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -1169,7 +1169,7 @@ const machine_t machines[] = { .nvrmask = 0, .jumpered_ecp_dma = 0, .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_pc_device, + .kbc_device = &kbc_xtclone_device, .kbc_params = 0x00000000, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -1212,7 +1212,7 @@ const machine_t machines[] = { .nvrmask = 0, .jumpered_ecp_dma = 0, .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_pc_device, + .kbc_device = &kbc_pc82_device, .kbc_params = 0x00000000, .kbc_p1 = 0xff, .gpio = 0xffffffff, @@ -1784,6 +1784,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Thomson TO16", + .internal_name = "to16", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_to16_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 64, + .max = 768, + .step = 64 + }, + .nvrmask = 0, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_xtclone_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &to16_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Toshiba T1000", .internal_name = "t1000", @@ -6627,7 +6670,7 @@ const machine_t machines[] = { }, /* Has AMIKey 'F' KBC firmware. */ { - .name = "[OPTi 391] DataExpert 386WB", + .name = "[OPTi 391] DataExpert 386C", .internal_name = "dataexpert386wb", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_OPTI_391, @@ -6661,7 +6704,7 @@ const machine_t machines[] = { .kbc_p1 = 0x000004f0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &dataexpert386wb_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -6851,7 +6894,7 @@ const machine_t machines[] = { }, /* Has IBM PS/55 5551-Sxx, Txx stage 2 firmware. */ { - .name = "[MCA] IBM PS/55 model 5550-T", + .name = "[MCA] IBM PS/55 model 5550-S/T Stage II", .internal_name = "ibmps55_m50t", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_PROPRIETARY, @@ -6893,50 +6936,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM PS/55 5551-V0x, V1x firmware. */ - { - .name = "[MCA] IBM PS/55 model 5550-V", - .internal_name = "ibmps55_m50v", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_ps55_model_50v_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX | CPU_PKG_486BL, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_MCA, - .flags = MACHINE_VIDEO | MACHINE_KEYBOARD_JIS | MACHINE_APM, - .ram = { - .min = 4096, - .max = 16384, - .step = 4096 - }, - .nvrmask = 63, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_IBM, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* 386DX/486 machines */ /* Winbond W83C42 - ASIC that clones AMI 'F'. */ @@ -7160,6 +7159,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has IBM PS/55 5551-V0x, V1x firmware. */ + { + .name = "[MCA] IBM PS/55 model 5550-V0/V1", + .internal_name = "ibmps55_m50v", + .type = MACHINE_TYPE_386DX_486, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_ps55_model_50v_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX | CPU_PKG_486BL | CPU_PKG_SOCKET1, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_MCA, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD_JIS | MACHINE_APM, + .ram = { + .min = 4096, + .max = 16384, + .step = 4096 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_IBM, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* 486 machines - Socket 1 */ /* Has JetKey V5 KBC Firmware - we now have a photo of the board and its POST @@ -8831,7 +8874,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_VLB, - .flags = MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_APM, .ram = { .min = 1024, .max = 131072, @@ -10728,7 +10771,7 @@ const machine_t machines[] = { /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ { - .name = "[UMC 8881] PCChips M919", + .name = "[UMC 8881] PC Chips M919", .internal_name = "m919", .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, @@ -11350,7 +11393,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &p5mp3_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -11448,7 +11491,7 @@ const machine_t machines[] = { }, /* Has IBM PS/2 Type 1 KBC firmware. */ { - .name = "[i430LX] IBM PS/ValuePoint P60", + .name = "[i430LX] IBM PS/ValuePoint P60 (Robin ACE)", .internal_name = "valuepointp60", .type = MACHINE_TYPE_SOCKET4, .chipset = MACHINE_CHIPSET_INTEL_430LX, @@ -12423,7 +12466,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &pt2000_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -12431,48 +12474,94 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430FX] HP Pavilion 50x0/70xx (Morrison32)", + .internal_name = "morrison32", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_morrison32_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, + .default_jumpered_ecp_dma = 3, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio32_onboard_pci_device, + .snd_device = &cs4232_onboard_device, + .net_device = NULL + }, { - .name = "[i430FX] IBM PC 3x0 (type 65x6) (Morrison64)", - .internal_name = "pc330_65x6", - .type = MACHINE_TYPE_SOCKET5, - .chipset = MACHINE_CHIPSET_INTEL_430FX, - .init = machine_at_pc330_65x6_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, + .name = "[i430FX] IBM PC 3x0 (type 65x6) (Morrison64)", + .internal_name = "pc330_65x6", + .type = MACHINE_TYPE_SOCKET5, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_pc330_65x6_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), - .min_bus = 50000000, - .max_bus = 66666667, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, .min_voltage = 3380, .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 2.0 + .min_multi = 1.5, + .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 8192, - .max = 131072, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, .step = 8192 }, - .nvrmask = 255, - .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, + .nvrmask = 255, + .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, .default_jumpered_ecp_dma = 3, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x000044f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio64_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the PC87306 Super I/O chip, command 0xA1 returns '5'. @@ -12525,7 +12614,7 @@ const machine_t machines[] = { The board turns out to be a BCM FM540 which has an AMI 'H' KBC. */ { - .name = "[i430FX] NEC PowerMate Vxxx", + .name = "[i430FX] NEC PowerMate Vxxx (BCM FM540)", .internal_name = "powermatev", .type = MACHINE_TYPE_SOCKET5, .chipset = MACHINE_CHIPSET_INTEL_430FX, @@ -12545,7 +12634,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT, .ram = { .min = 8192, .max = 131072, @@ -12564,7 +12653,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &opti_82c930_device, .net_device = NULL }, /* Has AMIKey Z(!) KBC firmware. */ @@ -13040,27 +13129,27 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { .min = 4096, .max = 131072, .step = 4096 }, - .nvrmask = 127, - .jumpered_ecp_dma = MACHINE_DMA_USE_CONFIG, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5434_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL + .nvrmask = 127, + .jumpered_ecp_dma = MACHINE_DMA_USE_CONFIG, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5434_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL }, /* Has a VIA KBC chip */ { @@ -13084,27 +13173,27 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { .min = 4096, .max = 262144, .step = 4096 }, - .nvrmask = 127, - .jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3, + .nvrmask = 127, + .jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3, .default_jumpered_ecp_dma = 1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_VIA | 0x00424600, /* Guess */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_VIA | 0x00424600, /* Guess */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL }, /* KBC firmware is unknown. No commands outside of the base PS/2 */ /* KBC command set are used. */ @@ -13129,27 +13218,27 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, - .ram = { + .flags = MACHINE_IDE_DUAL | MACHINE_APM, + .ram = { .min = 4096, .max = 131072, .step = 4096 }, - .nvrmask = 127, - .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, + .nvrmask = 127, + .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, .default_jumpered_ecp_dma = 4, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL }, /* This has Phoenix KBC firmware. */ { @@ -13173,27 +13262,27 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { .min = 8192, .max = 139264, .step = 4096 }, - .nvrmask = 127, - .jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3, + .nvrmask = 127, + .jumpered_ecp_dma = MACHINE_DMA_1 | MACHINE_DMA_3, .default_jumpered_ecp_dma = 3, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5430_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL }, /* VLSI Wildcat */ @@ -13219,27 +13308,27 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, - .ram = { + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_VIDEO, + .ram = { .min = 4096, .max = 196608, .step = 4096 }, - .nvrmask = 127, - .jumpered_ecp_dma = MACHINE_DMA_3, + .nvrmask = 127, + .jumpered_ecp_dma = MACHINE_DMA_3, .default_jumpered_ecp_dma = 3, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &s3_phoenix_trio64_onboard_pci_device, - .snd_device = NULL, - .net_device = NULL + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_PHOENIX | 0x00012900, /* Guess */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL }, /* Socket 7 (Single Voltage) machines */ @@ -13333,6 +13422,138 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430FX] HP Pavilion 51xx/7070/7090/71xx (Holly)", + .internal_name = "hpholly", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_hpholly_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_Cx6x86), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, + .default_jumpered_ecp_dma = 3, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, + .snd_device = &cs4232_onboard_device, + .net_device = NULL + }, + { + .name = "[i430FX] HP Vectra 500 Series xxx/MT", + .internal_name = "vectra500mt", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_vectra500mt_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 511, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_phoenix_trio64_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[i430FX] HP Vectra VE 5/xxx Series 2", + .internal_name = "vectra52", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_INTEL_430FX, + .init = machine_at_vectra52_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 8192, + .max = 131072, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &vectra52_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5436_onboard_pci_device, + .snd_device = NULL, + .net_device = NULL + }, /* Has a SM(S)C FDC37C932 Super I/O chip with on-chip KBC with AMI MegaKey (revision '5') KBC firmware. */ { @@ -13356,7 +13577,7 @@ const machine_t machines[] = { .max_multi = 2.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 131072, @@ -13402,7 +13623,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */ + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */ .ram = { .min = 8192, .max = 131072, @@ -13421,7 +13642,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &mach64ct_device_onboard, - .snd_device = NULL, + .snd_device = &cs4232_onboard_device, .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the @@ -13448,7 +13669,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */ + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT, /* Machine has optional onboard sound: Crystal CS4232-KQ */ .ram = { .min = 8192, .max = 131072, @@ -13467,7 +13688,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &s3_phoenix_trio64vplus_onboard_pci_device, - .snd_device = NULL, + .snd_device = &cs4232_onboard_device, .net_device = NULL }, /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the @@ -13540,7 +13761,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */ + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has onboard sound: Crystal CS4232-KQ */ .ram = { .min = 8192, .max = 131072, @@ -13559,7 +13780,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &mach64ct_device_onboard, - .snd_device = NULL, + .snd_device = &cs4232_onboard_device, .net_device = NULL }, /* This has an AMIKey-2, which is type 'H'. */ @@ -13598,7 +13819,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ms5119_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -13653,7 +13874,7 @@ const machine_t machines[] = { }, /* Has a VIA VT82C42N KBC. */ { - .name = "[i430FX] PCPartner MB500N", + .name = "[i430FX] PC Partner MB500N", .internal_name = "mb500n", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, @@ -13731,7 +13952,7 @@ const machine_t machines[] = { .kbc_p1 = 0x000004f0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &fmb_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -14102,6 +14323,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has AMIKey H KBC firmware (AMIKey-2). */ + { + .name = "[SiS 5511] HP Pavilion 52xx/53xx/71xx/72xx (BCM FM562)", + .internal_name = "fm562", + .type = MACHINE_TYPE_SOCKET7_3V, + .chipset = MACHINE_CHIPSET_SIS_5511, + .init = machine_at_fm562_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_Cx6x86, CPU_Cx6x86L, CPU_Cx6x86MX), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 3380, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 2.5 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM, /* Machine has internal sound: Crystal CS4232-KQ, and video: SiS 6205 (not yet emulated) */ + .ram = { + .min = 8192, + .max = 524288, + .step = 8192 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_AMI | 0x00004800, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &cs4232_onboard_device, + .net_device = NULL + }, /* Has an SMC FDC37C669QF Super I/O. */ { .name = "[SiS 5511] IBM PC 140 (type 6260)", @@ -14182,7 +14447,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ms5124_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -14330,7 +14595,7 @@ const machine_t machines[] = { }, /* Has the ALi M1543 southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN IV+] PCChips M560", + .name = "[ALi ALADDiN IV+] PC Chips M560", .internal_name = "m560", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, @@ -14350,7 +14615,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -14507,6 +14772,53 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* According to tests from real hardware: This has AMI MegaKey KBC firmware on the + PC87306 Super I/O chip, command 0xA1 returns '5'. + Command 0xA0 copyright string: (C)1994 AMI . */ + { + .name = "[i430HX] HP Pavilion 73xx/74xx (Ruby USB)", + .internal_name = "rubyusb", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430HX, + .init = machine_at_rubyusb_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 50000000, + .max_bus = 66666667, + .min_voltage = 2800, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 524288, + .step = 4096 + }, + .nvrmask = 255, + .jumpered_ecp_dma = MACHINE_DMA_DISABLED | MACHINE_DMA_1 | MACHINE_DMA_3, + .default_jumpered_ecp_dma = 3, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &s3_virge_325_onboard_pci_device, + .snd_device = &ymf701_device, + .net_device = NULL + }, /* OEM-only Intel CU430HX, has AMI MegaKey KBC firmware on the PC87306 Super I/O chip. */ { .name = "[i430HX] Intel CU430HX (Cumberland)", @@ -14983,7 +15295,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 16384, .max = 49152, @@ -15028,7 +15340,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM | MACHINE_ACPI, + .flags = MACHINE_IDE_DUAL | MACHINE_VIDEO | MACHINE_APM, .ram = { .min = 16384, .max = 49152, @@ -15132,7 +15444,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &p5vxb_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -15324,7 +15636,7 @@ const machine_t machines[] = { PC87306 Super I/O chip, command 0xA1 returns '5'. Command 0xA0 copyright string: (C)1994 AMI . */ { - .name = "[i430VX] Packard Bell Orlando/2D/2D/MMX (PB680/PB682/PB683/PB685)", + .name = "[i430VX] Packard Bell Orlando/2D/3D/MMX (PB680/PB682/PB683/PB685)", .internal_name = "pb680", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -15415,7 +15727,7 @@ const machine_t machines[] = { /* This has the AMIKey 'H' firmware, possibly AMIKey-2. Photos show it with a BestKey, so it likely clones the behavior of AMIKey 'H'. */ { - .name = "[i430VX] PCPartner MB520N", + .name = "[i430VX] PC Partner MB520N", .internal_name = "mb520n", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -15570,7 +15882,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -15608,7 +15920,7 @@ const machine_t machines[] = { .chipset = MACHINE_CHIPSET_INTEL_430TX, .init = machine_at_optiplexgn_init, .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, + .gpio_handler = machine_ap440fx_vs440fx_gpio_handler, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { @@ -15648,7 +15960,7 @@ const machine_t machines[] = { }, /* [TEST] Has AMI Megakey '5' KBC firmware on the SM(S)C FDC37C67x Super I/O chip. */ { - .name = "[i430TX] Gateway E-1000", + .name = "[i430TX] Gateway E-1000 (Tomahawk)", .internal_name = "tomahawk", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -15692,48 +16004,48 @@ const machine_t machines[] = { }, /* This has the Phoenix MultiKey KBC firmware on the NSC Super I/O chip. */ { - .name = "[i430TX] Intel AN430TX (Anchorage)", - .internal_name = "an430tx", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_an430tx_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, - CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), - .min_bus = 60000000, - .max_bus = 66666667, + .name = "[i430TX] Intel AN430TX (Anchorage)", + .internal_name = "an430tx", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_an430tx_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = machine_ap440fx_vs440fx_gpio_handler, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK(CPU_K5, CPU_5K86, CPU_K6, CPU_K6_2, CPU_K6_2C, CPU_K6_3, CPU_K6_2P, + CPU_K6_3P, CPU_Cx6x86, CPU_Cx6x86MX, CPU_Cx6x86L), + .min_bus = 60000000, + .max_bus = 66666667, .min_voltage = 2800, .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 + .min_multi = 1.5, + .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_SOUND | MACHINE_GAMEPORT, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ - .ram = { - .min = 8192, - .max = 262144, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ + .ram = { + .min = 8192, + .max = 262144, .step = 8192 }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x000044f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &an430tx_device, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &ymf715_onboard_device, - .net_device = NULL + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000044f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &an430tx_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &ymf715_onboard_device, + .net_device = NULL }, /* This has the Winbond W83977 Super I/O Chip with AMIKey-2 KBC firmware, which is type 'H'. */ { @@ -15758,7 +16070,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 4096, .max = 262144, @@ -15809,7 +16121,7 @@ const machine_t machines[] = { }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Machine has internal sound: Yamaha YMF701-S */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, .max = 262144, @@ -15879,7 +16191,7 @@ const machine_t machines[] = { /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { - .name = "[i430TX] PCPartner MB540N", + .name = "[i430TX] PC Partner MB540N", .internal_name = "mb540n", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -15943,7 +16255,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 4096, .max = 262144, @@ -16135,7 +16447,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ms5146_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -16211,7 +16523,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -16255,7 +16567,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1572864, @@ -16301,7 +16613,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -16348,7 +16660,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 524288, @@ -16395,7 +16707,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -16420,7 +16732,7 @@ const machine_t machines[] = { /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA VP3] PCPartner VIA809DS", + .name = "[VIA VP3] PC Partner VIA809DS", .internal_name = "via809ds", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, @@ -16440,7 +16752,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -16644,7 +16956,7 @@ const machine_t machines[] = { /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN V] PCChips M579", + .name = "[ALi ALADDiN V] PC Chips M579", .internal_name = "m579", .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, @@ -16664,7 +16976,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ .ram = { .min = 8192, .max = 1572864, @@ -16802,7 +17114,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 16384, .max = 786432, @@ -16824,33 +17136,33 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the VIA VT82C596A southbridge with on-chip KBC identical to the VIA - VT82C42N. Sadly likely abuses cache on Cyrix 6x86MX and MII CPUs (Cyrix MII being what most socket 7 eMachines PCs used) , so they are blocked and it's thus named after the only known eMachines with an AMD K6-2 CPU here */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { - .name = "[VIA MVP3] eMachines eTower 300k", - .internal_name = "delhi3", + .name = "[VIA MVP3] FIC VA-503+", + .internal_name = "ficva503p", .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_delhi3_init, + .init = machine_at_mvp3_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK(CPU_Cx6x86MX), + .block = CPU_BLOCK_NONE, .min_bus = 66666667, .max_bus = 124242424, .min_voltage = 2000, - .max_voltage = 3520, + .max_voltage = 3200, .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: ATI 3D Rage IIc AGP (Rage 2) */ - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_SOUND | MACHINE_USB, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 524288, + .max = 1048576, .step = 8192 }, .nvrmask = 255, @@ -16866,17 +17178,17 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = &cs4235_onboard_device, + .snd_device = NULL, .net_device = NULL }, - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA MVP3] FIC VA-503+", - .internal_name = "ficva503p", + .name = "[VIA MVP3] FIC VA-503A", + .internal_name = "ficva503a", .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_mvp3_init, + .init = machine_at_ficva503a_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -16886,16 +17198,16 @@ const machine_t machines[] = { .block = CPU_BLOCK_NONE, .min_bus = 66666667, .max_bus = 124242424, - .min_voltage = 2000, - .max_voltage = 3200, + .min_voltage = 1800, + .max_voltage = 3100, .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, .ram = { .min = 8192, - .max = 1048576, + .max = 786432, .step = 8192 }, .nvrmask = 255, @@ -16917,11 +17229,11 @@ const machine_t machines[] = { /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA MVP3] FIC VA-503A", - .internal_name = "ficva503a", + .name = "[VIA MVP3] Soyo 5EMA PRO", + .internal_name = "5emapro", .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_ficva503a_init, + .init = machine_at_5emapro_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -16931,13 +17243,13 @@ const machine_t machines[] = { .block = CPU_BLOCK_NONE, .min_bus = 66666667, .max_bus = 124242424, - .min_voltage = 1800, - .max_voltage = 3100, + .min_voltage = 2000, + .max_voltage = 3520, .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -16959,21 +17271,20 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the VIA VT82C686A southbridge with on-chip KBC identical to the VIA - VT82C42N. */ + /* Has the VIA VT82C596A southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA MVP3] Soyo 5EMA PRO", - .internal_name = "5emapro", + .name = "[VIA MVP3] TriGem Delhi-III", + .internal_name = "delhi3", .type = MACHINE_TYPE_SOCKETS7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_MVP3, - .init = machine_at_5emapro_init, + .init = machine_at_delhi3_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, + .block = CPU_BLOCK(CPU_Cx6x86MX), /* Sadly it likely abuses cache if using Cyrix 6x86MX and MII CPUs (the latter being what most Socket 7 eMachines PCs used), so they are blocked. */ .min_bus = 66666667, .max_bus = 124242424, .min_voltage = 2000, @@ -16981,11 +17292,11 @@ const machine_t machines[] = { .min_multi = 1.5, .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, /* Has internal video: ATI 3D Rage IIc AGP (Rage 2) */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_SOUND | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, + .max = 524288, .step = 8192 }, .nvrmask = 255, @@ -16996,12 +17307,12 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &delhi3_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &cs4235_onboard_device, .net_device = NULL }, @@ -17032,7 +17343,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM, .ram = { .min = 8192, - .max = 524288, + .max = 262144, .step = 8192 }, .nvrmask = 127, @@ -17328,7 +17639,7 @@ const machine_t machines[] = { .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_ap440fx_init, .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, + .gpio_handler = machine_ap440fx_vs440fx_gpio_handler, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { @@ -17374,7 +17685,7 @@ const machine_t machines[] = { .chipset = MACHINE_CHIPSET_INTEL_440FX, .init = machine_at_vs440fx_init, .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, + .gpio_handler = machine_ap440fx_vs440fx_gpio_handler, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { @@ -17434,7 +17745,7 @@ const machine_t machines[] = { .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal SCSI: Adaptec AIC-7880U */ .ram = { - .min = 40960, + .min = 40960, /* does not POST with lower than 40MB; Award and AMI retail BIOSes not affected(?) */ .max = 524288, .step = 8192 }, @@ -17501,7 +17812,7 @@ const machine_t machines[] = { }, /* Has a VIA VT82C42N KBC. */ { - .name = "[i440FX] PCPartner MB600N", + .name = "[i440FX] PC Partner MB600N", .internal_name = "mb600n", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, @@ -17548,7 +17859,7 @@ const machine_t machines[] = { /* ALi ALADDiN-PRO II */ /* Has the ALi M1543C southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN-PRO II] PCChips M729", + .name = "[ALi ALADDiN-PRO II] PC Chips M729", .internal_name = "m729", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_PRO_II, @@ -17750,7 +18061,7 @@ const machine_t machines[] = { .max_multi = 5.5 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 1048576, @@ -17781,7 +18092,7 @@ const machine_t machines[] = { .chipset = MACHINE_CHIPSET_INTEL_440LX, .init = machine_at_optiplexgxa_init, .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, + .gpio_handler = machine_ap440fx_vs440fx_gpio_handler, .available_flag = MACHINE_AVAILABLE, .gpio_acpi_handler = NULL, .cpu = { @@ -17795,7 +18106,7 @@ const machine_t machines[] = { .max_multi = 5.0 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Video: ATi 3D Rage Pro, Network: 3Com 3C905, Sound: Crystal CS4236B */ + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_USB, /* Video: ATi 3D Rage Pro, Network: 3Com 3C905, Sound: Crystal CS4236B */ .ram = { .min = 8192, .max = 786432, @@ -17840,7 +18151,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701 */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, /* Machine has internal sound: Yamaha YMF701 */ .ram = { .min = 8192, .max = 1048576, @@ -18083,7 +18394,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ax6bc_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -18337,7 +18648,7 @@ const machine_t machines[] = { .max_multi = 8.0 }, .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, .max = 786432, @@ -18351,7 +18662,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &p6sba_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -18396,7 +18707,7 @@ const machine_t machines[] = { .kbc_p1 = 0x000044f0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &s1846_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -18409,7 +18720,7 @@ const machine_t machines[] = { /* Has a SM(S)C FDC37M60x Super I/O chip with on-chip KBC with most likely AMIKey-2 KBC firmware. */ { - .name = "[i440ZX] HP Vectra VEi 8", + .name = "[i440ZX] MiTAC/Trigon 6110Zu", .internal_name = "vei8", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440ZX, @@ -18443,7 +18754,7 @@ const machine_t machines[] = { .kbc_p1 = 0x000044f0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &vei8_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -18589,7 +18900,7 @@ const machine_t machines[] = { }, /* Has the SiS (5)600 chipset with on-chip KBC. */ { - .name = "[SiS 5600] PCChips M747", + .name = "[SiS 5600] PC Chips M747", .internal_name = "m747", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_SIS_5600, @@ -18725,6 +19036,8 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + + /* VIA Apollo Pro 133 */ /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { @@ -18770,6 +19083,53 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[VIA Apollo Pro 133] MSI MS-6199VA", + .internal_name = "ms6199va", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .init = machine_at_ms6199va_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 155000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ms6199va_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + + /* VIA Apollo Pro 133A */ /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { @@ -18911,13 +19271,12 @@ const machine_t machines[] = { /* Slot 1/Socket 370 machines */ /* 440BX */ - /* OEM version of ECS P6BXT-A+ REV 1.3x/2.2x. Has a Winbond W83977EF Super - I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/ + /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware.*/ { - .name = "[i440BX] Compaq ProSignia S316/318 (Intel)", + .name = "[i440BX] ECS P6BXT-A+", .internal_name = "prosignias31x_bx", .type = MACHINE_TYPE_SLOT1_370, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133, + .chipset = MACHINE_CHIPSET_INTEL_440BX, .init = machine_at_prosignias31x_bx_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, @@ -18925,9 +19284,9 @@ const machine_t machines[] = { .gpio_acpi_handler = NULL, .cpu = { .package = CPU_PKG_SLOT1 | CPU_PKG_SOCKET370, - .block = CPU_BLOCK(CPU_PENTIUMPRO, CPU_CYRIX3S), /* Instability issues with PPro, and garbled text in POST with Cyrix */ + .block = CPU_BLOCK(CPU_PENTIUMPRO), /* Instability issues with PPro, and garbled text in POST with Cyrix (latter supported on unofficial v6.00PG BIOS) */ .min_bus = 66666667, - .max_bus = 100000000, + .max_bus = 124242424, .min_voltage = 1300, .max_voltage = 3500, .min_multi = 1.5, @@ -18948,7 +19307,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &prosignias31x_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, @@ -19470,7 +19829,7 @@ const machine_t machines[] = { /* Has an ITE IT8671F Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] PCChips M773", + .name = "[SMSC VictoryBX-66] PC Chips M773", .internal_name = "m773", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -19517,7 +19876,7 @@ const machine_t machines[] = { /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA Apollo Pro] PCPartner APAS3", + .name = "[VIA Apollo Pro] PC Partner APAS3", .internal_name = "apas3", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, @@ -19694,6 +20053,96 @@ const machine_t machines[] = { .snd_device = &cmi8738_onboard_device, .net_device = NULL }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA Apollo Pro 133A] MSI MS-6318", + .internal_name = "ms6318", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_ms6318_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_AG | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, + .ram = { + .min = 16384, + .max = 2097152, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ms6318_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &ct5880_onboard_device, + .net_device = NULL + }, + /* Has the VIA VT82C686B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA Apollo Pro 133A] Samsung CAIRO-5 (MSI MS-6309)", + .internal_name = "cairo5", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO_133A, + .init = machine_at_cairo5_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 150000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = MACHINE_MULTIPLIER_FIXED, + .max_multi = MACHINE_MULTIPLIER_FIXED + }, + .bus_flags = MACHINE_PS2_A97 | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 16384, + .max = 3145728, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Miscellaneous/Fake/Hypervisor machines */ /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC @@ -20235,7 +20684,7 @@ machine_get_nvr_name_ex(int m) if (dev != NULL) { device_context(dev); - const char *bios = device_get_config_string("bios"); + const char *bios = device_get_config_bios("bios"); if ((bios != NULL) && (strcmp(bios, "") != 0)) ret = bios; device_context_restore(); diff --git a/src/mem/mem.c b/src/mem/mem.c index b4225372d3b..80803e6a2f4 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -2316,7 +2316,38 @@ mem_mapping_recalc(uint64_t base, uint64_t size) if (start < map->base) start = map->base; - for (i_c = i_s; i_c <= i_e; i_c += i_a) { + if (i_e == 0x00000000ULL) { + for (c = start; c < end; c += MEM_GRANULARITY_SIZE) { + /* CPU */ + n = !!in_smm; + wp = _mem_wp[c >> MEM_GRANULARITY_BITS]; + + if (map->exec && mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].x)) + _mem_exec[c >> MEM_GRANULARITY_BITS] = map->exec + (c - map->base); + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + write_mapping[c >> MEM_GRANULARITY_BITS] = map; + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + read_mapping[c >> MEM_GRANULARITY_BITS] = map; + + /* Bus */ + n |= STATE_BUS; + wp = _mem_wp_bus[c >> MEM_GRANULARITY_BITS]; + + if (!wp && (map->write_b || map->write_w || map->write_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].w)) + write_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; + if ((map->read_b || map->read_w || map->read_l) && + mem_mapping_access_allowed(map->flags, + _mem_state[c >> MEM_GRANULARITY_BITS].states[n].r)) + read_mapping_bus[c >> MEM_GRANULARITY_BITS] = map; + } + } else for (i_c = i_s; i_c <= i_e; i_c += i_a) { for (c = (start + i_c); c < (end + i_c); c += MEM_GRANULARITY_SIZE) { /* CPU */ n = (!!in_smm) || (is_cxsmm && (ccr1 & CCR1_SMAC)); diff --git a/src/mem/rom.c b/src/mem/rom.c index 6313289130b..5798b4252ee 100644 --- a/src/mem/rom.c +++ b/src/mem/rom.c @@ -85,6 +85,36 @@ rom_add_path(const char *path) path_slash(rom_path->path); } +void +asset_add_path(const char *path) +{ + char cwd[1024] = { 0 }; + + rom_path_t *asset_path = &asset_paths; + + if (asset_paths.path[0] != '\0') { + // Iterate to the end of the list. + while (asset_path->next != NULL) { + asset_path = asset_path->next; + } + + // Allocate the new entry. + asset_path = asset_path->next = calloc(1, sizeof(rom_path_t)); + } + + // Save the path, turning it into absolute if needed. + if (!path_abs((char *) path)) { + plat_getcwd(cwd, sizeof(cwd)); + path_slash(cwd); + snprintf(asset_path->path, sizeof(asset_path->path), "%s%s", cwd, path); + } else { + snprintf(asset_path->path, sizeof(asset_path->path), "%s", path); + } + + // Ensure the path ends with a separator. + path_slash(asset_path->path); +} + static int rom_check(const char *fn) { @@ -129,6 +159,31 @@ rom_get_full_path(char *dest, const char *fn) } } +void +asset_get_full_path(char *dest, const char *fn) +{ + char temp[1024] = { 0 }; + + dest[0] = 0x00; + + if (!strncmp(fn, "assets/", 7)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 7); + + if (rom_check(temp)) { + strcpy(dest, temp); + return; + } + } + + return; + } else { + /* Absolute path */ + strcpy(dest, fn); + } +} + FILE * rom_fopen(const char *fn, char *mode) { @@ -154,6 +209,31 @@ rom_fopen(const char *fn, char *mode) } } +FILE * +asset_fopen(const char *fn, char *mode) +{ + char temp[1024]; + FILE *fp = NULL; + + if ((fn == NULL) || (mode == NULL)) + return NULL; + + if (!strncmp(fn, "assets/", 7)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 7); + + if ((fp = plat_fopen(temp, mode)) != NULL) + return fp; + } + + return fp; + } else { + /* Absolute path */ + return plat_fopen(fn, mode); + } +} + int rom_getfile(const char *fn, char *s, int size) { @@ -182,6 +262,34 @@ rom_getfile(const char *fn, char *s, int size) } } +int +asset_getfile(const char *fn, char *s, int size) +{ + char temp[1024]; + + if (!strncmp(fn, "assets/", 7)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 7); + + if (plat_file_check(temp)) { + strncpy(s, temp, size); + return 1; + } + } + + return 0; + } else { + /* Absolute path */ + if (plat_file_check(fn)) { + strncpy(s, fn, size); + return 1; + } + + return 0; + } +} + int rom_present(const char *fn) { @@ -206,6 +314,30 @@ rom_present(const char *fn) } } +int +asset_present(const char *fn) +{ + char temp[1024]; + + if (fn == NULL) + return 0; + + if (!strncmp(fn, "assets/", 7)) { + /* Relative path */ + for (rom_path_t *asset_path = &asset_paths; asset_path != NULL; asset_path = asset_path->next) { + path_append_filename(temp, asset_path->path, fn + 7); + + if (plat_file_check(temp)) + return 1; + } + + return 0; + } else { + /* Absolute path */ + return plat_file_check(fn); + } +} + uint8_t rom_read(uint32_t addr, void *priv) { @@ -643,27 +775,27 @@ bios_load(const char *fn1, const char *fn2, uint32_t addr, int sz, int off, int int bios_load_linear_combined(const char *fn1, const char *fn2, int sz, UNUSED(int off)) { - return bios_load_linear(fn1, 0x000f0000, 131072, 128) && \ + return bios_load_linear(fn1, 0x000f0000, 131072, 128) && bios_load_aux_linear(fn2, 0x000e0000, sz - 65536, 128); } int bios_load_linear_combined2(const char *fn1, const char *fn2, const char *fn3, const char *fn4, const char *fn5, int sz, int off) { - return bios_load_linear(fn3, 0x000f0000, 262144, off) && \ - bios_load_aux_linear(fn1, 0x000d0000, 65536, off) && \ - bios_load_aux_linear(fn2, 0x000c0000, 65536, off) && \ - bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off) && \ + return bios_load_linear(fn3, 0x000f0000, 262144, off) && + bios_load_aux_linear(fn1, 0x000d0000, 65536, off) && + bios_load_aux_linear(fn2, 0x000c0000, 65536, off) && + bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off) && (!fn5 || bios_load_aux_linear(fn5, 0x000ec000, 16384, 0)); } int bios_load_linear_combined2_ex(const char *fn1, const char *fn2, const char *fn3, const char *fn4, const char *fn5, int sz, int off) { - return bios_load_linear(fn3, 0x000e0000, 262144, off) && \ - bios_load_aux_linear(fn1, 0x000c0000, 65536, off) && \ - bios_load_aux_linear(fn2, 0x000d0000, 65536, off) && \ - bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off) && \ + return bios_load_linear(fn3, 0x000e0000, 262144, off) && + bios_load_aux_linear(fn1, 0x000c0000, 65536, off) && + bios_load_aux_linear(fn2, 0x000d0000, 65536, off) && + bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off) && (!fn5 || bios_load_aux_linear(fn5, 0x000fc000, 16384, 0)); } diff --git a/src/network/net_l80225.c b/src/network/net_l80225.c index 6493edec6d9..341799e57cf 100644 --- a/src/network/net_l80225.c +++ b/src/network/net_l80225.c @@ -34,8 +34,17 @@ l80225_mii_readw(uint16_t *regs, uint16_t addr) return 0; } +/* Readonly mask for MDI (PHY) registers */ +static const uint16_t tulip_mdi_mask[] = { + 0x0000, 0xffff, 0xffff, 0xffff, 0xc01f, 0xffff, 0xffff, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0fff, 0x0000, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + +}; + void l80225_mii_writew(uint16_t *regs, uint16_t addr, uint16_t val) { - regs[addr] = val; + regs[addr] = val & tulip_mdi_mask[addr]; } diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 5f2c85b0300..9cc52417fd9 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3257,14 +3257,9 @@ nic_init(const device_t *info) eep_data[1] = 0x10EC; eep_data[2] = 0x8139; - /* XXX: Get proper MAC addresses from real EEPROM dumps. OID taken from net_ne2000.c */ -#ifdef USE_REALTEK_OID + /* XXX: Get proper MAC addresses from real EEPROM dumps. OID is generic Realtek */ eep_data[7] = 0xe000; eep_data[8] = 0x124c; -#else - eep_data[7] = 0x1400; - eep_data[8] = 0x122a; -#endif eep_data[9] = 0x1413; mac_bytes = (uint8_t *) &(eep_data[7]); diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 113af5cd415..f93ac87670e 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -346,10 +346,10 @@ static void tulip_desc_read(TULIPState *s, uint32_t p, struct tulip_descriptor *desc) { - desc->status = mem_readl_phys(p); - desc->control = mem_readl_phys(p + 4); - desc->buf_addr1 = mem_readl_phys(p + 8); - desc->buf_addr2 = mem_readl_phys(p + 12); + dma_bm_read(p , (uint8_t *) &(desc->status) , 4, 4); + dma_bm_read(p + 4, (uint8_t *) &(desc->control) , 4, 4); + dma_bm_read(p + 8, (uint8_t *) &(desc->buf_addr1), 4, 4); + dma_bm_read(p + 12, (uint8_t *) &(desc->buf_addr2), 4, 4); if (s->csr[0] & CSR0_DBO) { bswap32s(&desc->status); @@ -364,15 +364,20 @@ tulip_desc_write(TULIPState *s, uint32_t p, struct tulip_descriptor *desc) { if (s->csr[0] & CSR0_DBO) { - mem_writel_phys(p, bswap32(desc->status)); - mem_writel_phys(p + 4, bswap32(desc->control)); - mem_writel_phys(p + 8, bswap32(desc->buf_addr1)); - mem_writel_phys(p + 12, bswap32(desc->buf_addr2)); + uint32_t status = bswap32(desc->status); + uint32_t control = bswap32(desc->control); + uint32_t buf_addr1 = bswap32(desc->buf_addr1); + uint32_t buf_addr2 = bswap32(desc->buf_addr2); + + dma_bm_write(p , (uint8_t *) &status , 4, 4); + dma_bm_write(p + 4, (uint8_t *) &control , 4, 4); + dma_bm_write(p + 8, (uint8_t *) &buf_addr1, 4, 4); + dma_bm_write(p + 12, (uint8_t *) &buf_addr2, 4, 4); } else { - mem_writel_phys(p, desc->status); - mem_writel_phys(p + 4, desc->control); - mem_writel_phys(p + 8, desc->buf_addr1); - mem_writel_phys(p + 12, desc->buf_addr2); + dma_bm_write(p , (uint8_t *) &(desc->status) , 4, 4); + dma_bm_write(p + 4, (uint8_t *) &(desc->control) , 4, 4); + dma_bm_write(p + 8, (uint8_t *) &(desc->buf_addr1), 4, 4); + dma_bm_write(p + 12, (uint8_t *) &(desc->buf_addr2), 4, 4); } } @@ -433,6 +438,10 @@ tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc) len = s->rx_frame_len; } + if (s->rx_frame_len + len > sizeof(s->rx_frame)) { + return; + } + dma_bm_write(desc->buf_addr1, s->rx_frame + (s->rx_frame_size - s->rx_frame_len), len, 4); s->rx_frame_len -= len; } @@ -444,6 +453,10 @@ tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc) len = s->rx_frame_len; } + if (s->rx_frame_len + len > sizeof(s->rx_frame)) { + return; + } + dma_bm_write(desc->buf_addr2, s->rx_frame + (s->rx_frame_size - s->rx_frame_len), len, 4); s->rx_frame_len -= len; } @@ -452,9 +465,7 @@ tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc) static bool tulip_filter_address(TULIPState *s, const uint8_t *addr) { -#ifdef BLOCK_BROADCAST static const char broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -#endif bool ret = false; for (uint8_t i = 0; i < 16 && ret == false; i++) { @@ -463,15 +474,9 @@ tulip_filter_address(TULIPState *s, const uint8_t *addr) } } -/* - Do not block broadcast packets - needed for connections to the guest - to succeed when using SLiRP. - */ -#ifdef BLOCK_BROADCAST if (!memcmp(addr, broadcast, ETH_ALEN)) { return true; } -#endif if (s->csr[6] & (CSR6_PR | CSR6_RA)) { /* Promiscuous mode enabled */ @@ -576,7 +581,7 @@ static const uint16_t tulip_mdi_default[] = { 0x0600, 0x0001, 0x0000, - 0x0000, + 0x3b40, 0x0000, 0x0000, 0x0000, diff --git a/src/qt/be_keyboard.hpp b/src/qt/be_keyboard.hpp index cc2bbabac7b..cd5303e6433 100644 --- a/src/qt/be_keyboard.hpp +++ b/src/qt/be_keyboard.hpp @@ -1,112 +1,112 @@ static std::unordered_map be_keycodes = { - {B_F1_KEY, 0x3b}, - {B_F2_KEY, 0x3c}, - {B_F3_KEY, 0x3d}, - {B_F4_KEY, 0x3e}, - {B_F5_KEY, 0x3f}, - {B_F6_KEY, 0x40}, - {B_F7_KEY, 0x41}, - {B_F8_KEY, 0x42}, - {B_F9_KEY, 0x43}, - {B_F10_KEY, 0x44}, - {B_F11_KEY, 0x57}, - {B_F12_KEY, 0x58}, - {B_PRINT_KEY, 0x137}, - {B_SCROLL_KEY, 0x46}, - {B_PAUSE_KEY, 0x145}, - {B_KATAKANA_HIRAGANA, 0x70}, - {B_HANKAKU_ZENKAKU, 0x76}, + { B_F1_KEY, 0x3b }, + { B_F2_KEY, 0x3c }, + { B_F3_KEY, 0x3d }, + { B_F4_KEY, 0x3e }, + { B_F5_KEY, 0x3f }, + { B_F6_KEY, 0x40 }, + { B_F7_KEY, 0x41 }, + { B_F8_KEY, 0x42 }, + { B_F9_KEY, 0x43 }, + { B_F10_KEY, 0x44 }, + { B_F11_KEY, 0x57 }, + { B_F12_KEY, 0x58 }, + { B_PRINT_KEY, 0x137 }, + { B_SCROLL_KEY, 0x46 }, + { B_PAUSE_KEY, 0x145 }, + { B_KATAKANA_HIRAGANA, 0x70 }, + { B_HANKAKU_ZENKAKU, 0x76 }, - {0x01, 0x01}, /* Escape */ - {0x11, 0x29}, - {0x12, 0x02}, - {0x13, 0x03}, - {0x14, 0x04}, - {0x15, 0x05}, - {0x16, 0x06}, - {0x17, 0x07}, - {0x18, 0x08}, - {0x19, 0x09}, - {0x1a, 0x0a}, - {0x1b, 0x0b}, - {0x1c, 0x0c}, - {0x1d, 0x0d}, - {0x1e, 0x0e}, /* Backspace */ - {0x1f, 0x152}, /* Insert */ - {0x20, 0x147}, /* Home */ - {0x21, 0x149}, /* Page Up */ - {0x22, 0x45}, - {0x23, 0x135}, - {0x24, 0x37}, - {0x25, 0x4a}, - {0x26, 0x0f}, /* Tab */ - {0x27, 0x10}, - {0x28, 0x11}, - {0x29, 0x12}, - {0x2a, 0x13}, - {0x2b, 0x14}, - {0x2c, 0x15}, - {0x2d, 0x16}, - {0x2e, 0x17}, - {0x2f, 0x18}, - {0x30, 0x19}, - {0x31, 0x1a}, - {0x32, 0x1b}, - {0x33, 0x2b}, - {0x34, 0x153}, /* Delete */ - {0x35, 0x14f}, /* End */ - {0x36, 0x151}, /* Page Down */ - {0x37, 0x47}, - {0x38, 0x48}, - {0x39, 0x49}, - {0x3a, 0x4e}, - {0x3b, 0x3a}, - {0x3c, 0x1e}, - {0x3d, 0x1f}, - {0x3e, 0x20}, - {0x3f, 0x21}, - {0x40, 0x22}, - {0x41, 0x23}, - {0x42, 0x24}, - {0x43, 0x25}, - {0x44, 0x26}, - {0x45, 0x27}, - {0x46, 0x28}, - {0x47, 0x1c}, /* Enter */ - {0x48, 0x4b}, - {0x49, 0x4c}, - {0x4a, 0x4d}, - {0x4b, 0x2a}, - {0x4c, 0x2c}, - {0x4d, 0x2d}, - {0x4e, 0x2e}, - {0x4f, 0x2f}, - {0x50, 0x30}, - {0x51, 0x31}, - {0x52, 0x32}, - {0x53, 0x33}, - {0x54, 0x34}, - {0x55, 0x35}, - {0x56, 0x36}, - {0x57, 0x148}, /* up arrow */ - {0x58, 0x51}, - {0x59, 0x50}, - {0x5a, 0x4f}, - {0x5b, 0x11c}, - {0x5c, 0x1d}, - {0x5d, 0x38}, - {0x5e, 0x39}, /* space bar */ - {0x5f, 0x138}, - {0x60, 0x11d}, - {0x61, 0x14b}, /* left arrow */ - {0x62, 0x150}, /* down arrow */ - {0x63, 0x14d}, /* right arrow */ - {0x64, 0x52}, - {0x65, 0x53}, - {0x66, 0x15b}, - {0x67, 0x15c}, - {0x68, 0x15d}, - {0x69, 0x56}, - {0x7e, 0x137}, /* System Request */ - {0x7f, 0x145}, /* Break */ + { 0x01, 0x01 }, /* Escape */ + { 0x11, 0x29 }, + { 0x12, 0x02 }, + { 0x13, 0x03 }, + { 0x14, 0x04 }, + { 0x15, 0x05 }, + { 0x16, 0x06 }, + { 0x17, 0x07 }, + { 0x18, 0x08 }, + { 0x19, 0x09 }, + { 0x1a, 0x0a }, + { 0x1b, 0x0b }, + { 0x1c, 0x0c }, + { 0x1d, 0x0d }, + { 0x1e, 0x0e }, /* Backspace */ + { 0x1f, 0x152 }, /* Insert */ + { 0x20, 0x147 }, /* Home */ + { 0x21, 0x149 }, /* Page Up */ + { 0x22, 0x45 }, + { 0x23, 0x135 }, + { 0x24, 0x37 }, + { 0x25, 0x4a }, + { 0x26, 0x0f }, /* Tab */ + { 0x27, 0x10 }, + { 0x28, 0x11 }, + { 0x29, 0x12 }, + { 0x2a, 0x13 }, + { 0x2b, 0x14 }, + { 0x2c, 0x15 }, + { 0x2d, 0x16 }, + { 0x2e, 0x17 }, + { 0x2f, 0x18 }, + { 0x30, 0x19 }, + { 0x31, 0x1a }, + { 0x32, 0x1b }, + { 0x33, 0x2b }, + { 0x34, 0x153 }, /* Delete */ + { 0x35, 0x14f }, /* End */ + { 0x36, 0x151 }, /* Page Down */ + { 0x37, 0x47 }, + { 0x38, 0x48 }, + { 0x39, 0x49 }, + { 0x3a, 0x4e }, + { 0x3b, 0x3a }, + { 0x3c, 0x1e }, + { 0x3d, 0x1f }, + { 0x3e, 0x20 }, + { 0x3f, 0x21 }, + { 0x40, 0x22 }, + { 0x41, 0x23 }, + { 0x42, 0x24 }, + { 0x43, 0x25 }, + { 0x44, 0x26 }, + { 0x45, 0x27 }, + { 0x46, 0x28 }, + { 0x47, 0x1c }, /* Enter */ + { 0x48, 0x4b }, + { 0x49, 0x4c }, + { 0x4a, 0x4d }, + { 0x4b, 0x2a }, + { 0x4c, 0x2c }, + { 0x4d, 0x2d }, + { 0x4e, 0x2e }, + { 0x4f, 0x2f }, + { 0x50, 0x30 }, + { 0x51, 0x31 }, + { 0x52, 0x32 }, + { 0x53, 0x33 }, + { 0x54, 0x34 }, + { 0x55, 0x35 }, + { 0x56, 0x36 }, + { 0x57, 0x148 }, /* up arrow */ + { 0x58, 0x51 }, + { 0x59, 0x50 }, + { 0x5a, 0x4f }, + { 0x5b, 0x11c }, + { 0x5c, 0x1d }, + { 0x5d, 0x38 }, + { 0x5e, 0x39 }, /* space bar */ + { 0x5f, 0x138 }, + { 0x60, 0x11d }, + { 0x61, 0x14b }, /* left arrow */ + { 0x62, 0x150 }, /* down arrow */ + { 0x63, 0x14d }, /* right arrow */ + { 0x64, 0x52 }, + { 0x65, 0x53 }, + { 0x66, 0x15b }, + { 0x67, 0x15c }, + { 0x68, 0x15d }, + { 0x69, 0x56 }, + { 0x7e, 0x137 }, /* System Request */ + { 0x7f, 0x145 }, /* Break */ }; diff --git a/src/qt/cocoa_keyboard.hpp b/src/qt/cocoa_keyboard.hpp index da3161bb229..136dd9a6521 100644 --- a/src/qt/cocoa_keyboard.hpp +++ b/src/qt/cocoa_keyboard.hpp @@ -1,4 +1,5 @@ -static std::array cocoa_keycodes = { /* key names in parentheses are not declared by Apple headers */ +static std::array cocoa_keycodes = { + /* key names in parentheses are not declared by Apple headers */ 0x1e, /* ANSI_A */ 0x1f, /* ANSI_S */ 0x20, /* ANSI_D */ @@ -66,9 +67,9 @@ static std::array cocoa_keycodes = { /* key names in parentheses 0x5e, /* F17 => F14 */ 0x53, /* ANSI_KeypadDecimal */ 0, - 0x37, /* ANSI_KeypadMultiply */ + 0x37, /* ANSI_KeypadMultiply */ 0, - 0x4e, /* ANSI_KeypadPlus */ + 0x4e, /* ANSI_KeypadPlus */ 0, 0x45, /* ANSI_KeypadClear => Num Lock (location equivalent) */ 0x130, /* VolumeUp */ diff --git a/src/qt/evdev_keyboard.cpp b/src/qt/evdev_keyboard.cpp index 0f54775baa7..e0fcea3d0cb 100644 --- a/src/qt/evdev_keyboard.cpp +++ b/src/qt/evdev_keyboard.cpp @@ -16,132 +16,132 @@ #include static std::unordered_map evdev_keycodes = { - {184, 0x46}, /* F14 => Scroll Lock (for Apple keyboards) */ - {86, 0x56}, /* 102ND */ - {87, 0x57}, /* F11 */ - {88, 0x58}, /* F12 */ - {186, 0x5d}, /* F16 => F13 */ - {187, 0x5e}, /* F17 => F14 */ - {188, 0x5f}, /* F18 => F15 */ + { 184, 0x46 }, /* F14 => Scroll Lock (for Apple keyboards) */ + { 86, 0x56 }, /* 102ND */ + { 87, 0x57 }, /* F11 */ + { 88, 0x58 }, /* F12 */ + { 186, 0x5d }, /* F16 => F13 */ + { 187, 0x5e }, /* F17 => F14 */ + { 188, 0x5f }, /* F18 => F15 */ /* Japanese keys. */ - {95, 0x5c}, /* KPJPCOMMA */ - {93, 0x70}, /* KATAKANAHIRAGANA */ - {89, 0x73}, /* RO */ - {85, 0x76}, /* ZENKAKUHANKAKU */ - {91, 0x77}, /* HIRAGANA */ - {90, 0x78}, /* KATAKANA */ - {92, 0x79}, /* HENKAN */ - {94, 0x7b}, /* MUHENKAN */ - {124, 0x7d}, /* YEN */ - {121, 0x7e}, /* KPCOMMA */ + { 95, 0x5c }, /* KPJPCOMMA */ + { 93, 0x70 }, /* KATAKANAHIRAGANA */ + { 89, 0x73 }, /* RO */ + { 85, 0x76 }, /* ZENKAKUHANKAKU */ + { 91, 0x77 }, /* HIRAGANA */ + { 90, 0x78 }, /* KATAKANA */ + { 92, 0x79 }, /* HENKAN */ + { 94, 0x7b }, /* MUHENKAN */ + { 124, 0x7d }, /* YEN */ + { 121, 0x7e }, /* KPCOMMA */ /* Korean keys. */ - {123, 0xf1}, /* HANJA */ - {122, 0xf2}, /* HANGUL */ + { 123, 0xf1 }, /* HANJA */ + { 122, 0xf2 }, /* HANGUL */ - {96, 0x11c}, /* KPENTER */ - {97, 0x11d}, /* RIGHTCTRL */ - {98, 0x135}, /* KPSLASH */ - {99, 0x137}, /* SYSRQ */ - {183, 0x137}, /* F13 => SysRq (for Apple keyboards) */ - {100, 0x138}, /* RIGHTALT */ - {119, 0x145}, /* PAUSE */ - {411, 0x145}, /* BREAK */ - {185, 0x145}, /* F15 => Pause (for Apple keyboards) */ - {102, 0x147}, /* HOME */ - {103, 0x148}, /* UP */ - {104, 0x149}, /* PAGEUP */ - {105, 0x14b}, /* LEFT */ - {106, 0x14d}, /* RIGHT */ - {107, 0x14f}, /* END */ - {108, 0x150}, /* DOWN */ - {109, 0x151}, /* PAGEDOWN */ - {110, 0x152}, /* INSERT */ - {111, 0x153}, /* DELETE */ + { 96, 0x11c }, /* KPENTER */ + { 97, 0x11d }, /* RIGHTCTRL */ + { 98, 0x135 }, /* KPSLASH */ + { 99, 0x137 }, /* SYSRQ */ + { 183, 0x137 }, /* F13 => SysRq (for Apple keyboards) */ + { 100, 0x138 }, /* RIGHTALT */ + { 119, 0x145 }, /* PAUSE */ + { 411, 0x145 }, /* BREAK */ + { 185, 0x145 }, /* F15 => Pause (for Apple keyboards) */ + { 102, 0x147 }, /* HOME */ + { 103, 0x148 }, /* UP */ + { 104, 0x149 }, /* PAGEUP */ + { 105, 0x14b }, /* LEFT */ + { 106, 0x14d }, /* RIGHT */ + { 107, 0x14f }, /* END */ + { 108, 0x150 }, /* DOWN */ + { 109, 0x151 }, /* PAGEDOWN */ + { 110, 0x152 }, /* INSERT */ + { 111, 0x153 }, /* DELETE */ - {125, 0x15b}, /* LEFTMETA */ - {126, 0x15c}, /* RIGHTMETA */ - {127, 0x15d}, /* COMPOSE => Menu */ + { 125, 0x15b }, /* LEFTMETA */ + { 126, 0x15c }, /* RIGHTMETA */ + { 127, 0x15d }, /* COMPOSE => Menu */ /* Multimedia keys. Guideline is to try and follow the Microsoft standard, then fill in remaining scancodes with OEM-specific keys for redundancy sake. Keys marked with # are not translated into evdev codes by the standard atkbd driver. */ - {634, 0x54}, /* SELECTIVE_SCREENSHOT# => Alt+SysRq */ - {117, 0x59}, /* KPEQUAL */ - {418, 0x6a}, /* ZOOMIN# => Logitech */ - {420, 0x6b}, /* ZOOMRESET# => Logitech */ - {223, 0x6d}, /* CANCEL# => Logitech */ - {132, 0x101}, /* # Logitech Task Select */ - {148, 0x102}, /* PROG1# => Samsung */ - {149, 0x103}, /* PROG2# => Samsung */ - {419, 0x104}, /* ZOOMOUT# => Logitech */ - {144, 0x105}, /* FILE# => Messenger/Files */ - {216, 0x105}, /* CHAT# => Messenger/Files */ - {430, 0x105}, /* MESSENGER# */ - {182, 0x107}, /* REDO# */ - {131, 0x108}, /* UNDO# */ - {135, 0x10a}, /* PASTE# */ - {177, 0x10b}, /* SCROLLUP# => normal speed */ - {165, 0x110}, /* PREVIOUSSONG */ - {136, 0x112}, /* FIND# => Logitech */ - {421, 0x113}, /* WORDPROCESSOR# => Word */ - {423, 0x114}, /* SPREADSHEET# => Excel */ - {397, 0x115}, /* CALENDAR# */ - {433, 0x116}, /* LOGOFF# */ - {137, 0x117}, /* CUT# */ - {133, 0x118}, /* COPY# */ - {163, 0x119}, /* NEXTSONG */ - {154, 0x11e}, /* CYCLEWINDOWS => Application Right (no left counterpart) */ - {113, 0x120}, /* MUTE */ - {140, 0x121}, /* CALC */ - {164, 0x122}, /* PLAYPAUSE */ - {432, 0x123}, /* SPELLCHECK# */ - {166, 0x124}, /* STOPCD */ - {139, 0x126}, /* MENU# => Shortcut/Menu/Help for a few OEMs */ - {114, 0x12e}, /* VOL- */ - {160, 0x12f}, /* CLOSECD# => Logitech Eject */ - {161, 0x12f}, /* EJECTCD# => Logitech */ - {162, 0x12f}, /* EJECTCLOSECD# => Logitech */ - {115, 0x130}, /* VOL+ */ - {150, 0x132}, /* WWW# */ - {172, 0x132}, /* HOMEPAGE */ - {138, 0x13b}, /* HELP# */ - {213, 0x13c}, /* SOUND# => My Music/Office Home */ - {360, 0x13c}, /* VENDOR# => My Music/Office Home */ - {204, 0x13d}, /* DASHBOARD# => Task Pane */ - {181, 0x13e}, /* NEW# */ - {134, 0x13f}, /* OPEN# */ - {206, 0x140}, /* CLOSE# */ - {232, 0x141}, /* REPLY# */ - {233, 0x142}, /* FORWARDMAIL# */ - {231, 0x143}, /* SEND# */ - {151, 0x144}, /* MSDOS# */ - {112, 0x14c}, /* MACRO */ - {179, 0x14c}, /* KPLEFTPAREN# */ - {118, 0x14e}, /* KPPLUSMINUS */ - {235, 0x155}, /* DOCUMENTS# => Logitech */ - {234, 0x157}, /* SAVE# */ - {210, 0x158}, /* PRINT# */ - {116, 0x15e}, /* POWER */ - {142, 0x15f}, /* SLEEP */ - {143, 0x163}, /* WAKEUP */ - {180, 0x164}, /* KPRIGHTPAREN# */ - {212, 0x164}, /* CAMERA# => My Pictures */ - {217, 0x165}, /* SEARCH */ - {156, 0x166}, /* BOOKMARKS => Favorites */ - {364, 0x166}, /* FAVORITES# */ - {173, 0x167}, /* REFRESH */ - {128, 0x168}, /* STOP */ - {159, 0x169}, /* FORWARD */ - {158, 0x16a}, /* BACK */ - {157, 0x16b}, /* COMPUTER */ - {155, 0x16c}, /* MAIL */ - {215, 0x16c}, /* EMAIL# */ - {226, 0x16d}, /* MEDIA */ - {167, 0x178}, /* RECORD# => Logitech */ - {152, 0x17a}, /* COFFEE/SCREENLOCK# */ - {178, 0x18b}, /* SCROLLDOWN# => normal speed */ + { 634, 0x54 }, /* SELECTIVE_SCREENSHOT# => Alt+SysRq */ + { 117, 0x59 }, /* KPEQUAL */ + { 418, 0x6a }, /* ZOOMIN# => Logitech */ + { 420, 0x6b }, /* ZOOMRESET# => Logitech */ + { 223, 0x6d }, /* CANCEL# => Logitech */ + { 132, 0x101 }, /* # Logitech Task Select */ + { 148, 0x102 }, /* PROG1# => Samsung */ + { 149, 0x103 }, /* PROG2# => Samsung */ + { 419, 0x104 }, /* ZOOMOUT# => Logitech */ + { 144, 0x105 }, /* FILE# => Messenger/Files */ + { 216, 0x105 }, /* CHAT# => Messenger/Files */ + { 430, 0x105 }, /* MESSENGER# */ + { 182, 0x107 }, /* REDO# */ + { 131, 0x108 }, /* UNDO# */ + { 135, 0x10a }, /* PASTE# */ + { 177, 0x10b }, /* SCROLLUP# => normal speed */ + { 165, 0x110 }, /* PREVIOUSSONG */ + { 136, 0x112 }, /* FIND# => Logitech */ + { 421, 0x113 }, /* WORDPROCESSOR# => Word */ + { 423, 0x114 }, /* SPREADSHEET# => Excel */ + { 397, 0x115 }, /* CALENDAR# */ + { 433, 0x116 }, /* LOGOFF# */ + { 137, 0x117 }, /* CUT# */ + { 133, 0x118 }, /* COPY# */ + { 163, 0x119 }, /* NEXTSONG */ + { 154, 0x11e }, /* CYCLEWINDOWS => Application Right (no left counterpart) */ + { 113, 0x120 }, /* MUTE */ + { 140, 0x121 }, /* CALC */ + { 164, 0x122 }, /* PLAYPAUSE */ + { 432, 0x123 }, /* SPELLCHECK# */ + { 166, 0x124 }, /* STOPCD */ + { 139, 0x126 }, /* MENU# => Shortcut/Menu/Help for a few OEMs */ + { 114, 0x12e }, /* VOL- */ + { 160, 0x12f }, /* CLOSECD# => Logitech Eject */ + { 161, 0x12f }, /* EJECTCD# => Logitech */ + { 162, 0x12f }, /* EJECTCLOSECD# => Logitech */ + { 115, 0x130 }, /* VOL+ */ + { 150, 0x132 }, /* WWW# */ + { 172, 0x132 }, /* HOMEPAGE */ + { 138, 0x13b }, /* HELP# */ + { 213, 0x13c }, /* SOUND# => My Music/Office Home */ + { 360, 0x13c }, /* VENDOR# => My Music/Office Home */ + { 204, 0x13d }, /* DASHBOARD# => Task Pane */ + { 181, 0x13e }, /* NEW# */ + { 134, 0x13f }, /* OPEN# */ + { 206, 0x140 }, /* CLOSE# */ + { 232, 0x141 }, /* REPLY# */ + { 233, 0x142 }, /* FORWARDMAIL# */ + { 231, 0x143 }, /* SEND# */ + { 151, 0x144 }, /* MSDOS# */ + { 112, 0x14c }, /* MACRO */ + { 179, 0x14c }, /* KPLEFTPAREN# */ + { 118, 0x14e }, /* KPPLUSMINUS */ + { 235, 0x155 }, /* DOCUMENTS# => Logitech */ + { 234, 0x157 }, /* SAVE# */ + { 210, 0x158 }, /* PRINT# */ + { 116, 0x15e }, /* POWER */ + { 142, 0x15f }, /* SLEEP */ + { 143, 0x163 }, /* WAKEUP */ + { 180, 0x164 }, /* KPRIGHTPAREN# */ + { 212, 0x164 }, /* CAMERA# => My Pictures */ + { 217, 0x165 }, /* SEARCH */ + { 156, 0x166 }, /* BOOKMARKS => Favorites */ + { 364, 0x166 }, /* FAVORITES# */ + { 173, 0x167 }, /* REFRESH */ + { 128, 0x168 }, /* STOP */ + { 159, 0x169 }, /* FORWARD */ + { 158, 0x16a }, /* BACK */ + { 157, 0x16b }, /* COMPUTER */ + { 155, 0x16c }, /* MAIL */ + { 215, 0x16c }, /* EMAIL# */ + { 226, 0x16d }, /* MEDIA */ + { 167, 0x178 }, /* RECORD# => Logitech */ + { 152, 0x17a }, /* COFFEE/SCREENLOCK# */ + { 178, 0x18b }, /* SCROLLDOWN# => normal speed */ }; uint16_t diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index 9b6ce93998c..8bedf31f846 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -273,36 +273,6 @@ msgstr "" msgid "&Folder..." msgstr "" -msgid "Target &framerate" -msgstr "" - -msgid "&Sync with video" -msgstr "" - -msgid "&25 fps" -msgstr "" - -msgid "&30 fps" -msgstr "" - -msgid "&50 fps" -msgstr "" - -msgid "&60 fps" -msgstr "" - -msgid "&75 fps" -msgstr "" - -msgid "&VSync" -msgstr "" - -msgid "&Select shader..." -msgstr "" - -msgid "&Remove shader" -msgstr "" - msgid "Preferences" msgstr "" @@ -603,9 +573,6 @@ msgstr "" msgid "ID:" msgstr "" -msgid "&Specify..." -msgstr "" - msgid "Sectors:" msgstr "" @@ -690,9 +657,6 @@ msgstr "" msgid "POST card" msgstr "" -msgid "86Box" -msgstr "" - msgid "Error" msgstr "" @@ -852,9 +816,18 @@ msgstr "" msgid "Invalid PCap device" msgstr "" +msgid "Generic paddle controller(s)" +msgstr "" + +msgid "2-axis, 1-button joystick(s)" +msgstr "" + msgid "2-axis, 2-button joystick(s)" msgstr "" +msgid "2-axis, 3-button joystick" +msgstr "" + msgid "2-axis, 4-button joystick" msgstr "" @@ -867,34 +840,40 @@ msgstr "" msgid "3-axis, 2-button joystick" msgstr "" +msgid "3-axis, 3-button joystick" +msgstr "" + msgid "3-axis, 4-button joystick" msgstr "" -msgid "4-axis, 4-button joystick" +msgid "4-axis, 2-button joystick" msgstr "" -msgid "CH Flightstick Pro" +msgid "4-axis, 3-button joystick" msgstr "" -msgid "CH Flightstick Pro + CH Pedals" +msgid "4-axis, 4-button joystick" msgstr "" -msgid "Microsoft SideWinder Pad" +msgid "2-button gamepad(s)" msgstr "" -msgid "Thrustmaster Flight Control System" +msgid "3-button gamepad" msgstr "" -msgid "Thrustmaster FCS + Rudder Control System" +msgid "4-button gamepad" msgstr "" -msgid "2-button gamepad(s)" +msgid "6-button gamepad" +msgstr "" + +msgid "Gravis PC GamePad" msgstr "" msgid "2-button flight yoke" msgstr "" -msgid "4-button gamepad" +msgid "3-button flight yoke" msgstr "" msgid "4-button flight yoke" @@ -903,10 +882,70 @@ msgstr "" msgid "2-button flight yoke with throttle" msgstr "" +msgid "3-button flight yoke with throttle" +msgstr "" + msgid "4-button flight yoke with throttle" msgstr "" -msgid "Win95 Steering Wheel (3-axis, 4-button)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "" + +msgid "CH Flightstick" +msgstr "" + +msgid "CH Flightstick + CH Pedals" +msgstr "" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "" + +msgid "CH Flightstick Pro" +msgstr "" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "" + +msgid "CH Virtual Pilot" +msgstr "" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "" + +msgid "CH Virtual Pilot Pro" +msgstr "" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "" + +msgid "Microsoft SideWinder Pad" +msgstr "" + +msgid "Thrustmaster Flight Control System" +msgstr "" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "" + +msgid "Thrustmaster Formula T1/T2 without adapter" msgstr "" msgid "None" @@ -978,10 +1017,7 @@ msgstr "" msgid "Save" msgstr "" -msgid "About 86Box" -msgstr "" - -msgid "86Box v" +msgid "About %1" msgstr "" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." @@ -1332,7 +1368,7 @@ msgstr "" msgid "Storage" msgstr "" -msgid "Disk %1: " +msgid "Disk %1:" msgstr "" msgid "No disks" @@ -1746,7 +1782,7 @@ msgstr "" msgid "I Copied It" msgstr "" -msgid "86Box Monitor #" +msgid "86Box Monitor #%1" msgstr "" msgid "No MCA devices." @@ -1782,6 +1818,9 @@ msgstr "" msgid "VDE Socket:" msgstr "" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "" @@ -2157,12 +2196,6 @@ msgstr "" msgid "Surround module" msgstr "" -msgid "CODEC" -msgstr "" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "" - msgid "SB Address" msgstr "" @@ -2178,6 +2211,18 @@ msgstr "" msgid "WSS DMA" msgstr "" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "" @@ -2448,9 +2493,6 @@ msgstr "" msgid "SigmaTel STAC9721T (stereo)" msgstr "" -msgid "Classic" -msgstr "" - msgid "256 KB" msgstr "" @@ -2739,9 +2781,6 @@ msgstr "" msgid "Could not load shader: %1" msgstr "" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "" - msgid "Could not load texture: %1" msgstr "" @@ -2805,6 +2844,9 @@ msgstr "" msgid "Toggle fullscreen" msgstr "" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "" @@ -2988,9 +3030,6 @@ msgstr "" msgid "Color scheme" msgstr "" -msgid "System" -msgstr "" - msgid "Light" msgstr "" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 03103a3e31e..5611694c728 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -214,7 +214,7 @@ msgid "Enable &Discord integration" msgstr "Povolit integraci s &Discordem" msgid "Sound &gain..." -msgstr "&ZesĂ­lenĂ­ zvuku" +msgstr "&ZesĂ­lenĂ­ zvuku..." msgid "Begin trace" msgstr "ZaÄĂ­t trace" @@ -226,10 +226,10 @@ msgid "&Help" msgstr "NĂ¡&povÄ›da" msgid "&Documentation..." -msgstr "&Dokumentace" +msgstr "&Dokumentace..." msgid "&About 86Box..." -msgstr "&O programu 86Box" +msgstr "&O programu 86Box..." msgid "&New image..." msgstr "&NovĂ½ obraz..." @@ -273,36 +273,6 @@ msgstr "NaÄĂ­st znova pÅ™edchozĂ­ obraz" msgid "&Folder..." msgstr "&Složka..." -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" @@ -603,9 +573,6 @@ msgstr "KanĂ¡l:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Zadat..." - msgid "Sectors:" msgstr "Sektory:" @@ -690,9 +657,6 @@ msgstr "ZaÅ™Ă­zenĂ­ ISABugger" msgid "POST card" msgstr "Karta pro kĂ³dy POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Chyba" @@ -852,9 +816,18 @@ msgstr "Nebyla nalezena Å¾Ă¡dnĂ¡ PCap zaÅ™Ă­zenĂ­" msgid "Invalid PCap device" msgstr "NeplatnĂ© PCap zaÅ™Ă­zenĂ­" +msgid "Generic paddle controller(s)" +msgstr "ObecnĂ½ otoÄnĂ½ ovladaÄ" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick s 2 osami a 1 tlaÄĂ­tkem" + msgid "2-axis, 2-button joystick(s)" msgstr "Joystick s 2 osami a 2 tlaÄĂ­tky" +msgid "2-axis, 3-button joystick" +msgstr "Joystick s 2 osami a 3 tlaÄĂ­tky" + msgid "2-axis, 4-button joystick" msgstr "Joystick s 2 osami a 4 tlaÄĂ­tky" @@ -867,35 +840,41 @@ msgstr "Joystick s 2 osami a 8 tlaÄĂ­tky" msgid "3-axis, 2-button joystick" msgstr "Joystick s 3 osami a 2 tlaÄĂ­tky" +msgid "3-axis, 3-button joystick" +msgstr "Joystick s 3 osami a 3 tlaÄĂ­tky" + msgid "3-axis, 4-button joystick" msgstr "Joystick s 3 osami a 4 tlaÄĂ­tky" -msgid "4-axis, 4-button joystick" -msgstr "Joystick s 4 osami a 4 tlaÄĂ­tky" +msgid "4-axis, 2-button joystick" +msgstr "Joystick se 4 osami a 2 tlaÄĂ­tky" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" +msgid "4-axis, 3-button joystick" +msgstr "Joystick se 4 osami a 3 tlaÄĂ­tky" -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "4-axis, 4-button joystick" +msgstr "Joystick se 4 osami a 4 tlaÄĂ­tky" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "2-button gamepad(s)" +msgstr "OvladaÄ s 2 tlaÄĂ­tky" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "3-button gamepad" +msgstr "OvladaÄ s 3 tlaÄĂ­tky" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "4-button gamepad" +msgstr "OvladaÄ se 4 tlaÄĂ­tky" -msgid "2-button gamepad(s)" -msgstr "OvladaÄ se 2 tlaÄĂ­tky" +msgid "6-button gamepad" +msgstr "OvladaÄ se 6 tlaÄĂ­tky" + +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" -msgstr "LeteckĂ½ knipl se 2 tlaÄĂ­tky" +msgstr "LeteckĂ½ knipl s 2 tlaÄĂ­tky" -msgid "4-button gamepad" -msgstr "OvladaÄ se 4 tlaÄĂ­tky" +msgid "3-button flight yoke" +msgstr "LeteckĂ½ knipl s 3 tlaÄĂ­tky" msgid "4-button flight yoke" msgstr "LeteckĂ½ knipl se 4 tlaÄĂ­tky" @@ -903,11 +882,71 @@ msgstr "LeteckĂ½ knipl se 4 tlaÄĂ­tky" msgid "2-button flight yoke with throttle" msgstr "LeteckĂ½ knipl s 2 tlaÄĂ­tky a pĂ¡kou" +msgid "3-button flight yoke with throttle" +msgstr "LeteckĂ½ knipl s 3 tlaÄĂ­tky a pĂ¡kou" + msgid "4-button flight yoke with throttle" -msgstr "LeteckĂ½ knipl s 4 tlaÄĂ­tky a pĂ¡kou" +msgstr "LeteckĂ½ knipl se 4 tlaÄĂ­tky a pĂ¡kou" + +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volant (3 osy, 2 tlaÄĂ­tka)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volant (3 osy, 3 tlaÄĂ­tka)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volant (3 osy, 4 tlaÄĂ­tka)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volant pro Windows 95 (3 osy, 4 tlaÄĂ­tka)" +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 s adaptĂ©rem" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 bez adaptĂ©ru" msgid "None" msgstr "ŽadnĂ©" @@ -978,11 +1017,8 @@ 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 "About %1" +msgstr "O programu %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nS pÅ™edchozĂ­mi pÅ™Ă­spÄ›vky od Sarah Walker, leilei, JohnElliott, greatpsycho a dalÅ¡Ă­ch.\n\nZveÅ™ejnÄ›no pod licencĂ­ GNU General Public License verze 2 nebo novÄ›jÅ¡Ă­. Viz soubor LICENSE pro vĂ­ce informacĂ­." @@ -1186,7 +1222,7 @@ msgid "Directory does not exist" msgstr "AdresĂ¡Å™ neexistuje" msgid "A new directory for the system will be created in the selected directory above" -msgstr "Pro tento systĂ©m bude vytvoÅ™en novĂ½ adresĂ¡Å™ ve vĂ½Å¡e zvolenĂ©m adresĂ¡Å™i." +msgstr "Pro tento systĂ©m bude vytvoÅ™en novĂ½ adresĂ¡Å™ ve vĂ½Å¡e zvolenĂ©m adresĂ¡Å™i" msgid "System location:" msgstr "UmĂ­stÄ›nĂ­ systĂ©mu:" @@ -1240,7 +1276,7 @@ msgid "Virtual machine \"%1\" (%2) will be cloned into:" msgstr "VirtuĂ¡lnĂ­ poÄĂ­taÄ \"%1\" (%2) bude naklonovĂ¡n do:" msgid "Directory %1 already exists" -msgstr "AdresĂ¡Å™ %1 již existuje." +msgstr "AdresĂ¡Å™ %1 již existuje" msgid "You cannot use the following characters in the name: %1" msgstr "V nĂ¡zvu nelze pouÅ¾Ă­t nĂ¡sledujĂ­cĂ­ znaky: %1" @@ -1332,8 +1368,8 @@ msgstr "SystĂ©m" msgid "Storage" msgstr "ĂložiÅ¡tÄ›" -msgid "Disk %1: " -msgstr "Disk %1: " +msgid "Disk %1:" +msgstr "Disk %1:" msgid "No disks" msgstr "Å½Ă¡dnĂ© disky" @@ -1651,7 +1687,7 @@ msgid "Show non-&primary monitors" msgstr "Zobrazit neprimĂ¡rnĂ­ monitory" msgid "Open screenshots &folder..." -msgstr "OtevÅ™Ă­t složku se snĂ­mky obrazovky" +msgstr "OtevÅ™Ă­t složku se snĂ­mky obrazovky..." msgid "Appl&y fullscreen stretch mode when maximized" msgstr "PouÅ¾Ă­t režim roztĂ¡&hnutĂ­ pÅ™i celĂ© obrazovce pro maximalizovanĂ© okno" @@ -1714,7 +1750,7 @@ msgid "Remove" msgstr "Odstranit" msgid "Browse..." -msgstr "Browse..." +msgstr "ProchĂ¡zet..." msgid "Couldn't create OpenGL context." msgstr "NepodaÅ™ilo se vytvoÅ™it kontext OpenGL." @@ -1746,8 +1782,8 @@ msgstr "PÅ™esunul jsem jej" msgid "I Copied It" msgstr "ZkopĂ­roval jsem jej" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box Monitor %1" msgid "No MCA devices." msgstr "Å½Ă¡dnĂ© zaÅ™Ă­zenĂ­ MCA." @@ -1780,7 +1816,10 @@ msgid "Adapter:" msgstr "AdaptĂ©r:" msgid "VDE Socket:" -msgstr "ZĂ¡suvka VDE:" +msgstr "VDE socket:" + +msgid "TAP Bridge Device:" +msgstr "ZaÅ™Ă­zenĂ­ TAP mostu:" msgid "86Box Unit Tester" msgstr "86Box Unit Tester" @@ -2157,12 +2196,6 @@ msgstr "SĂ­la filtru SID" msgid "Surround module" msgstr "Modul Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "VyvolĂ¡t pÅ™eruÅ¡enĂ­ CODEC pÅ™i nastavenĂ­ CODEC (potÅ™ebujĂ­ nÄ›kterĂ© ovladaÄe)" - msgid "SB Address" msgstr "Adresa SB" @@ -2178,6 +2211,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA kanĂ¡l WSS" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "Povolit OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "KlasickĂ©" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "Chyba GLSL" msgid "Could not load shader: %1" msgstr "Nebylo možnĂ© naÄĂ­st shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Je vyžadovĂ¡no OpenGL verze 3.0 nebo vÄ›tÅ¡Ă­. SouÄasnĂ¡ verze GLSL je %1.%2" - msgid "Could not load texture: %1" msgstr "Nebylo možnĂ© naÄĂ­st texturu: %1" @@ -2770,7 +2809,7 @@ msgid "Could not load file %1" msgstr "Nebylo možnĂ© naÄĂ­st soubor %1" msgid "Key Bindings:" -msgstr "NastavenĂ­ klĂ¡ves" +msgstr "NastavenĂ­ klĂ¡ves:" msgid "Action" msgstr "Akce" @@ -2788,7 +2827,7 @@ msgid "Bind Key" msgstr "Nastavit klĂ¡vesu" msgid "Enter key combo:" -msgstr "Zadejte kombinaci klĂ¡ves" +msgstr "Zadejte kombinaci klĂ¡ves:" msgid "Bind conflict" msgstr "Konflikt nastavenĂ­" @@ -2805,6 +2844,9 @@ msgstr "Stisknout Ctrl+Alt+Esc" msgid "Toggle fullscreen" msgstr "PÅ™epnout režim celĂ© obrazovky" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "PoÅ™Ă­dit snĂ­mek obrazovky" @@ -2839,7 +2881,7 @@ msgid "Hub Mode" msgstr "Režim hubu" msgid "Hostname:" -msgstr "HostitelskĂ© jmĂ©no" +msgstr "HostitelskĂ© jmĂ©no:" msgid "ISA RAM:" msgstr "ISA paměť RAM:" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index bdcddfe8ddb..3e23d868263 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: German \n" +"Language: de-DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: de_DE\n" "X-Source-Language: en_US\n" @@ -273,36 +279,6 @@ msgstr "Voriges Abbild neu laden" msgid "&Folder..." msgstr "&Verzeichnis..." -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" @@ -478,7 +454,7 @@ msgid "MIDI In Device:" msgstr "MIDI Eingabegerät:" msgid "MIDI Out:" -msgstr "" +msgstr "MIDI Ausgang:" msgid "Standalone MPU-401" msgstr "Eigenständiges-MPU-401-Gerät" @@ -520,7 +496,7 @@ msgid "LPT4 Device:" msgstr "LPT4-Gerät:" msgid "Internal LPT ECP DMA:" -msgstr "" +msgstr "DMA des ECP des internen Parallelports:" msgid "Serial port 1" msgstr "Serielle Schnittstelle 1" @@ -603,9 +579,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Festlegen..." - msgid "Sectors:" msgstr "Sektoren:" @@ -643,7 +616,7 @@ msgid "MO drives:" msgstr "MO-Laufwerke:" msgid "MO:" -msgstr "" +msgstr "MO:" msgid "Removable disks:" msgstr "Wechseldatenträger:" @@ -690,9 +663,6 @@ msgstr "ISABugger-Gerät" msgid "POST card" msgstr "POST-Code-Karte" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Fehler" @@ -790,7 +760,7 @@ msgid "Hard disks" msgstr "Festplatten" msgid "Disks:" -msgstr "" +msgstr "Festplatten:" msgid "Floppy:" msgstr "Diskette:" @@ -852,9 +822,18 @@ msgstr "Keine PCap-Geräte gefunden" msgid "Invalid PCap device" msgstr "UngĂ¼ltiges PCap-Gerät" +msgid "Generic paddle controller(s)" +msgstr "Generischer Paddel-Controller(s)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-Achsen-, 1-Tasten-Joystick(s)" + msgid "2-axis, 2-button joystick(s)" msgstr "2-Achsen-, 2-Tasten-Joystick(s)" +msgid "2-axis, 3-button joystick" +msgstr "2-Achsen-, 3-Tasten-Joystick" + msgid "2-axis, 4-button joystick" msgstr "2-Achsen-, 4-Tasten-Joystick" @@ -867,35 +846,41 @@ msgstr "2-Achsen-, 8-Tasten-Joystick" msgid "3-axis, 2-button joystick" msgstr "3-Achsen-, 2-Tasten-Joystick" +msgid "3-axis, 3-button joystick" +msgstr "3-Achsen-, 3-Tasten-Joystick" + msgid "3-axis, 4-button joystick" msgstr "3-Achsen-, 4-Tasten-Joystick" +msgid "4-axis, 2-button joystick" +msgstr "4-Achsen-, 2-Tasten-Joystick" + +msgid "4-axis, 3-button joystick" +msgstr "4-Achsen-, 3-Tasten-Joystick" + msgid "4-axis, 4-button joystick" msgstr "4-Achsen-, 4-Tasten-Joystick" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" +msgid "2-button gamepad(s)" +msgstr "2-Tasten-Gamepad(s)" -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedale" +msgid "3-button gamepad" +msgstr "3-Tasten-Gamepad" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "4-button gamepad" +msgstr "4-Tasten-Gamepad" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "6-button gamepad" +msgstr "6-Tasten-Gamepad" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" - -msgid "2-button gamepad(s)" -msgstr "2-Tasten-Gamepad(s)" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2-Tasten-Steuerhorn" -msgid "4-button gamepad" -msgstr "4-Tasten-Gamepad" +msgid "3-button flight yoke" +msgstr "3-Tasten-Steuerhorn" msgid "4-button flight yoke" msgstr "4-Tasten-Steuerhorn" @@ -903,11 +888,71 @@ msgstr "4-Tasten-Steuerhorn" msgid "2-button flight yoke with throttle" msgstr "2-Tasten-Steuerhorn mit Schubregler" +msgid "3-button flight yoke with throttle" +msgstr "3-Tasten-Steuerhorn mit Schubregler" + msgid "4-button flight yoke with throttle" msgstr "4-Tasten-Steuerhorn mit Schubregler" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 Lenkrad (3-Achsen, 4-Tasten)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Lenkrad (3-Achsen, 2-Tasten)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Lenkrad (3-Achsen, 3-Tasten)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Lenkrad (3-Achsen, 4-Tasten)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedale" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedale Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedale" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedale Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedale" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedale Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 mit Adapter" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 ohne Adapter" msgid "None" msgstr "Ohne" @@ -958,7 +1003,7 @@ msgid "&File" msgstr "&Datei" msgid "&New machine..." -msgstr "&Neue Maschine" +msgstr "&Neue Maschine..." msgid "&Check for updates..." msgstr "&Auf Aktualisierungen prĂ¼fen..." @@ -978,11 +1023,8 @@ msgstr "Dies wird zu einem Kaltstart des emulierten Systems fĂ¼hren." msgid "Save" msgstr "Speichern" -msgid "About 86Box" -msgstr "Ăœber 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Ăœber %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne sowie andere.\n\nMit frĂ¼heren Kernbeiträgen von Sarah Walker, 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." @@ -1111,10 +1153,10 @@ msgid "%1 total" msgstr "%1 insgesamt" msgid "VMs: %1" -msgstr "" +msgstr "VMs: %1" msgid "System Directory:" -msgstr "Systemverzeichnis" +msgstr "Systemverzeichnis:" msgid "Choose directory" msgstr "Verzeichnis auswählen" @@ -1144,7 +1186,7 @@ msgid "Introduction" msgstr "Einleitung" msgid "This will help you add a new system to 86Box." -msgstr "Hilft dir ein neues System zu 86Box hinzuzufĂ¼gen" +msgstr "Hilft dir ein neues System zu 86Box hinzuzufĂ¼gen." msgid "New configuration" msgstr "Neue Konfiguration" @@ -1216,19 +1258,19 @@ msgid "Enter the new display name (blank to reset)" msgstr "Gebe den neuen Anzeigenamen ein (leer lassen zum ZurĂ¼cksetzen)" msgid "Change &display name..." -msgstr "&Anzeigename ändern" +msgstr "&Anzeigename ändern..." msgid "Context Menu" msgstr "KontextmenĂ¼" msgid "&Open folder..." -msgstr "&Ordner öffnen" +msgstr "&Ordner öffnen..." msgid "Open p&rinter tray..." msgstr "D&ruckerausgabe öffnen..." msgid "Set &icon..." -msgstr "&Symbol setzen" +msgstr "&Symbol setzen..." msgid "Select an icon" msgstr "Wähle ein Symbol aus" @@ -1282,10 +1324,10 @@ msgid "Some files in the machine's directory were unable to be deleted. Please d msgstr "Eine Dateien im Verzeichnis der Maschine konnten nicht gelöscht werden, bitte lösche diese manuell." msgid "Build" -msgstr "" +msgstr "Build" msgid "Version" -msgstr "" +msgstr "Version" msgid "An update to 86Box is available: %1 %2" msgstr "Eine Aktualisierung fĂ¼r 86Box is verfĂ¼gbar: %1 %2" @@ -1327,22 +1369,22 @@ msgid "Found %1" msgstr "Gefunden %1" msgid "System" -msgstr "" +msgstr "System" msgid "Storage" msgstr "Speicherplatz" -msgid "Disk %1: " -msgstr "" +msgid "Disk %1:" +msgstr "Festplatte %1:" msgid "No disks" msgstr "Keine Disks" msgid "Audio" -msgstr "" +msgstr "Klang" msgid "Audio:" -msgstr "" +msgstr "Klang:" msgid "ACPI shutdown" msgstr "Ăœber ACPI herunterfahren" @@ -1746,8 +1788,8 @@ msgstr "Ich habe es verschoben" msgid "I Copied It" msgstr "Ich habe es kopiert" -msgid "86Box Monitor #" -msgstr "86Box-Monitor #" +msgid "86Box Monitor #%1" +msgstr "86Box-Monitor #%1" msgid "No MCA devices." msgstr "Keine MCA-Geräte." @@ -1782,6 +1824,9 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "VDE Anschluss:" +msgid "TAP Bridge Device:" +msgstr "TAP-BrĂ¼ckengerät:" + msgid "86Box Unit Tester" msgstr "86Box-Gerätetester" @@ -2157,12 +2202,6 @@ msgstr "SID-Filterstärke" msgid "Surround module" msgstr "Surround-Modul" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "CODEC-Interrupt bei CODEC-Einrichtung auslösen (wird von einigen Treibern benötigt)" - msgid "SB Address" msgstr "SB-Adresse" @@ -2178,6 +2217,18 @@ msgstr "WSS-IRQ" msgid "WSS DMA" msgstr "WSS-DMA" +msgid "RTC IRQ" +msgstr "IRQ der RTC" + +msgid "RTC Port Address" +msgstr "Portadresse der RTC" + +msgid "Onboard RTC" +msgstr "Integrierte RTC" + +msgid "Not installed" +msgstr "Nicht installiert" + msgid "Enable OPL" msgstr "OPL einschalten" @@ -2448,9 +2499,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (Stereo)" -msgid "Classic" -msgstr "Klassisch" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2787,6 @@ msgstr "GLSL-Fehler" msgid "Could not load shader: %1" msgstr "Shader konnte nicht geladen werden: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL-Version 3.0 oder höher ist erforderlich. Die aktuelle GLSL-Version ist %1.%2" - msgid "Could not load texture: %1" msgstr "Textur konnte nicht geladen werden: %1" @@ -2805,6 +2850,9 @@ msgstr "Strg+Alt+Esc senden" msgid "Toggle fullscreen" msgstr "Vollbild umschalten" +msgid "Toggle UI in fullscreen" +msgstr "UI im Vollbildmodus umschalten" + msgid "Screenshot" msgstr "Bildschirmaufnahme" @@ -2851,7 +2899,7 @@ msgid "&Wipe NVRAM" msgstr "NVRAM leeren" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "Dadurch werden alle NVRAM-Dateien (und zugehörige Dateien) der virtuellen Maschine im Unterverzeichnis \"nvr\" werden gelöscht. Gegebenenfalls mĂ¼ssen die BIOS-Einstellungen (und möglicherweise auch die Einstellungen anderer Geräte innerhalb der VM) erneut konfiguriert werden. Möchtest du wirklich den gesamten NVRAM-Inhalt der virtuellen Maschine \"%1\" löschen?" +msgstr "Dadurch werden alle NVRAM-Dateien (und zugehörige Dateien) der virtuellen Maschine im Unterverzeichnis \"nvr\" werden gelöscht. Gegebenenfalls mĂ¼ssen die BIOS-Einstellungen (und möglicherweise auch die Einstellungen anderer Geräte innerhalb der VM) erneut konfiguriert werden.\n\nMöchtest du wirklich den gesamten NVRAM-Inhalt der virtuellen Maschine \"%1\" löschen?" msgid "Success" msgstr "Erfolgreich" @@ -2878,7 +2926,7 @@ msgid "Check for updates on startup" msgstr "Beim Programmstart auf Aktualisierungen prĂ¼fen" msgid "Unable to determine release information" -msgstr "Die Veröffentlichungsinformationen können nicht ermittelt werden." +msgstr "Die Veröffentlichungsinformationen können nicht ermittelt werden" msgid "There was an error checking for updates:\n\n%1\n\nPlease try again later." msgstr "Bei der PrĂ¼fung auf Aktualisierungen trat ein Fehler auf:\n\n%1\n\nBitte versuche es später erneut." diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 2bf3f518158..a365d62aa5e 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Spanish \n" +"Language: es-ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: es_ES\n" "X-Source-Language: en_US\n" @@ -273,36 +279,6 @@ msgstr "Recargar imagen previa" msgid "&Folder..." msgstr "&Carpeta..." -msgid "Target &framerate" -msgstr "Objetivo de &tasa de refresco" - -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" @@ -478,7 +454,7 @@ msgid "MIDI In Device:" msgstr "Dispositivo MIDI de entrada:" msgid "MIDI Out:" -msgstr "Salida MIDI" +msgstr "Salida MIDI:" msgid "Standalone MPU-401" msgstr "MPU-401 independiente" @@ -603,9 +579,6 @@ msgstr "Canal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "E&specificar..." - msgid "Sectors:" msgstr "Sectores:" @@ -690,9 +663,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Tarjeta POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Error" @@ -852,9 +822,18 @@ msgstr "No se encontraron dispositivos PCap" msgid "Invalid PCap device" msgstr "Dispositivo PCap invĂ¡lido" +msgid "Generic paddle controller(s)" +msgstr "Controlador(es) de paleta genĂ©rico(s)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Mando(s) de 2 ejes, 1 botones" + msgid "2-axis, 2-button joystick(s)" msgstr "Mando(s) de 2 ejes, 2 botones" +msgid "2-axis, 3-button joystick" +msgstr "Mando de 2 ejes, 3 botones" + msgid "2-axis, 4-button joystick" msgstr "Mando de 2 ejes, 4 botones" @@ -867,35 +846,41 @@ msgstr "Mando de 2 ejes, 8 botones" msgid "3-axis, 2-button joystick" msgstr "Mando de 3 ejes, 2 botones" +msgid "3-axis, 3-button joystick" +msgstr "Mando de 3 ejes, 3 botones" + msgid "3-axis, 4-button joystick" msgstr "Mando de 3 ejes, 4 botones" +msgid "4-axis, 2-button joystick" +msgstr "Mando de 4 ejes, 2 botones" + +msgid "4-axis, 3-button joystick" +msgstr "Mando de 4 ejes, 3 botones" + msgid "4-axis, 4-button joystick" msgstr "Mando de 4 ejes, 4 botones" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "Mando(s) de juegos de 2 botones" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Mando de juegos de 3 botones" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Mando de juegos de 4 botones" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "Mando de juegos de 6 botones" -msgid "2-button gamepad(s)" -msgstr "Mando(s) de juegos de 2 botones" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Yugo de vuelo de 2 botones" -msgid "4-button gamepad" -msgstr "Mando de juegos de 4 botones" +msgid "3-button flight yoke" +msgstr "Yugo de vuelo de 3 botones" msgid "4-button flight yoke" msgstr "Yugo de vuelo de 4 botones" @@ -903,11 +888,71 @@ msgstr "Yugo de vuelo de 4 botones" msgid "2-button flight yoke with throttle" msgstr "Yugo de vuelo de 2 botones con acelerador" +msgid "3-button flight yoke with throttle" +msgstr "Yugo de vuelo de 3 botones con acelerador" + msgid "4-button flight yoke with throttle" msgstr "Yugo de vuelo de 4 botones con acelerador" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volante Win95 (de 3 ejes, 4 botones)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volante (de 3 ejes, 2 botones)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volante (de 3 ejes, 3 botones)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volante (de 3 ejes, 4 botones)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 con adaptador" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 sin adaptador" msgid "None" msgstr "Ninguno" @@ -978,11 +1023,8 @@ msgstr "Se harĂ¡ una reinicializaciĂ³n completa de la mĂ¡quina emulada." msgid "Save" msgstr "Guardar" -msgid "About 86Box" -msgstr "Acerca de 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Acerca de %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, y otros.\n\nCon contribuciones anteriores de Sarah Walker, 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." @@ -1234,7 +1276,7 @@ msgid "Select an icon" msgstr "Escoger un icono" msgid "C&lone..." -msgstr "C&lonar" +msgstr "C&lonar..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" msgstr "La mĂ¡quina virtual \"%1\" (%2) serĂ¡ clonada para:" @@ -1332,8 +1374,8 @@ msgstr "Sistema" msgid "Storage" msgstr "Almacenamiento" -msgid "Disk %1: " -msgstr "Disco" +msgid "Disk %1:" +msgstr "Disco %1:" msgid "No disks" msgstr "Sin disco" @@ -1746,8 +1788,8 @@ msgstr "La he movido" msgid "I Copied It" msgstr "La he copiado" -msgid "86Box Monitor #" -msgstr "Monitor de 86Box " +msgid "86Box Monitor #%1" +msgstr "Monitor de 86Box %1" msgid "No MCA devices." msgstr "No hay dispositovos MCA." @@ -1782,6 +1824,9 @@ msgstr "Adaptador:" msgid "VDE Socket:" msgstr "Toma VDE:" +msgid "TAP Bridge Device:" +msgstr "Dispositivo puente TAP:" + msgid "86Box Unit Tester" msgstr "Comprobador de unidad 86Box" @@ -2157,12 +2202,6 @@ msgstr "Fuerza del filtro de SID" msgid "Surround module" msgstr "MĂ³dulo Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Activar la interrupciĂ³n CODEC en la configuraciĂ³n CODEC (necesario para algunos controladores)" - msgid "SB Address" msgstr "DirecciĂ³n del SB" @@ -2178,6 +2217,18 @@ msgstr "IRQ de WSS" msgid "WSS DMA" msgstr "DMA de WSS" +msgid "RTC IRQ" +msgstr "IRQ RTC" + +msgid "RTC Port Address" +msgstr "DirecciĂ³n puerta RTC" + +msgid "Onboard RTC" +msgstr "RTC integrado" + +msgid "Not installed" +msgstr "No instalado" + msgid "Enable OPL" msgstr "Habilitar OPL" @@ -2317,13 +2368,13 @@ msgid "EMS 2 Address" msgstr "DirecciĂ³n de EMS 2" msgid "EMS Memory Size" -msgstr "DirecciĂ³n de EMS" +msgstr "Tamaño de memoria de EMS" msgid "EMS 1 Memory Size" -msgstr "DirecciĂ³n de EMS 1" +msgstr "Tamaño de memoria de EMS 1" msgid "EMS 2 Memory Size" -msgstr "DirecciĂ³n de EMS 2" +msgstr "Tamaño de memoria de EMS 2" msgid "Enable EMS" msgstr "Habilitar EMS" @@ -2448,9 +2499,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (estĂ©reo)" -msgid "Classic" -msgstr "ClĂ¡sico" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2787,6 @@ msgstr "Error de GLSL" msgid "Could not load shader: %1" msgstr "No fuĂ© posible cargar el shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Se requiere la versiĂ³n 3.0 o superior de OpenGL. La versiĂ³n actual de GLSL es %1.%2" - msgid "Could not load texture: %1" msgstr "Error al cargar la textura: %1" @@ -2805,6 +2850,9 @@ msgstr "Enviar Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Alternar pantalla completa" +msgid "Toggle UI in fullscreen" +msgstr "Alternar interfaz de usuario en modo de pantalla completa" + msgid "Screenshot" msgstr "Captura de pantalla" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 24102f07133..ce6d6bab449 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -273,36 +273,6 @@ msgstr "Lataa edellinen levykuva uudelleen" msgid "&Folder..." msgstr "&Kansio..." -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" @@ -603,9 +573,6 @@ msgstr "Kanava:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Määritä..." - msgid "Sectors:" msgstr "Sektorit:" @@ -690,9 +657,6 @@ msgstr "ISABugger-laite" msgid "POST card" msgstr "POST-kortti" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Virhe" @@ -852,9 +816,18 @@ msgstr "PCap-laitteita ei löytynyt" msgid "Invalid PCap device" msgstr "Virheellinen PCap-laite" +msgid "Generic paddle controller(s)" +msgstr "Yleinen melainohjain" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-akseliset 1-painikkeiset peliohjaimet" + msgid "2-axis, 2-button joystick(s)" msgstr "2-akseliset 2-painikkeiset peliohjaimet" +msgid "2-axis, 3-button joystick" +msgstr "2-akselinen 3-painikkeinen peliohjain" + msgid "2-axis, 4-button joystick" msgstr "2-akselinen 4-painikkeinen peliohjain" @@ -867,35 +840,41 @@ msgstr "2-akselinen 8-painikkeinen peliohjain" msgid "3-axis, 2-button joystick" msgstr "3-akselinen 2-painikkeinen peliohjain" +msgid "3-axis, 3-button joystick" +msgstr "3-akselinen 3-painikkeinen peliohjain" + msgid "3-axis, 4-button joystick" msgstr "3-akselinen 4-painikkeinen peliohjain" +msgid "4-axis, 2-button joystick" +msgstr "4-akselinen 2-painikkeinen peliohjain" + +msgid "4-axis, 3-button joystick" +msgstr "4-akselinen 3-painikkeinen peliohjain" + msgid "4-axis, 4-button joystick" msgstr "4-akselinen 4-painikkeinen peliohjain" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "" +msgid "2-button gamepad(s)" +msgstr "2-painikkeiset peliohjaimet" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3-painikkeinen peliohjain" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4-painikkeinen peliohjain" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "" +msgid "6-button gamepad" +msgstr "6-painikkeinen peliohjain" -msgid "2-button gamepad(s)" -msgstr "2-painikkeiset peliohjaimet" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2-painikkeinen lento-ohjain" -msgid "4-button gamepad" -msgstr "4-painikkeinen peliohjain" +msgid "3-button flight yoke" +msgstr "3-painikkeinen lento-ohjain" msgid "4-button flight yoke" msgstr "4-painikkeinen lento-ohjain" @@ -903,11 +882,71 @@ msgstr "4-painikkeinen lento-ohjain" msgid "2-button flight yoke with throttle" msgstr "2-painikkeinen lento-ohjain kaasuvivulla" +msgid "3-button flight yoke with throttle" +msgstr "3-painikkeinen lento-ohjain kaasuvivulla" + msgid "4-button flight yoke with throttle" msgstr "4-painikkeinen lento-ohjain kaasuvivulla" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95-ratti (3-akselinen, 4-painikkeinen)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "ratti (3-akselinen, 2-painikkeinen)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "ratti (3-akselinen, 3-painikkeinen)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "ratti (3-akselinen, 4-painikkeinen)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 adapterilla" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 ilman adapteria" msgid "None" msgstr "Ei mikään" @@ -978,11 +1017,8 @@ 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 "About %1" +msgstr "Tietoja %1:sta" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ja muut.\n\nSisältää Sarah Walkerin, leilein, JohnElliottin, greatpsychon ja muiden aiemmat keskeiset työpanokset.\n\nJulkaistu GNU General Public License 2. version tai myöhemmän alaisena. Tarkempia tietoja LICENSE-tiedostossa." @@ -1192,7 +1228,7 @@ msgid "System location:" msgstr "Koneen sijainti:" msgid "System name and location" -msgstr "Koneen nimi ja sijainti:" +msgstr "Koneen nimi ja sijainti" msgid "Enter the name of the system and choose the location" msgstr "Anna koneen nimi ja valitse sijainti" @@ -1216,7 +1252,7 @@ msgid "Enter the new display name (blank to reset)" msgstr "Anna uusi näyttönimi tai poista se" msgid "Change &display name..." -msgstr "Vaihda &näyttönimi" +msgstr "Vaihda &näyttönimi..." msgid "Context Menu" msgstr "Kontekstivalikko" @@ -1332,8 +1368,8 @@ msgstr "Järjestelmä" msgid "Storage" msgstr "Tallennus" -msgid "Disk %1: " -msgstr "Levy %1: " +msgid "Disk %1:" +msgstr "Levy %1:" msgid "No disks" msgstr "Ei levyjä" @@ -1384,7 +1420,7 @@ msgid "Unable to write file" msgstr "Tiedostoa ei voitu 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" +msgstr "HDI- ja HDX-levykuvien ainoa tuettu sektorikoko on 512." msgid "Disk image file already exists" msgstr "Levykuva on jo olemassa" @@ -1396,7 +1432,7 @@ msgid "Disk image created" msgstr "Levykuva luotu" msgid "Make sure the file exists and is readable." -msgstr "Varmista, että tiedosto on olemassa ja lukukelpoinen" +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 pystyy kirjoittamaan." @@ -1746,8 +1782,8 @@ msgstr "Siirsin sen" msgid "I Copied It" msgstr "Kopioin sen" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box Monitor %1" msgid "No MCA devices." msgstr "Ei MCA-laitteita." @@ -1782,6 +1818,9 @@ msgstr "Sovitin:" msgid "VDE Socket:" msgstr "VDE-socket:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "86Box Unit Tester" @@ -2157,12 +2196,6 @@ msgstr "SID-filtterin vahvuus" msgid "Surround module" msgstr "Surround-moduuli" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "CODEC-keskeytys CODEC-asennuksen yhteydessä (jotkut ohjaimet tarvitsevat sitä)" - msgid "SB Address" msgstr "SB-osoite" @@ -2178,6 +2211,18 @@ msgstr "WSS-IRQ" msgid "WSS DMA" msgstr "WSS-DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "OPL" @@ -2448,9 +2493,6 @@ msgstr "24 Mt" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klassinen" - msgid "256 KB" msgstr "256 Kt" @@ -2739,9 +2781,6 @@ msgstr "GLSL-virhe" msgid "Could not load shader: %1" msgstr "Varjostinta %1 ei voitu ladata" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Vähintään OpenGL-versio 3.0 vaaditaan. Tämänhetkinen GLSL-versio on %1.%2" - msgid "Could not load texture: %1" msgstr "Tekstuuria ei voitu ladata: %1" @@ -2805,6 +2844,9 @@ msgstr "Lähetä Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Koko näyttö" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Kuvakaappaus" @@ -2908,7 +2950,7 @@ msgid "Version %1 is now available." msgstr "Versio %1 on nyt saatavilla." msgid "You are currently running build %1." -msgstr "Käytät käännöstä %1" +msgstr "Käytät käännöstä %1." msgid "Build %1 is now available." msgstr "Käännös %1 on nyt saatavilla." diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c98280f3b19..d51553ba6f8 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: French \n" +"Language: fr-FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: fr_FR\n" "X-Source-Language: en_US\n" @@ -273,36 +279,6 @@ msgstr "Recharger image prĂ©cedente" msgid "&Folder..." msgstr "&Dossier..." -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" @@ -328,64 +304,64 @@ msgid "&Default" msgstr "&DĂ©faut" msgid "Language:" -msgstr "Langue:" +msgstr "Langue :" msgid "Gain" msgstr "Gain" msgid "File name:" -msgstr "Nom fichier:" +msgstr "Nom fichier :" msgid "Disk size:" -msgstr "Taille disque:" +msgstr "Taille disque :" msgid "RPM mode:" -msgstr "Mode RPM:" +msgstr "Mode RPM :" msgid "Progress:" -msgstr "Progression:" +msgstr "Progression :" msgid "Width:" -msgstr "Largeur:" +msgstr "Largeur :" msgid "Height:" -msgstr "Hauteur:" +msgstr "Hauteur :" msgid "Lock to this size" msgstr "Verrouiller Ă  cette taille" msgid "Machine type:" -msgstr "Type de machine:" +msgstr "Type de machine :" msgid "Machine:" -msgstr "Machine:" +msgstr "Machine :" msgid "Configure" msgstr "Configurer" msgid "CPU:" -msgstr "Processeur:" +msgstr "Processeur :" msgid "CPU type:" -msgstr "Type de processeur:" +msgstr "Type de processeur :" msgid "Speed:" -msgstr "Vitesse:" +msgstr "Vitesse :" msgid "Frequency:" -msgstr "FrĂ©quence:" +msgstr "FrĂ©quence :" msgid "FPU:" -msgstr "FPU:" +msgstr "FPU :" msgid "Wait states:" -msgstr "États d'attente:" +msgstr "États d'attente :" msgid "MB" msgstr "Mo" msgid "Memory:" -msgstr "MĂ©moire:" +msgstr "MĂ©moire :" msgid "Time synchronization" msgstr "Synchronisation du temps" @@ -412,10 +388,10 @@ msgid "Smaller frames (smoother)" msgstr "Blocs plus petits (plus fluide)" msgid "Video:" -msgstr "VidĂ©o:" +msgstr "VidĂ©o :" msgid "Video #2:" -msgstr "VidĂ©o 2:" +msgstr "VidĂ©o 2 :" msgid "Voodoo 1 or 2 Graphics" msgstr "Graphique Voodoo 1 ou 2" @@ -430,22 +406,22 @@ msgid "IBM PS/55 Display Adapter Graphics" msgstr "Graphique du adaptateur IBM PS/55" msgid "Keyboard:" -msgstr "Clavier:" +msgstr "Clavier :" msgid "Keyboard" msgstr "Clavier" msgid "Mouse:" -msgstr "Souris:" +msgstr "Souris :" msgid "Mouse" msgstr "Souris" msgid "Joystick:" -msgstr "Manette:" +msgstr "Manette :" msgid "Joystick" -msgstr "Joystick" +msgstr "Manette" msgid "Joystick 1..." msgstr "Manette 1..." @@ -460,25 +436,25 @@ msgid "Joystick 4..." msgstr "Manette 4..." msgid "Sound card #1:" -msgstr "Carte son 1:" +msgstr "Carte son 1 :" msgid "Sound card #2:" -msgstr "Carte son 2:" +msgstr "Carte son 2 :" msgid "Sound card #3:" -msgstr "Carte son 3:" +msgstr "Carte son 3 :" msgid "Sound card #4:" -msgstr "Carte son 4:" +msgstr "Carte son 4 :" msgid "MIDI Out Device:" -msgstr "Sortie MIDI:" +msgstr "Sortie MIDI :" msgid "MIDI In Device:" -msgstr "EntrĂ©e MIDI:" +msgstr "EntrĂ©e MIDI :" msgid "MIDI Out:" -msgstr "Sortie MIDI:" +msgstr "Sortie MIDI :" msgid "Standalone MPU-401" msgstr "MPU-401 autonome" @@ -496,31 +472,31 @@ msgid "YMFM (faster)" msgstr "YMFM (plus rapide)" msgid "COM1 Device:" -msgstr "Dispositif COM1:" +msgstr "Dispositif COM1 :" msgid "COM2 Device:" -msgstr "Dispositif COM2:" +msgstr "Dispositif COM2 :" msgid "COM3 Device:" -msgstr "Dispositif COM3:" +msgstr "Dispositif COM3 :" msgid "COM4 Device:" -msgstr "Dispositif COM4:" +msgstr "Dispositif COM4 :" msgid "LPT1 Device:" -msgstr "Dispositif LPT1:" +msgstr "Dispositif LPT1 :" msgid "LPT2 Device:" -msgstr "Dispositif LPT2:" +msgstr "Dispositif LPT2 :" msgid "LPT3 Device:" -msgstr "Dispositif LPT3:" +msgstr "Dispositif LPT3 :" msgid "LPT4 Device:" -msgstr "Dispositif LPT4:" +msgstr "Dispositif LPT4 :" msgid "Internal LPT ECP DMA:" -msgstr "DMA de l'ECP du LPT interne:" +msgstr "DMA de l'ECP du LPT interne :" msgid "Serial port 1" msgstr "Port sĂ©rie 1" @@ -547,10 +523,10 @@ msgid "Parallel port 4" msgstr "Port parallèle 4" msgid "FD Controller:" -msgstr "ContrĂ´leur FD:" +msgstr "ContrĂ´leur FD :" msgid "CD-ROM Controller:" -msgstr "ContrĂ´leur CD-ROM:" +msgstr "ContrĂ´leur CD-ROM :" msgid "Tertiary IDE Controller" msgstr "Troisième contrĂ´leur IDE" @@ -565,22 +541,22 @@ msgid "SCSI" msgstr "SCSI" msgid "Controller 1:" -msgstr "ContrĂ´leur 1:" +msgstr "ContrĂ´leur 1 :" msgid "Controller 2:" -msgstr "ContrĂ´leur 2:" +msgstr "ContrĂ´leur 2 :" msgid "Controller 3:" -msgstr "ContrĂ´leur 3:" +msgstr "ContrĂ´leur 3 :" msgid "Controller 4:" -msgstr "ContrĂ´leur 4:" +msgstr "ContrĂ´leur 4 :" msgid "Cassette" msgstr "Cassette" msgid "Hard disks:" -msgstr "Disques durs:" +msgstr "Disques durs :" msgid "Firmware Version" msgstr "Version du micrologiciel" @@ -595,40 +571,37 @@ msgid "&Remove" msgstr "&Supprimer" msgid "Bus:" -msgstr "Bus:" +msgstr "Bus :" msgid "Channel:" -msgstr "Canal:" +msgstr "Canal :" msgid "ID:" -msgstr "ID:" - -msgid "&Specify..." -msgstr "&SpĂ©cifier..." +msgstr "ID :" msgid "Sectors:" -msgstr "Secteurs:" +msgstr "Secteurs :" msgid "Heads:" -msgstr "TĂªtes:" +msgstr "TĂªtes :" msgid "Cylinders:" -msgstr "Cylindres:" +msgstr "Cylindres :" msgid "Size (MB):" -msgstr "Taille (Mo):" +msgstr "Taille (Mo) :" msgid "Type:" -msgstr "Type:" +msgstr "Type :" msgid "Image Format:" -msgstr "Format Image:" +msgstr "Format Image :" msgid "Block Size:" -msgstr "Taille du bloc:" +msgstr "Taille du bloc :" msgid "Floppy drives:" -msgstr "Lecteurs de disquettes:" +msgstr "Lecteurs de disquettes :" msgid "Turbo timings" msgstr "Turbo" @@ -637,25 +610,25 @@ msgid "Check BPB" msgstr "VĂ©rifier BPB" msgid "CD-ROM drives:" -msgstr "Lecteurs CD-ROM:" +msgstr "Lecteurs CD-ROM :" msgid "MO drives:" -msgstr "Lecteurs magnĂ©to-optiques:" +msgstr "Lecteurs magnĂ©to-optiques :" msgid "MO:" -msgstr "MagnĂ©to-optiques:" +msgstr "MagnĂ©to-optiques :" msgid "Removable disks:" -msgstr "Disques amovibles:" +msgstr "Disques amovibles :" msgid "Removable disk drives:" -msgstr "Lecteurs de disques amovibles:" +msgstr "Lecteurs de disques amovibles :" msgid "ZIP 250" msgstr "ZIP 250" msgid "ISA RTC:" -msgstr "Horloge temps rĂ©el ISA:" +msgstr "Horloge temps rĂ©el ISA :" msgid "ISA Memory Expansion" msgstr "Extension de la mĂ©moire ISA" @@ -664,16 +637,16 @@ msgid "ISA ROM Cards" msgstr "Cartes ROM ISA" msgid "Card 1:" -msgstr "Carte 1:" +msgstr "Carte 1 :" msgid "Card 2:" -msgstr "Carte 2:" +msgstr "Carte 2 :" msgid "Card 3:" -msgstr "Carte 3:" +msgstr "Carte 3 :" msgid "Card 4:" -msgstr "Carte 4:" +msgstr "Carte 4 :" msgid "Generic ISA ROM Board" msgstr "Carte ROM ISA gĂ©nĂ©rique" @@ -690,9 +663,6 @@ msgstr "Dispositif ISABugger" msgid "POST card" msgstr "Carte POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Erreur" @@ -706,10 +676,10 @@ msgid "Speed" msgstr "Vitesse" msgid "Removable disk %1 (%2): %3" -msgstr "Disque amovible %1 (%2): %3" +msgstr "Disque amovible %1 (%2) : %3" msgid "&Removable disk %1 (%2): %3" -msgstr "&Disque amovible %1 (%2): %3" +msgstr "&Disque amovible %1 (%2) : %3" msgid "Removable disk images" msgstr "Imges de disque amovible" @@ -718,7 +688,7 @@ msgid "Image %1" msgstr "Image %1" 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\"." +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)" @@ -745,16 +715,16 @@ 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." +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." +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 "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "La carte vidĂ©o 2 \"%hs\" n'est pas disponible en raison de l'absence de ROMs dans le rĂ©pertoire roms/video. DĂ©sactiver la deuxième carte vidĂ©o." +msgstr "La carte vidĂ©o 2 « %hs » n'est pas disponible en raison de l'absence de ROMs dans le rĂ©pertoire roms/video. DĂ©sactiver la deuxième carte vidĂ©o." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "Le dispositif \"%hs\" n'est pas disponible en raison de l'absence de ROMs. Ignorer le dispositif." +msgstr "Le dispositif « %hs » n'est pas disponible en raison de l'absence de ROMs. Ignorer le dispositif." msgid "Machine" msgstr "Machine" @@ -778,10 +748,10 @@ msgid "Ports" msgstr "Ports" msgid "Serial ports:" -msgstr "Ports sĂ©rie:" +msgstr "Ports sĂ©rie :" msgid "Parallel ports:" -msgstr "Ports parallèles:" +msgstr "Ports parallèles :" msgid "Storage controllers" msgstr "ContrĂ´leurs de stockage" @@ -790,13 +760,13 @@ msgid "Hard disks" msgstr "Disques durs" msgid "Disks:" -msgstr "Disques:" +msgstr "Disques :" msgid "Floppy:" -msgstr "Disquettes:" +msgstr "Disquettes :" msgid "Controllers:" -msgstr "ContrĂ´leurs:" +msgstr "ContrĂ´leurs :" msgid "Floppy & CD-ROM drives" msgstr "Lecteurs de disquette et CD-ROM" @@ -852,9 +822,18 @@ msgstr "Aucun dispositif PCap trouvĂ©" msgid "Invalid PCap device" msgstr "Dispositif PCap invalide" +msgid "Generic paddle controller(s)" +msgstr "ContrĂ´leur(s) Ă  palette gĂ©nĂ©rique(s)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Manette(s) avec 2 axes, 1 boutons" + msgid "2-axis, 2-button joystick(s)" msgstr "Manette(s) avec 2 axes, 2 boutons" +msgid "2-axis, 3-button joystick" +msgstr "Manette avec 2 axes, 4 boutons" + msgid "2-axis, 4-button joystick" msgstr "Manette avec 2 axes, 4 boutons" @@ -867,35 +846,41 @@ msgstr "Manette avec 2 axes, 8 boutons" msgid "3-axis, 2-button joystick" msgstr "Manette avec 3 axes, 2 boutons" +msgid "3-axis, 3-button joystick" +msgstr "Manette avec 3 axes, 3 boutons" + msgid "3-axis, 4-button joystick" msgstr "Manette avec 3 axes, 4 boutons" +msgid "4-axis, 2-button joystick" +msgstr "Manette avec 4 axes, 2 boutons" + +msgid "4-axis, 3-button joystick" +msgstr "Manette avec 4 axes, 3 boutons" + msgid "4-axis, 4-button joystick" msgstr "Manette avec 4 axes, 4 boutons" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "Manette(s) de jeu Ă  2 boutons" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Manette de jeu Ă  2 boutons" -msgid "Thrustmaster Flight Control System" -msgstr "Système de contrĂ´le de vol Thrustmaster" +msgid "4-button gamepad" +msgstr "Manette de jeu Ă  4 boutons" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "SCV Thrustmaster + Système de commande de gouvernail" +msgid "6-button gamepad" +msgstr "Manette de jeu Ă  6 boutons" -msgid "2-button gamepad(s)" -msgstr "Manette(s) de jeu Ă  2 boutons" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Manette de vol Ă  2 boutons" -msgid "4-button gamepad" -msgstr "Manette de jeu Ă  2 boutons" +msgid "3-button flight yoke" +msgstr "Manette de vol Ă  3 boutons" msgid "4-button flight yoke" msgstr "Manette de vol Ă  4 boutons" @@ -903,23 +888,83 @@ msgstr "Manette de vol Ă  4 boutons" msgid "2-button flight yoke with throttle" msgstr "Manette de vol Ă  2 boutons avec manette des gaz" +msgid "3-button flight yoke with throttle" +msgstr "Manette de vol Ă  3 boutons avec manette des gaz" + msgid "4-button flight yoke with throttle" msgstr "Manette de vol Ă  4 boutons avec manette des gaz" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volant Win95 (3 axes, 4 boutons)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volant (3 axes, 2 boutons)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volant (3 axes, 3 boutons)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volant (3 axes, 4 boutons)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Système de contrĂ´le de vol Thrustmaster" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "SCV Thrustmaster + Système de commande de gouvernail" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 avec adaptateur" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 sans adaptateur" msgid "None" msgstr "Aucun" msgid "%1 MB (CHS: %2, %3, %4)" -msgstr "%1 Mo (CTS: %2, %3, %4)" +msgstr "%1 Mo (CTS : %2, %3, %4)" msgid "Floppy %1 (%2): %3" -msgstr "Disquette %1 (%2): %3" +msgstr "Disquette %1 (%2) : %3" msgid "&Floppy %1 (%2): %3" -msgstr "&Disquette %1 (%2): %3" +msgstr "&Disquette %1 (%2) : %3" msgid "Advanced sector images" msgstr "Images secteur avancĂ©" @@ -928,10 +973,10 @@ msgid "Flux images" msgstr "Images Flux" 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 ?" +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?" +msgstr "Etes-vous sĂ»r de vouloir quitter 86Box ?" msgid "Unable to initialize Ghostscript" msgstr "Impossible d'initialiser Ghostscript" @@ -940,16 +985,16 @@ msgid "Unable to initialize GhostPCL" msgstr "Impossible d'initialiser GhostPCL" msgid "MO %1 (%2): %3" -msgstr "MagnĂ©to-optique %1 (%2): %3" +msgstr "MagnĂ©to-optique %1 (%2) : %3" msgid "&MO %1 (%2): %3" -msgstr "&MagnĂ©to-optique %1 (%2): %3" +msgstr "&MagnĂ©to-optique %1 (%2) : %3" msgid "MO images" msgstr "Images magnĂ©to-optiques" msgid "Welcome to 86Box!" -msgstr "Bienvenue dans 86Box !" +msgstr "Bienvenue dans 86Box !" msgid "Internal device" msgstr "Dispositif interne" @@ -970,7 +1015,7 @@ 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 ?" +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." @@ -978,14 +1023,11 @@ 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 "About %1" +msgstr "Ă€ propos de %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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 d'ordinateurs du passĂ©\n\nAuteurs: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nAvec les contributions de Sarah Walker, leilei, JohnElliott, greatpsycho et d'autres.\n\nLibĂ©rĂ© sous la licence GNU General Public License version 2 ou ultĂ©rieure. Pour plus d'informations, voir le fichier LICENSE." +msgstr "Un Ă©mulateur d'ordinateurs du passĂ©\n\nAuteurs : Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nAvec les contributions de Sarah Walker, leilei, JohnElliott, greatpsycho et d'autres.\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" @@ -1036,19 +1078,19 @@ msgid "Continue" msgstr "Continuer" msgid "Cassette: %1" -msgstr "Cassette: %1" +msgstr "Cassette : %1" msgid "C&assette: %1" -msgstr "C&assette: %1" +msgstr "C&assette : %1" msgid "Cassette images" msgstr "Images cassette" msgid "Cartridge %1: %2" -msgstr "Cartouche %1: %2" +msgstr "Cartouche %1 : %2" msgid "Car&tridge %1: %2" -msgstr "Car&touche %1: %2" +msgstr "Car&touche %1 : %2" msgid "Cartridge images" msgstr "Images cartouche" @@ -1111,10 +1153,10 @@ msgid "%1 total" msgstr "%1 total" msgid "VMs: %1" -msgstr "Machines virtuelles: %1" +msgstr "Machines virtuelles : %1" msgid "System Directory:" -msgstr "RĂ©pertoire du système:" +msgstr "RĂ©pertoire du système :" msgid "Choose directory" msgstr "SĂ©lectionner le rĂ©pertoire" @@ -1129,13 +1171,13 @@ msgid "Configuration read failed" msgstr "Échec de la lecture de la configuration" msgid "Unable to open the selected configuration file for reading: %1" -msgstr "Impossible d'ouvrir le fichier de configuration sĂ©lectionnĂ© pour lecture : %1" +msgstr "Impossible d'ouvrir le fichier de configuration sĂ©lectionnĂ© pour lecture : %1" msgid "Use regular expressions in search box" msgstr "Utilisez des expressions rĂ©gulières dans le champ de recherche" msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?" -msgstr "%1 machine(s) sont actuellement actives. Ătes-vous sĂ»r de vouloir quitter le gestionnaire de machines virtuelles malgrĂ© tout ?" +msgstr "%1 machine(s) sont actuellement actives. Ătes-vous sĂ»r de vouloir quitter le gestionnaire de machines virtuelles malgrĂ© tout ?" msgid "Add new system wizard" msgstr "Assistant pour ajouter un nouveau système" @@ -1171,7 +1213,7 @@ msgid "System name" msgstr "Nom du système" msgid "System name:" -msgstr "Nom du système:" +msgstr "Nom du système :" msgid "System name cannot contain certain characters" msgstr "Le nom du système ne peut pas contenir certains caractères" @@ -1189,7 +1231,7 @@ msgid "A new directory for the system will be created in the selected directory msgstr "Un nouveau rĂ©pertoire pour le système sera créé dans le rĂ©pertoire sĂ©lectionnĂ© ci-dessus" msgid "System location:" -msgstr "Emplacement du système:" +msgstr "Emplacement du système :" msgid "System name and location" msgstr "Nom et emplacement du système" @@ -1204,10 +1246,10 @@ msgid "Please enter a system name" msgstr "Veuillez entrer un nom de système" msgid "Display name (optional):" -msgstr "Nom d'affichage (facultatif):" +msgstr "Nom d'affichage (facultatif) :" msgid "Display name:" -msgstr "Nom d'affichage:" +msgstr "Nom d'affichage :" msgid "Set display name" msgstr "DĂ©finir le nom d'affichage" @@ -1237,13 +1279,13 @@ msgid "C&lone..." msgstr "C&loner..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" -msgstr "La machine virtuelle \"%1\" (%2) sera clonĂ©e dans :" +msgstr "La machine virtuelle « %1 » (%2) sera clonĂ©e dans :" msgid "Directory %1 already exists" msgstr "Le rĂ©pertoire %1 existe dĂ©jĂ " msgid "You cannot use the following characters in the name: %1" -msgstr "Vous ne pouvez pas utiliser les caractères suivants dans le nom : %1" +msgstr "Vous ne pouvez pas utiliser les caractères suivants dans le nom : %1" msgid "Clone" msgstr "Cloner" @@ -1288,13 +1330,13 @@ msgid "Version" msgstr "Version" msgid "An update to 86Box is available: %1 %2" -msgstr "Une mise Ă  jour de 86Box est disponible : %1 %2" +msgstr "Une mise Ă  jour de 86Box est disponible : %1 %2" msgid "An error has occurred while checking for updates: %1" -msgstr "Une erreur s'est produite lors de la vĂ©rification des mises Ă  jour : %1" +msgstr "Une erreur s'est produite lors de la vĂ©rification des mises Ă  jour : %1" msgid "An update to 86Box is available!" -msgstr "Une mise Ă  jour de 86Box est disponible !" +msgstr "Une mise Ă  jour de 86Box est disponible !" msgid "Warning" msgstr "Avertissement" @@ -1303,13 +1345,13 @@ msgid "&Kill" msgstr "Fo&rcer Extinction" msgid "Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?" -msgstr "La fermeture forcĂ©e d'une machine virtuelle peut entraĂ®ner une perte de donnĂ©es. Ne procĂ©dez ainsi que si le processus 86Box est bloquĂ©.\n\nVoulez-vous vraiment fermer la machine virtuelle \"%1\" ?" +msgstr "La fermeture forcĂ©e d'une machine virtuelle peut entraĂ®ner une perte de donnĂ©es. Ne procĂ©dez ainsi que si le processus 86Box est bloquĂ©.\n\nVoulez-vous vraiment fermer la machine virtuelle « %1 » ?" msgid "&Delete" msgstr "&Supprimer" msgid "Do you really want to delete the virtual machine \"%1\" and all its files? This action cannot be undone!" -msgstr "Voulez-vous vraiment supprimer la machine virtuelle \"%1\" et tous ses fichiers ? Cette action ne peut pas Ăªtre annulĂ©e !" +msgstr "Voulez-vous vraiment supprimer la machine virtuelle « %1 » et tous ses fichiers ? Cette action ne peut pas Ăªtre annulĂ©e !" msgid "Show &config file" msgstr "Afficher le fichier de &configuration" @@ -1332,8 +1374,8 @@ msgstr "Système" msgid "Storage" msgstr "Stockage" -msgid "Disk %1: " -msgstr "Disque %1: " +msgid "Disk %1:" +msgstr "Disque %1 :" msgid "No disks" msgstr "Pas de disques" @@ -1342,7 +1384,7 @@ msgid "Audio" msgstr "Audio" msgid "Audio:" -msgstr "Audio:" +msgstr "Audio :" msgid "ACPI shutdown" msgstr "ArrĂªt ACPI" @@ -1408,7 +1450,7 @@ 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 ?" +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" @@ -1471,7 +1513,7 @@ 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 ai Ă©tĂ© modifiĂ©e après la crĂ©ation de l'image diffĂ©rentielle.\n\nIl est mĂªme possible que les fichiers de l’image ont Ă©tĂ© dĂ©placĂ©s ou copiĂ©s ou il existe un bogue dans le programme qui a créé ce disque.\n\nVoulez-vous rĂ©parer l'horodatage ?" +msgstr "Il est possible que l'image parente ai Ă©tĂ© modifiĂ©e après la crĂ©ation de l'image diffĂ©rentielle.\n\nIl est mĂªme possible que les fichiers de l’image ont Ă©tĂ© dĂ©placĂ©s ou copiĂ©s ou il existe un bogue dans le programme qui 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 parents et enfants ne correspondent pas" @@ -1495,10 +1537,10 @@ msgid "ATAPI" msgstr "ATAPI" msgid "CD-ROM %1 (%2): %3" -msgstr "CD-ROM %1 (%2): %3" +msgstr "CD-ROM %1 (%2) : %3" msgid "&CD-ROM %1 (%2): %3" -msgstr "&CD-ROM %1 (%2): %3" +msgstr "&CD-ROM %1 (%2) : %3" msgid "160 KB" msgstr "160 Ko" @@ -1591,13 +1633,13 @@ msgid "The network configuration will be switched to the null driver" msgstr "La configuration du rĂ©seau passera au pilote NULL" msgid "Mouse sensitivity:" -msgstr "SensibilitĂ© de la souris:" +msgstr "SensibilitĂ© de la souris :" msgid "Select media images from program working directory" msgstr "SĂ©lectionner des images dans le rĂ©pertoire de travail du programme" msgid "PIT mode:" -msgstr "Mode PIT:" +msgstr "Mode PIT :" msgid "Auto" msgstr "Auto" @@ -1636,7 +1678,7 @@ msgid "MCA devices" msgstr "Dispositifs MCA" msgid "List of MCA devices:" -msgstr "Liste des dispositifs MCA :" +msgstr "Liste des dispositifs MCA :" msgid "&Tablet tool" msgstr "Outil Tablette" @@ -1684,7 +1726,7 @@ msgid "Null Driver" msgstr "Pilote NULL" msgid "NIC:" -msgstr "NIC:" +msgstr "NIC :" msgid "NIC %1 (%2) %3" msgstr "NIC %1 (%2) %3" @@ -1696,7 +1738,7 @@ msgid "Render behavior" msgstr "Comportement du rendu" msgid "Use target framerate:" -msgstr "Utiliser le taux de rafraĂ®chissement cible:" +msgstr "Utiliser le taux de rafraĂ®chissement cible :" msgid " fps" msgstr " Images par seconde" @@ -1738,7 +1780,7 @@ msgid "This machine might have been moved or copied." msgstr "Cette machine peut avoir Ă©tĂ© dĂ©placĂ©e ou copiĂ©e." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Afin d'assurer le bon fonctionnement du rĂ©seau, 86Box doit savoir si cette machine a Ă©tĂ© dĂ©placĂ©e ou copiĂ©e.\n\nSĂ©lectionnez « Je l'ai copiĂ© » si vous n'Ăªtes pas sĂ»r." +msgstr "Afin d'assurer le bon fonctionnement du rĂ©seau, 86Box doit savoir si cette machine a Ă©tĂ© dĂ©placĂ©e ou copiĂ©e.\n\nSĂ©lectionnez « Je l'ai copié » si vous n'Ăªtes pas sĂ»r." msgid "I Moved It" msgstr "Je l'ai dĂ©placĂ©" @@ -1746,8 +1788,8 @@ msgstr "Je l'ai dĂ©placĂ©" msgid "I Copied It" msgstr "Je l'ai copiĂ©" -msgid "86Box Monitor #" -msgstr "Moniteur 86Box" +msgid "86Box Monitor #%1" +msgstr "Moniteur 86Box %1" msgid "No MCA devices." msgstr "Pas de dispositifs MCA." @@ -1771,16 +1813,19 @@ msgid "Network Card #4" msgstr "Carte rĂ©seau 4" msgid "Mode:" -msgstr "Mode:" +msgstr "Mode :" msgid "Interface:" -msgstr "Interface:" +msgstr "Interface :" msgid "Adapter:" -msgstr "Adaptateur:" +msgstr "Adaptateur :" msgid "VDE Socket:" -msgstr "Prise VDE:" +msgstr "Prise VDE :" + +msgid "TAP Bridge Device:" +msgstr "Dispositif de pont TAP :" msgid "86Box Unit Tester" msgstr "Testeur d'unitĂ© de 86Box" @@ -2157,12 +2202,6 @@ msgstr "IntensitĂ© du filtre SID" msgid "Surround module" msgstr "Module Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Lever l'interruption CODEC lors de la configuration du CODEC (nĂ©cessaire pour certains pilotes)" - msgid "SB Address" msgstr "Adresse SB" @@ -2178,6 +2217,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ du horloge en temps rĂ©el" + +msgid "RTC Port Address" +msgstr "Addresse du port du horloge en temps rĂ©el" + +msgid "Onboard RTC" +msgstr "Horloge en temps rĂ©el integrĂ©" + +msgid "Not installed" +msgstr "Non installĂ©" + msgid "Enable OPL" msgstr "Activer OPL" @@ -2218,7 +2269,7 @@ msgid "GUS type" msgstr "Type de GUS" msgid "Enable 0x04 \"Exit 86Box\" command" -msgstr "Activer la commande 0x04 « Sortir de 86Box »" +msgstr "Activer la commande 0x04 « Sortir de 86Box »" msgid "Display type" msgstr "Type d'Ă©cran" @@ -2448,9 +2499,6 @@ msgstr "24 Mo" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stĂ©rĂ©o)" -msgid "Classic" -msgstr "Classique" - msgid "256 KB" msgstr "256 Ko" @@ -2707,7 +2755,7 @@ msgid "Unable to find Dot-Matrix fonts" msgstr "Impossible de trouver les polices matricielles" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P 2 Dot-Matrix Printer." -msgstr "Les polices TrueType dans le rĂ©pertoire \"roms/printer/fonts\" sont nĂ©cessaires Ă  l'Ă©mulation de l'imprimante gĂ©nĂ©rique ESC/P 2 matricielle." +msgstr "Les polices TrueType dans le rĂ©pertoire « roms/printer/fonts » sont nĂ©cessaires Ă  l'Ă©mulation de l'imprimante gĂ©nĂ©rique ESC/P 2 matricielle." msgid "Inhibit multimedia keys" msgstr "DĂ©sactiver les touches multimĂ©dia" @@ -2739,17 +2787,14 @@ msgstr "Erreur GLSL" msgid "Could not load shader: %1" msgstr "Impossible de charger le shader %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL version 3.0 ou supĂ©rieure requis. Version installĂ©e: %1.%2" - msgid "Could not load texture: %1" msgstr "Impossible de charger la texture %1" msgid "Could not compile shader:\n\n%1" -msgstr "Impossible de compiler le shader:\n\n%1" +msgstr "Impossible de compiler le shader :\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "Programme non linkĂ©:\n\n%1" +msgstr "Programme non linké :\n\n%1" msgid "Shader Manager" msgstr "Gestionnaire de shader" @@ -2770,7 +2815,7 @@ msgid "Could not load file %1" msgstr "Impossible de charger le fichier %1" msgid "Key Bindings:" -msgstr "Raccourcis clavier:" +msgstr "Raccourcis clavier :" msgid "Action" msgstr "Action" @@ -2788,7 +2833,7 @@ msgid "Bind Key" msgstr "Lier touche" msgid "Enter key combo:" -msgstr "Entrez la combinaison de touches:" +msgstr "Entrez la combinaison de touches :" msgid "Bind conflict" msgstr "Conflit de raccourci" @@ -2805,6 +2850,9 @@ msgstr "Envoyer Ctrl+Alt+Échap" msgid "Toggle fullscreen" msgstr "Activer/dĂ©sactiver le mode plein Ă©cran" +msgid "Toggle UI in fullscreen" +msgstr "Basculer l'interface utilisateur en mode plein Ă©cran" + msgid "Screenshot" msgstr "Capture d'Ă©cran" @@ -2833,34 +2881,34 @@ msgid "Remote Switch" msgstr "Commutateur distant" msgid "Switch:" -msgstr "Commutateur:" +msgstr "Commutateur :" msgid "Hub Mode" msgstr "Mode concentrateur" msgid "Hostname:" -msgstr "Nom d'hĂ´te:" +msgstr "Nom d'hĂ´te :" msgid "ISA RAM:" -msgstr "RAM ISA:" +msgstr "RAM ISA :" msgid "ISA ROM:" -msgstr "ROM ISA:" +msgstr "ROM ISA :" msgid "&Wipe NVRAM" msgstr "&Effacer la mĂ©moire NVRAM" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "Cela supprimera tous les fichiers NVRAM (et associĂ©s) de la machine virtuelle situĂ©s dans le sous-rĂ©pertoire \"nvr\". Vous devrez reconfigurer les paramètres du BIOS (et Ă©ventuellement d'autres pĂ©riphĂ©riques Ă  l'intĂ©rieur de la machine virtuelle) si nĂ©cessaire. \n\nĂtes-vous sĂ»r de vouloir effacer tout le contenu NVRAM de la machine virtuelle \"%1\" ?" +msgstr "Cela supprimera tous les fichiers NVRAM (et associĂ©s) de la machine virtuelle situĂ©s dans le sous-rĂ©pertoire « nvr ». Vous devrez reconfigurer les paramètres du BIOS (et Ă©ventuellement d'autres pĂ©riphĂ©riques Ă  l'intĂ©rieur de la machine virtuelle) si nĂ©cessaire. \n\nĂtes-vous sĂ»r de vouloir effacer tout le contenu NVRAM de la machine virtuelle « %1 » ?" msgid "Success" msgstr "Succès" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "Le contenu de la NVRAM de la machine virtuelle \"%1\" a Ă©tĂ© effacĂ© avec succès" +msgstr "Le contenu de la NVRAM de la machine virtuelle « %1 » a Ă©tĂ© effacĂ© avec succès" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" -msgstr "Une erreur s'est produite lors de la tentative d'effacement du contenu NVRAM de la machine virtuelle \"%1\"" +msgstr "Une erreur s'est produite lors de la tentative d'effacement du contenu NVRAM de la machine virtuelle « %1 »" msgid "%1 VM Manager" msgstr "Gestionnaire de machines virtuelles de %1" @@ -2872,7 +2920,7 @@ msgid "Unknown Status" msgstr "Statut inconnu" msgid "No Machines Found!" -msgstr "Aucune machine trouvĂ©e !" +msgstr "Aucune machine trouvĂ©e !" msgid "Check for updates on startup" msgstr "VĂ©rifier les mises Ă  jour au dĂ©marrage" @@ -2881,7 +2929,7 @@ msgid "Unable to determine release information" msgstr "Impossible de dĂ©terminer les informations relatives Ă  la version" msgid "There was an error checking for updates:\n\n%1\n\nPlease try again later." -msgstr "Une erreur s'est produite lors de la vĂ©rification des mises Ă  jour :\n\n%1\n\nVeuillez rĂ©essayer plus tard." +msgstr "Une erreur s'est produite lors de la vĂ©rification des mises Ă  jour :\n\n%1\n\nVeuillez rĂ©essayer plus tard." msgid "Update check complete" msgstr "VĂ©rification des mises Ă  jour terminĂ©e" @@ -2893,7 +2941,7 @@ msgid "beta" msgstr "bĂªta" msgid "You are running the latest %1 version of 86Box: %2" -msgstr "Vous utilisez la dernière version %1 de 86Box : %2" +msgstr "Vous utilisez la dernière version %1 de 86Box : %2" msgid "version" msgstr "version" @@ -2914,7 +2962,7 @@ msgid "Build %1 is now available." msgstr "Le Build %1 est dĂ©sormais disponible." msgid "Would you like to visit the download page?" -msgstr "Souhaitez-vous visiter la page de tĂ©lĂ©chargement ?" +msgstr "Souhaitez-vous visiter la page de tĂ©lĂ©chargement ?" msgid "Visit download page" msgstr "Visiter la page de tĂ©lĂ©chargement" @@ -2929,7 +2977,7 @@ msgid "86Box Update" msgstr "Mise Ă  jour de 86Box" msgid "Release notes:" -msgstr "Notes de mise Ă  jour :" +msgstr "Notes de mise Ă  jour :" msgid "%1 Hz" msgstr "%1 Hz" @@ -2938,7 +2986,7 @@ msgid "Virtual machine crash" msgstr "Panne de la machine virtuelle" msgid "The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2." -msgstr "Le processus de la machine virtuelle \"%1\" s'est arrĂªtĂ© de manière inattendue avec le code de sortie %2." +msgstr "Le processus de la machine virtuelle « %1 » s'est arrĂªtĂ© de manière inattendue avec le code de sortie %2." msgid "The system will not be added." msgstr "Le système ne sera pas ajoutĂ©." @@ -2977,7 +3025,7 @@ msgid "Export EDID" msgstr "Exporter l'EDID" msgid "EDID file \"%ls\" is too large." -msgstr "Le fichier EDID \"%ls\" est trop volumineux." +msgstr "Le fichier EDID « %ls » est trop volumineux." msgid "OpenGL input scale" msgstr "Échelle d'entrĂ©e d'OpenGL" @@ -2995,4 +3043,4 @@ msgid "Dark" msgstr "Sombre" msgid "Search:" -msgstr "Rechercher:" +msgstr "Rechercher :" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 0ea717dceb2..ee6c238b9b6 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Croatian " +"\n" +"Language: hr-HR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: hr_HR\n" "X-Source-Language: en_US\n" @@ -273,36 +281,6 @@ msgstr "Ponovo uÄitaj prethodnu sliku" msgid "&Folder..." msgstr "&Mapa..." -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" @@ -603,9 +581,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Odredi..." - msgid "Sectors:" msgstr "Sektori:" @@ -690,9 +665,6 @@ msgstr "UreÄ‘aj ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "GreÅ¡ka" @@ -852,9 +824,18 @@ msgstr "Nema PCap ureÄ‘aja" msgid "Invalid PCap device" msgstr "Nevažeći PCap ureÄ‘aj" +msgid "Generic paddle controller(s)" +msgstr "GeneriÄki kontroleri s lopaticama" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Palica za igru s 2 osi, 1 tipke" + msgid "2-axis, 2-button joystick(s)" msgstr "Palica za igru s 2 osi, 2 tipke" +msgid "2-axis, 3-button joystick" +msgstr "Palica za igru s 2 osi, 3 tipke" + msgid "2-axis, 4-button joystick" msgstr "Palica za igru s 2 osi, 4 tipke" @@ -867,35 +848,41 @@ msgstr "Palica za igru s 2 osi, 8 tipke" msgid "3-axis, 2-button joystick" msgstr "Palica za igru s 3 osi, 2 tipke" +msgid "3-axis, 3-button joystick" +msgstr "Palica za igru s 3 osi, 3 tipke" + msgid "3-axis, 4-button joystick" msgstr "Palica za igru s 3 osi, 4 tipke" +msgid "4-axis, 2-button joystick" +msgstr "Palica za igru s 4 osi, 2 tipke" + +msgid "4-axis, 3-button joystick" +msgstr "Palica za igru s 4 osi, 3 tipke" + msgid "4-axis, 4-button joystick" msgstr "Palica za igru s 4 osi, 4 tipke" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "Gamepad(ovi) s 2 tipke" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Gamepad s 3 tipke" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Gamepad s 4 tipke" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "Gamepad s 6 tipke" -msgid "2-button gamepad(s)" -msgstr "Gamepad(ovi) s 2 tipke" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Jaram za letenje s 2 tipke" -msgid "4-button gamepad" -msgstr "Gamepad s 4 tipke" +msgid "3-button flight yoke" +msgstr "Jaram za letenje s 3 tipke" msgid "4-button flight yoke" msgstr "Jaram za letenje s 4 tipke" @@ -903,11 +890,71 @@ msgstr "Jaram za letenje s 4 tipke" msgid "2-button flight yoke with throttle" msgstr "Jaram za letenje s 2 tipke i gasom" +msgid "3-button flight yoke with throttle" +msgstr "Jaram za letenje s 3 tipke i gasom" + msgid "4-button flight yoke with throttle" msgstr "Jaram za letenje s 4 tipke i gasom" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volan Win95 (3 osi, 4 tipke)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volan (3 osi, 2 tipke)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volan (3 osi, 3 tipke)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volan (3 osi, 4 tipke)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 s adapterom" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 bez adaptera" msgid "None" msgstr "Bez" @@ -978,11 +1025,8 @@ 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 "About %1" +msgstr "O programu %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i drugi.\n\nS prethodnim osnovnim doprinosima Sarah Walker, Leilei, JohnElliott, greatpsycho i drugih.\n\nPreveo: dob205\n\nObjavljeno pod licencom GNU General Public License, verzija 2 ili novije. Za viÅ¡e informacija pogledajte datoteku LICENCE." @@ -1030,7 +1074,7 @@ 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\"." +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 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" @@ -1332,8 +1376,8 @@ msgstr "Sistem" msgid "Storage" msgstr "Diskovi" -msgid "Disk %1: " -msgstr "Disk %1: " +msgid "Disk %1:" +msgstr "Disk %1:" msgid "No disks" msgstr "Nema diskova" @@ -1474,7 +1518,7 @@ msgid "This could mean that the parent image was modified after the differencing 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." +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." @@ -1714,7 +1758,7 @@ msgid "Remove" msgstr "Ukloni" msgid "Browse..." -msgstr "Pregledajte..." +msgstr "Pretraži..." msgid "Couldn't create OpenGL context." msgstr "Nije moguće stvoriti kontekst OpenGL." @@ -1746,8 +1790,8 @@ msgstr "Premjestio sam ga" msgid "I Copied It" msgstr "Kopirao sam ga" -msgid "86Box Monitor #" -msgstr "Monitor 86Box-a " +msgid "86Box Monitor #%1" +msgstr "Monitor 86Box-a %1" msgid "No MCA devices." msgstr "Nema ureÄ‘aja MCA." @@ -1782,6 +1826,9 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "VDE utiÄnica:" +msgid "TAP Bridge Device:" +msgstr "Mostovni ureÄ‘aj TAP:" + msgid "86Box Unit Tester" msgstr "JediniÄni ispitivaÄ 86Box-a" @@ -2157,12 +2204,6 @@ msgstr "JaÄina filtra SID-a" msgid "Surround module" msgstr "Modul Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Podigni prekid CODEC na postavljanju CODEC-a (potrebno nekim upravljaÄkim programima)" - msgid "SB Address" msgstr "Adresa SB-a" @@ -2178,6 +2219,18 @@ msgstr "IRQ WSS-a" msgid "WSS DMA" msgstr "DMA WSS-a" +msgid "RTC IRQ" +msgstr "IRQ sata u stvarnom vremenu" + +msgid "RTC Port Address" +msgstr "Adresa sata u stvarnom vremenu" + +msgid "Onboard RTC" +msgstr "Integrirani sat u stvarnom vremenu" + +msgid "Not installed" +msgstr "Nije instaliran" + msgid "Enable OPL" msgstr "Omogući OPL" @@ -2448,9 +2501,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "KlasiÄan" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2789,6 @@ msgstr "GreÅ¡ka GLSL" msgid "Could not load shader: %1" msgstr "Nije moguće uÄitati shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Potrebna je OpenGL verzija 3.0 ili novija. Trenutna GLSL verzija je %1.%2" - msgid "Could not load texture: %1" msgstr "Nije moguće uÄitati teksturu: %1" @@ -2805,6 +2852,9 @@ msgstr "PoÅ¡alji Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "UkljuÄi/iskljuÄi cijelozaslonski naÄin" +msgid "Toggle UI in fullscreen" +msgstr "Prebaci korisniÄko suÄelje u naÄinu cijelog zaslona" + msgid "Screenshot" msgstr "Snimka zaslona" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index a399c59e64a..533377b465a 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Italian \n" +"Language: it-IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: it_IT\n" "X-Source-Language: en_US\n" @@ -273,36 +279,6 @@ msgstr "Ricarica l'immagine precedente" msgid "&Folder..." msgstr "&Cartella..." -msgid "Target &framerate" -msgstr "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 "Sincronizzazione &verticale" - -msgid "&Select shader..." -msgstr "&Seleziona shader..." - -msgid "&Remove shader" -msgstr "&Rimuovi shader" - msgid "Preferences" msgstr "Preferenze" @@ -520,7 +496,7 @@ msgid "LPT4 Device:" msgstr "Dispositivo LPT4:" msgid "Internal LPT ECP DMA:" -msgstr "DMA LPT ECP interna" +msgstr "DMA LPT ECP interna:" msgid "Serial port 1" msgstr "Porta seriale 1" @@ -603,9 +579,6 @@ msgstr "Canale:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Specifica..." - msgid "Sectors:" msgstr "Settori:" @@ -690,9 +663,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Scheda di diagnostica" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Errore" @@ -852,9 +822,18 @@ msgstr "Nessun dispositivo PCap trovato" msgid "Invalid PCap device" msgstr "Dispositivo PCap non valido" +msgid "Generic paddle controller(s)" +msgstr "Controller generico/i a paletta" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick a 2 assi, 1 pulsanti" + msgid "2-axis, 2-button joystick(s)" msgstr "Joystick a 2 assi, 2 pulsanti" +msgid "2-axis, 3-button joystick" +msgstr "Joystick a 2 assi, 3 pulsanti" + msgid "2-axis, 4-button joystick" msgstr "Joystick a 2 assi, 4 pulsanti" @@ -867,35 +846,41 @@ msgstr "Joystick a 2 assi, 8 pulsanti" msgid "3-axis, 2-button joystick" msgstr "Joystick a 3 assi, 2 pulsanti" +msgid "3-axis, 3-button joystick" +msgstr "Joystick a 3 assi, 4 pulsanti" + msgid "3-axis, 4-button joystick" msgstr "Joystick a 3 assi, 4 pulsanti" +msgid "4-axis, 2-button joystick" +msgstr "Joystick a 4 assi, 2 pulsanti" + +msgid "4-axis, 3-button joystick" +msgstr "Joystick a 4 assi, 3 pulsanti" + msgid "4-axis, 4-button joystick" msgstr "Joystick a 4 assi, 4 pulsanti" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + Pedali CH" +msgid "2-button gamepad(s)" +msgstr "Gamepad a 2 pulsanti" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder" +msgid "3-button gamepad" +msgstr "Gamepad a 3 pulsanti" -msgid "Thrustmaster Flight Control System" -msgstr "Sistema di controllo Thrustmaster Flight" +msgid "4-button gamepad" +msgstr "Gamepad a 4 pulsanti" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Sistema di controllo timone" +msgid "6-button gamepad" +msgstr "Gamepad a 6 pulsanti" -msgid "2-button gamepad(s)" -msgstr "Gamepad a 2 pulsanti" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Barra di comando a 2 pulsanti" -msgid "4-button gamepad" -msgstr "Gamepad a 4 pulsanti" +msgid "3-button flight yoke" +msgstr "Barra di comando a 3 pulsanti" msgid "4-button flight yoke" msgstr "Barra di comando a 4 pulsanti" @@ -903,11 +888,71 @@ msgstr "Barra di comando a 4 pulsanti" msgid "2-button flight yoke with throttle" msgstr "Barra di comando a 2 pulsanti con acceleratore" +msgid "3-button flight yoke with throttle" +msgstr "Barra di comando a 4 pulsanti con acceleratore" + msgid "4-button flight yoke with throttle" msgstr "Barra di comando a 4 pulsanti con acceleratore" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volante Win95 (3 assi, 4 pulsanti)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volante (3 assi, 2 pulsanti)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volante (3 assi, 3 pulsanti)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volante (3 assi, 4 pulsanti)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + Pedali CH" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedali Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedali" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedali Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedali" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedali Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder" + +msgid "Thrustmaster Flight Control System" +msgstr "Sistema di controllo Thrustmaster Flight" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Sistema di controllo timone" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 con adattatore" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 senza adattatore" msgid "None" msgstr "Nessuno" @@ -978,11 +1023,8 @@ msgstr "Questo riavvierĂ  la macchina emulata." msgid "Save" msgstr "Salva" -msgid "About 86Box" -msgstr "Informazioni su 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Informazioni su %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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 vecchi computer\n\nAutori: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne e altri.\n\nCon i precedenti contributi fondamentali di Sarah Walker, leilei, JohnElliott, greatpsycho e altri.\n\nRilasciato sotto la Licenza Pubblica Generale GNU versione 2 o successiva. Per ulteriori informazioni, consultare il file LICENSE." @@ -1332,8 +1374,8 @@ msgstr "Sistema" msgid "Storage" msgstr "Archiviazione" -msgid "Disk %1: " -msgstr "Disco %1: " +msgid "Disk %1:" +msgstr "Disco %1:" msgid "No disks" msgstr "Nessun disco" @@ -1746,8 +1788,8 @@ msgstr "L'ho spostata" msgid "I Copied It" msgstr "L'ho copiata" -msgid "86Box Monitor #" -msgstr "Monitor 86Box #" +msgid "86Box Monitor #%1" +msgstr "Monitor 86Box #%1" msgid "No MCA devices." msgstr "Nessun dispositivo MCA." @@ -1782,6 +1824,9 @@ msgstr "Adattatore:" msgid "VDE Socket:" msgstr "Presa VDE:" +msgid "TAP Bridge Device:" +msgstr "Dispositivo ponte TAP:" + msgid "86Box Unit Tester" msgstr "Tester di unitĂ  86Box" @@ -2157,12 +2202,6 @@ msgstr "IntensitĂ  filtro SID" msgid "Surround module" msgstr "Modulo surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Incrementa l'interrupt CODEC nella configurazione CODEC (necessario per alcuni driver)" - msgid "SB Address" msgstr "Indirizzo SB" @@ -2178,6 +2217,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ dell'ora in tempo reale" + +msgid "RTC Port Address" +msgstr "Indirizzo porta dell'ora in tempo reale" + +msgid "Onboard RTC" +msgstr "Ora in tempo reale integrata" + +msgid "Not installed" +msgstr "Non installato" + msgid "Enable OPL" msgstr "Abilita OPL" @@ -2448,9 +2499,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Classico" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2787,6 @@ msgstr "Errore GLSL" msgid "Could not load shader: %1" msgstr "Impossibile caricare lo shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Ăˆ richiesta la versione 3.0 di OpenGL o successiva. La versione GLSL corrente è %1.%2" - msgid "Could not load texture: %1" msgstr "Impossibile caricare la texture: %1" @@ -2805,6 +2850,9 @@ msgstr "Invia Ctrl+Alt+Esc" msgid "Toggle fullscreen" msgstr "Attiva/disattiva schermo intero" +msgid "Toggle UI in fullscreen" +msgstr "Attivare/disattivare interfaccia utente in modalitĂ  a schermo intero" + msgid "Screenshot" msgstr "Istantanea dello schermo" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 5c6aa485c2f..8d117f34903 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -1,8 +1,15 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Japanese " +"\n" +"Language: ja-JP\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: ja_JP\n" "X-Source-Language: en_US\n" @@ -67,7 +74,7 @@ msgid "&VNC" msgstr "VNC(&V)" msgid "Specify &dimensions..." -msgstr "ăƒ‡ă‚£ăƒ¡ăƒ³ă‚·ăƒ§ăƒ³ă‚’æŒ‡å®...(&D)" +msgstr "ăƒ‡ă‚£ăƒ¡ăƒ³ă‚·ăƒ§ăƒ³ă‚’æŒ‡å®(&D)..." msgid "Force &4:3 display ratio" msgstr "4:3ă®ç¸¦æ¨ªæ¯”ă‚’å¼·åˆ¶è¡¨ç¤º(&4)" @@ -273,36 +280,6 @@ msgstr "å‰ă®ă‚¤ăƒ¡ăƒ¼ă‚¸ă‚’å†èª­ă¿è¾¼ă¿" msgid "&Folder..." msgstr "ăƒ•ă‚©ăƒ«ăƒ€(&F)..." -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 "環境設å®" @@ -478,7 +455,7 @@ msgid "MIDI In Device:" msgstr "MIDIå…¥å›ăƒ‡ăƒă‚¤ă‚¹:" msgid "MIDI Out:" -msgstr "MIDI出å›" +msgstr "MIDI出å›:" msgid "Standalone MPU-401" msgstr "独立å‹MPU-401" @@ -603,9 +580,6 @@ msgstr "ăƒăƒ£ăƒ³ăƒăƒ«:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "å‚ç…§(&S)..." - msgid "Sectors:" msgstr "ă‚»ă‚¯ă‚¿ăƒ¼:" @@ -690,9 +664,6 @@ msgstr "ISABuggerăƒ‡ăƒă‚¤ă‚¹" msgid "POST card" msgstr "POSTă‚«ăƒ¼ăƒ‰" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "ă‚¨ăƒ©ăƒ¼" @@ -852,9 +823,18 @@ msgstr "PCapăƒ‡ăƒă‚¤ă‚¹ăŒă‚ă‚ă¾ă›ă‚“" msgid "Invalid PCap device" msgstr "䏿­£ăªPCapăƒ‡ăƒă‚¤ă‚¹" +msgid "Generic paddle controller(s)" +msgstr "æ±ç”¨ăƒ‘ăƒ‰ăƒ«ă‚³ăƒ³ăƒˆăƒ­ăƒ¼ăƒ©ăƒ¼" + +msgid "2-axis, 1-button joystick(s)" +msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(2軸ă€1ăƒœă‚¿ăƒ³)" + msgid "2-axis, 2-button joystick(s)" msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(2軸ă€2ăƒœă‚¿ăƒ³)" +msgid "2-axis, 3-button joystick" +msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(2軸ă€3ăƒœă‚¿ăƒ³)" + msgid "2-axis, 4-button joystick" msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(2軸ă€4ăƒœă‚¿ăƒ³)" @@ -867,35 +847,41 @@ msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(2軸ă€8ăƒœă‚¿ăƒ³)" msgid "3-axis, 2-button joystick" msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(3軸ă€2ăƒœă‚¿ăƒ³)" +msgid "3-axis, 3-button joystick" +msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(3軸ă€3ăƒœă‚¿ăƒ³)" + msgid "3-axis, 4-button joystick" msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(3軸ă€4ăƒœă‚¿ăƒ³)" +msgid "4-axis, 2-button joystick" +msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(4軸ă€2ăƒœă‚¿ăƒ³)" + +msgid "4-axis, 3-button joystick" +msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(4軸ă€3ăƒœă‚¿ăƒ³)" + msgid "4-axis, 4-button joystick" msgstr "ă‚¸ăƒ§ă‚¤ă‚¹ăƒ†ă‚£ăƒƒă‚¯(4軸ă€4ăƒœă‚¿ăƒ³)" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "2ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinderăƒ‘ăƒƒăƒ‰" +msgid "3-button gamepad" +msgstr "3ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "6ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" -msgid "2-button gamepad(s)" -msgstr "2ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2ăƒœă‚¿ăƒ³å¼æ“縦桿" -msgid "4-button gamepad" -msgstr "4ăƒœă‚¿ăƒ³å¼ă‚²ăƒ¼ăƒ ăƒ‘ăƒƒăƒ‰" +msgid "3-button flight yoke" +msgstr "3ăƒœă‚¿ăƒ³å¼æ“縦桿" msgid "4-button flight yoke" msgstr "4ăƒœă‚¿ăƒ³å¼æ“縦桿" @@ -903,11 +889,71 @@ msgstr "4ăƒœă‚¿ăƒ³å¼æ“縦桿" msgid "2-button flight yoke with throttle" msgstr "2ăƒœă‚¿ăƒ³å¼ăƒ•ăƒ©ă‚¤ăƒˆăƒ¨ăƒ¼ă‚¯(ă‚¹ăƒ­ăƒƒăƒˆăƒ«ä»˜ă)" +msgid "3-button flight yoke with throttle" +msgstr "3ăƒœă‚¿ăƒ³å¼ăƒ•ăƒ©ă‚¤ăƒˆăƒ¨ăƒ¼ă‚¯(ă‚¹ăƒ­ăƒƒăƒˆăƒ«ä»˜ă)" + msgid "4-button flight yoke with throttle" msgstr "4ăƒœă‚¿ăƒ³å¼ăƒ•ăƒ©ă‚¤ăƒˆăƒ¨ăƒ¼ă‚¯(ă‚¹ăƒ­ăƒƒăƒˆăƒ«ä»˜ă)" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 ă‚¹ăƒ†ă‚¢ăƒªăƒ³ă‚°ăƒ›ă‚¤ăƒ¼ăƒ«(3軸ă€4ăƒœă‚¿ăƒ³)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "ă‚¹ăƒ†ă‚¢ăƒªăƒ³ă‚°ăƒ›ă‚¤ăƒ¼ăƒ«(3軸ă€2ăƒœă‚¿ăƒ³)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "ă‚¹ăƒ†ă‚¢ăƒªăƒ³ă‚°ăƒ›ă‚¤ăƒ¼ăƒ«(3軸ă€3ăƒœă‚¿ăƒ³)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "ă‚¹ăƒ†ă‚¢ăƒªăƒ³ă‚°ăƒ›ă‚¤ăƒ¼ăƒ«(3軸ă€4ăƒœă‚¿ăƒ³)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinderăƒ‘ăƒƒăƒ‰" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "ă‚¢ăƒ€ăƒ—ă‚¿ăƒ¼ä»˜ă Thrustmaster Formula T1/T2" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "ă‚¢ăƒ€ăƒ—ă‚¿ăƒ¼ăªă— Thrustmaster Formula T1/T2" msgid "None" msgstr "ăªă—" @@ -958,7 +1004,7 @@ msgid "&File" msgstr "ăƒ•ă‚¡ă‚¤ăƒ«(&F)" msgid "&New machine..." -msgstr "æ–°ă—ă„ăƒă‚·ăƒ³(&N)" +msgstr "æ–°ă—ă„ăƒă‚·ăƒ³(&N)..." msgid "&Check for updates..." msgstr "ă‚¢ăƒƒăƒ—ăƒ‡ăƒ¼ăƒˆă‚’ç¢ºèªä¸­(&C)..." @@ -978,11 +1024,8 @@ msgstr "使用中ă®ăƒă‚·ăƒ³ăŒăƒăƒ¼ăƒ‰ăƒªă‚»ăƒƒăƒˆă•ă‚Œă¾ă™ă€‚" msgid "Save" msgstr "ä¿å­˜" -msgid "About 86Box" -msgstr "86Boxă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³æƒ…å ±" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "%1ă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³æƒ…å ±" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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著者: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nSarah Walker, leilei, JohnElliott, greatpsycho, ăă®ä»–ă®æ–¹ă€…ă«ă‚ˆă‚‹ä»¥å‰ă‹ă‚‰ă®å¤å¤§ăªè²¢çŒ®ă€‚\n\nGNU General Public License version 2以é™ă§ăƒªăƒªăƒ¼ă‚¹ă•ă‚Œă¦ă„ă¾ă™ă€‚詳ă—ăă¯ LICENSE ă‚’ă”覧ăă ă•ă„。" @@ -1237,7 +1280,7 @@ msgid "C&lone..." msgstr "ă‚¯ăƒ­ăƒ¼ăƒ³(&L)..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" -msgstr "仮想ăƒă‚·ăƒ³\"%1\" (%2)ă¯ă€ä»¥ä¸‹ă®å ´æ‰€ă«ă‚¯ăƒ­ăƒ¼ăƒ³ă•ă‚Œă¾ă™:" +msgstr "仮想ăƒă‚·ăƒ³ă€Œ%1〠(%2)ă¯ă€ä»¥ä¸‹ă®å ´æ‰€ă«ă‚¯ăƒ­ăƒ¼ăƒ³ă•ă‚Œă¾ă™:" msgid "Directory %1 already exists" msgstr "ăƒ‡ă‚£ăƒ¬ă‚¯ăƒˆăƒª %1 ă¯æ—¢ă«å­˜åœ¨ă—ă¾ă™" @@ -1294,7 +1337,7 @@ msgid "An error has occurred while checking for updates: %1" msgstr "ă‚¢ăƒƒăƒ—ăƒ‡ăƒ¼ăƒˆă®ç¢ºèªä¸­ă«ă‚¨ăƒ©ăƒ¼ăŒç™ºç”Ÿă—ă¾ă—ăŸ: %1" msgid "An update to 86Box is available!" -msgstr "86Boxă®ă‚¢ăƒƒăƒ—ăƒ‡ăƒ¼ăƒˆăŒåˆ©ç”¨å¯èƒ½ă«ăªă‚ă¾ă—ăŸ!" +msgstr "86Boxă®ă‚¢ăƒƒăƒ—ăƒ‡ăƒ¼ăƒˆăŒåˆ©ç”¨å¯èƒ½ă«ăªă‚ă¾ă—ăŸï¼" msgid "Warning" msgstr "è­¦å‘" @@ -1303,13 +1346,13 @@ msgid "&Kill" msgstr "強制ç„ă«çµ‚了ă™ă‚‹(&K)" msgid "Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?" -msgstr "仮想ăƒă‚·ăƒ³ă‚’強制終了ă™ă‚‹ă¨ă€ăƒ‡ăƒ¼ă‚¿ăŒå¤±ă‚ă‚Œă‚‹å¯èƒ½æ€§ăŒă‚ă‚ă¾ă™ă€‚86Boxăƒ—ăƒ­ă‚»ă‚¹ăŒå¿œç­”ă—ăªăăªă£ăŸå ´åˆă®ă¿ă€ă“ă®æ“ä½œă‚’è¡Œă£ă¦ăă ă•ă„。\n\n本当ă«ä»®æƒ³ăƒă‚·ăƒ³\"%1\"ă‚’çµ‚äº†ă—ă¾ă™ă‹ï¼Ÿ" +msgstr "仮想ăƒă‚·ăƒ³ă‚’強制終了ă™ă‚‹ă¨ă€ăƒ‡ăƒ¼ă‚¿ăŒå¤±ă‚ă‚Œă‚‹å¯èƒ½æ€§ăŒă‚ă‚ă¾ă™ă€‚86Boxăƒ—ăƒ­ă‚»ă‚¹ăŒå¿œç­”ă—ăªăăªă£ăŸå ´åˆă®ă¿ă€ă“ă®æ“ä½œă‚’è¡Œă£ă¦ăă ă•ă„。\n\n本当ă«ä»®æƒ³ăƒă‚·ăƒ³ă€Œ%1ă€ă‚’終了ă—ă¾ă™ă‹ï¼Ÿ" msgid "&Delete" msgstr "å‰é™¤(&D)" msgid "Do you really want to delete the virtual machine \"%1\" and all its files? This action cannot be undone!" -msgstr "本当ă«ä»®æƒ³ăƒă‚·ăƒ³\"%1\"ă¨ăă®ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ«ă‚’å‰é™¤ă—ă¾ă™ă‹? ă“ă®æ“作ă¯å…ƒă«æˆ»ă›ă¾ă›ă‚“!" +msgstr "本当ă«ä»®æƒ³ăƒă‚·ăƒ³ă€Œ%1ă€ă¨ăă®ă™ă¹ă¦ă®ăƒ•ă‚¡ă‚¤ăƒ«ă‚’å‰é™¤ă—ă¾ă™ă‹ï¼Ÿ ă“ă®æ“作ă¯å…ƒă«æˆ»ă›ă¾ă›ă‚“ï¼" msgid "Show &config file" msgstr "設å®ăƒ•ă‚¡ă‚¤ăƒ«ă‚’è¡¨ç¤ºă™ă‚‹(&C)" @@ -1332,7 +1375,7 @@ msgstr "ă‚·ă‚¹ăƒ†ăƒ " msgid "Storage" msgstr "ă‚¹ăƒˆăƒ¬ăƒ¼ă‚¸" -msgid "Disk %1: " +msgid "Disk %1:" msgstr "ăƒ‡ă‚£ă‚¹ă‚¯ %1:" msgid "No disks" @@ -1651,7 +1694,7 @@ msgid "Show non-&primary monitors" msgstr "ăƒ—ăƒ©ă‚¤ăƒăƒªăƒ¼ăƒ¢ăƒ‹ă‚¿ăƒ¼ä»¥å¤–ă®ăƒ¢ăƒ‹ă‚¿ăƒ¼ă‚’表示ă™ă‚‹(&P)" msgid "Open screenshots &folder..." -msgstr "ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆăƒ•ă‚©ăƒ«ăƒ€ă‚’é–‹ă(&F)" +msgstr "ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆăƒ•ă‚©ăƒ«ăƒ€ă‚’é–‹ă(&F)..." msgid "Appl&y fullscreen stretch mode when maximized" msgstr "最大化時ă«ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚¹ăƒˆăƒ¬ăƒƒăƒăƒ¢ăƒ¼ăƒ‰ă‚’é©ç”¨(&Y)" @@ -1714,7 +1757,7 @@ msgid "Remove" msgstr "å‰é™¤" msgid "Browse..." -msgstr "ăƒ–ăƒ©ă‚¦ă‚º..." +msgstr "å‚ç…§..." msgid "Couldn't create OpenGL context." msgstr "OpenGLă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă‚’ä½œæˆă§ăă¾ă›ă‚“ă§ă—ăŸă€‚" @@ -1723,7 +1766,7 @@ msgid "Couldn't switch to OpenGL context." msgstr "OpenGLă‚³ăƒ³ăƒ†ă‚­ă‚¹ăƒˆă«åˆ‡ă‚替ăˆă‚‰ă‚Œăªă‹ă£ăŸă€‚" msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" -msgstr "OpenGLă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³3.0以ä¸ăŒå¿…è¦ă§ă™ă€‚ç¾åœ¨ă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³ă¯ %1.%2 ă§ă™ă€‚" +msgstr "OpenGLă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³3.0以ä¸ăŒå¿…è¦ă§ă™ă€‚ç¾åœ¨ă®ăƒăƒ¼ă‚¸ăƒ§ăƒ³ă¯ %1.%2 ă§ă™" msgid "Error initializing OpenGL" msgstr "OpenGLă®åˆæœŸåŒ–ă‚¨ăƒ©ăƒ¼" @@ -1738,7 +1781,7 @@ msgid "This machine might have been moved or copied." msgstr "ă“ă®ăƒă‚·ăƒ³ă¯ç§»å‹•ă•ă‚ŒăŸă‹ă‚³ăƒ”ăƒ¼ă•ă‚ŒăŸå¯èƒ½æ€§ăŒă‚る。" msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "ăƒăƒƒăƒˆăƒ¯ăƒ¼ă‚¯æ©Ÿèƒ½ă‚’æ­£ă—ă動作ă•ă›ă‚‹ăŸă‚ă«ă€86Boxă¯ă“ă®ăƒă‚·ăƒ³ăŒç§»å‹•ă•ă‚ŒăŸă‹ă‚³ăƒ”ăƒ¼ă•ă‚ŒăŸă‹ă‚’çŸ¥ă‚‹å¿…è¦ăŒă‚ă‚ă¾ă™ă€‚ă€Œă‚³ăƒ”ăƒ¼ă—ăŸă€ă‚’鏿ă—ă¦ăă ă•ă„。" +msgstr "ăƒăƒƒăƒˆăƒ¯ăƒ¼ă‚¯æ©Ÿèƒ½ă‚’æ­£ă—ă動作ă•ă›ă‚‹ăŸă‚ă«ă€86Boxă¯ă“ă®ăƒă‚·ăƒ³ăŒç§»å‹•ă•ă‚ŒăŸă‹ă‚³ăƒ”ăƒ¼ă•ă‚ŒăŸă‹ă‚’çŸ¥ă‚‹å¿…è¦ăŒă‚ă‚ă¾ă™ă€‚\n\nă€Œă‚³ăƒ”ăƒ¼ă—ăŸă€ă‚’鏿ă—ă¦ăă ă•ă„。" msgid "I Moved It" msgstr "å‹•ă‹ă—ăŸ" @@ -1746,8 +1789,8 @@ msgstr "å‹•ă‹ă—ăŸ" msgid "I Copied It" msgstr "ă‚³ăƒ”ăƒ¼ă—ăŸ" -msgid "86Box Monitor #" -msgstr "86Box ăƒ¢ăƒ‹ă‚¿ăƒ¼" +msgid "86Box Monitor #%1" +msgstr "86Box ăƒ¢ăƒ‹ă‚¿ăƒ¼%1" msgid "No MCA devices." msgstr "MCAăƒ‡ăƒă‚¤ă‚¹ă¯ăªă„。" @@ -1782,6 +1825,9 @@ msgstr "ă‚¢ăƒ€ăƒ—ă‚¿ăƒ¼:" msgid "VDE Socket:" msgstr "VDEă‚½ă‚±ăƒƒăƒˆ:" +msgid "TAP Bridge Device:" +msgstr "TAP ăƒ–ăƒªăƒƒă‚¸ăƒ‡ăƒă‚¤ă‚¹:" + msgid "86Box Unit Tester" msgstr "86Boxăƒ¦ăƒ‹ăƒƒăƒˆăƒ†ă‚¹ă‚¿ăƒ¼" @@ -1801,7 +1847,7 @@ msgid "Serial port passthrough 4" msgstr "ă‚·ăƒªă‚¢ăƒ«ăƒ»ăƒăƒ¼ăƒˆăƒ»ăƒ‘ă‚¹ă‚¹ăƒ«ăƒ¼ 4" msgid "Renderer &options..." -msgstr "ăƒ¬ăƒ³ăƒ€ăƒ©ăƒ¼è¨­å®...(&O)" +msgstr "ăƒ¬ăƒ³ăƒ€ăƒ©ăƒ¼è¨­å®(&O)..." msgid "PC/XT Keyboard" msgstr "PC/XT ă‚­ăƒ¼ăƒœăƒ¼ăƒ‰" @@ -2157,12 +2203,6 @@ msgstr "SIDăƒ•ă‚£ăƒ«ă‚¿ăƒ¼ă®å¼·åº¦" msgid "Surround module" msgstr "ă‚µăƒ©ă‚¦ăƒ³ăƒ‰ăƒ»ăƒ¢ă‚¸ăƒ¥ăƒ¼ăƒ«" -msgid "CODEC" -msgstr "ă‚³ăƒ¼ăƒ‡ăƒƒă‚¯" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "CODECă‚»ăƒƒăƒˆă‚¢ăƒƒăƒ—æ™‚ă«CODEC割ă‚è¾¼ă¿ă‚’発生ă•ă›ă‚‹(一部ă®ăƒ‰ăƒ©ă‚¤ăƒă§å¿…è¦)" - msgid "SB Address" msgstr "SBă‚¢ăƒ‰ăƒ¬ă‚¹" @@ -2178,6 +2218,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "RTCă®IRQ" + +msgid "RTC Port Address" +msgstr "RTCă®ăƒăƒ¼ăƒˆă‚¢ăƒ‰ăƒ¬ă‚¹" + +msgid "Onboard RTC" +msgstr "ă‚ªăƒ³ăƒœăƒ¼ăƒ‰ RTC" + +msgid "Not installed" +msgstr "ă‚¤ăƒ³ă‚¹ăƒˆăƒ¼ăƒ«ă•ă‚Œă¦ă„ă¾ă›ă‚“" + msgid "Enable OPL" msgstr "OPLă‚’æœ‰å¹ă«ă™ă‚‹" @@ -2218,7 +2270,7 @@ msgid "GUS type" msgstr "GUSă‚¿ă‚¤ăƒ—" msgid "Enable 0x04 \"Exit 86Box\" command" -msgstr "ă‚³ăƒăƒ³ăƒ‰ 0x04 \"86Boxă‚’çµ‚äº†ă™ă‚‹\"ă‚’æœ‰å¹ă«ă™ă‚‹" +msgstr "ă‚³ăƒăƒ³ăƒ‰ 0x04 ă€Œ86Boxă‚’çµ‚äº†ă™ă‚‹ă€ă‚’有å¹ă«ă™ă‚‹" msgid "Display type" msgstr "è¡¨ç¤ºă‚¿ă‚¤ăƒ—" @@ -2448,9 +2500,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "ă‚·ă‚°ăƒăƒ†ăƒ« STAC9721Tï¼ˆă‚¹ăƒ†ăƒ¬ă‚ªï¼‰" -msgid "Classic" -msgstr "ă‚¯ăƒ©ă‚·ăƒƒă‚¯" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2788,6 @@ msgstr "GLSLă‚¨ăƒ©ăƒ¼" msgid "Could not load shader: %1" msgstr "ă‚·ă‚§ăƒ¼ăƒ€ăƒ¼ă‚’èª­ă¿è¾¼ă‚ă¾ă›ă‚“ă§ă—ăŸ: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGLăƒăƒ¼ă‚¸ăƒ§ăƒ³ 3.0 以ä¸ăŒå¿…è¦ă§ă™ă€‚ç¾åœ¨ă®GLSLăƒăƒ¼ă‚¸ăƒ§ăƒ³ă¯ %1.%2 ă§ă™ă€‚" - msgid "Could not load texture: %1" msgstr "ăƒ†ă‚¯ă‚¹ăƒăƒ£ă‚’読ă¿è¾¼ă‚ă¾ă›ă‚“ă§ă—ăŸ: %1" @@ -2805,6 +2851,9 @@ msgstr "Ctrl+Alt+Escă‚’é€ä¿¡" msgid "Toggle fullscreen" msgstr "ăƒ•ăƒ«ă‚¹ă‚¯ăƒªăƒ¼ăƒ³è¡¨ç¤ºă‚’åˆ‡ă‚æ›¿ăˆă‚‹" +msgid "Toggle UI in fullscreen" +msgstr "全画é¢è¡¨ç¤ºæ™‚ă«UIă‚’åˆ‡ă‚æ›¿ăˆă‚‹" + msgid "Screenshot" msgstr "ă‚¹ă‚¯ăƒªăƒ¼ăƒ³ă‚·ăƒ§ăƒƒăƒˆ" @@ -2851,16 +2900,16 @@ msgid "&Wipe NVRAM" msgstr "NVRAMă‚’æ¶ˆå»ă™ă‚‹(&W)" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "ă“ă‚Œă«ă‚ˆă£ă¦ă€ä»®æƒ³ăƒă‚·ăƒ³å†…ă®\"nvr\"ă‚µăƒ–ăƒ‡ă‚£ăƒ¬ă‚¯ăƒˆăƒªă«æ ¼ç´ă•ă‚Œă¦ă„ă‚‹ă™ă¹ă¦ă®NVRAM(ăă‚ˆă³é–¢é€£)ăƒ•ă‚¡ă‚¤ăƒ«ăŒå‰é™¤ă•ă‚Œă¾ă™ă€‚å¿…è¦ă«å¿œă˜ă¦ă€BIOSă®è¨­å®(ăă‚ˆă³ä»®æƒ³ăƒă‚·ăƒ³å†…ă®ä»–ă®ăƒ‡ăƒă‚¤ă‚¹è¨­å®)ă‚’å†æ§‹æˆă™ă‚‹å¿…è¦ăŒă‚ă‚ă¾ă™ă€‚\n\n仮想ăƒă‚·ăƒ³\"%1\"ă®ă™ă¹ă¦ă®NVRAMå†…å®¹ă‚’å‰é™¤ă—ă¦ă‚‚ă‚ˆă‚ă—ă„ă§ă™ă‹?" +msgstr "ă“ă‚Œă«ă‚ˆă£ă¦ă€ä»®æƒ³ăƒă‚·ăƒ³å†…ă®ă€Œnvră€ă‚µăƒ–ăƒ‡ă‚£ăƒ¬ă‚¯ăƒˆăƒªă«æ ¼ç´ă•ă‚Œă¦ă„ă‚‹ă™ă¹ă¦ă®NVRAM(ăă‚ˆă³é–¢é€£)ăƒ•ă‚¡ă‚¤ăƒ«ăŒå‰é™¤ă•ă‚Œă¾ă™ă€‚å¿…è¦ă«å¿œă˜ă¦ă€BIOSă®è¨­å®(ăă‚ˆă³ä»®æƒ³ăƒă‚·ăƒ³å†…ă®ä»–ă®ăƒ‡ăƒă‚¤ă‚¹è¨­å®)ă‚’å†æ§‹æˆă™ă‚‹å¿…è¦ăŒă‚ă‚ă¾ă™ă€‚\n\n仮想ăƒă‚·ăƒ³ă€Œ%1ă€ă®ă™ă¹ă¦ă®NVRAMå†…å®¹ă‚’å‰é™¤ă—ă¦ă‚‚ă‚ˆă‚ă—ă„ă§ă™ă‹ï¼Ÿ" msgid "Success" msgstr "æˆåŸ" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "仮想ăƒă‚·ăƒ³\"%1\"ă®NVRAMă®å†…å®¹ă‚’æ­£å¸¸ă«æ¶ˆå»ă—ă¾ă—ăŸ" +msgstr "仮想ăƒă‚·ăƒ³ă€Œ%1ă€ă®NVRAMă®å†…å®¹ă‚’æ­£å¸¸ă«æ¶ˆå»ă—ă¾ă—ăŸ" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" -msgstr "仮想ăƒă‚·ăƒ³\"%1\"ă®NVRAMă®å†…å®¹ă‚’æ¶ˆå»ă—ă‚ˆă†ă¨ă—ăŸé›ă«ă‚¨ăƒ©ăƒ¼ăŒç™ºç”Ÿă—ă¾ă—ăŸ" +msgstr "仮想ăƒă‚·ăƒ³ă€Œ%1ă€ă®NVRAMă®å†…å®¹ă‚’æ¶ˆå»ă—ă‚ˆă†ă¨ă—ăŸé›ă«ă‚¨ăƒ©ăƒ¼ăŒç™ºç”Ÿă—ă¾ă—ăŸ" msgid "%1 VM Manager" msgstr "%1 VMăƒăƒăƒ¼ă‚¸ăƒ£ăƒ¼" @@ -2872,7 +2921,7 @@ msgid "Unknown Status" msgstr "䏿˜ăªç¶æ…‹" msgid "No Machines Found!" -msgstr "ăƒă‚·ăƒ³ăŒæ¤œå‡ºă•ă‚Œă¾ă›ă‚“!" +msgstr "ăƒă‚·ăƒ³ăŒæ¤œå‡ºă•ă‚Œă¾ă›ă‚“ï¼" msgid "Check for updates on startup" msgstr "起動時ă«ă‚¢ăƒƒăƒ—ăƒ‡ăƒ¼ăƒˆă‚’ç¢ºèªă™ă‚‹" @@ -2938,7 +2987,7 @@ msgid "Virtual machine crash" msgstr "仮想ăƒă‚·ăƒ³ă®äºˆæœŸă›ă¬çµ‚了" msgid "The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2." -msgstr "仮想ăƒă‚·ăƒ³\"%1\"ă®ăƒ—ăƒ­ă‚»ă‚¹ăŒă€çµ‚äº†ă‚³ăƒ¼ăƒ‰ %2 ă§äºˆæœŸă›ă終了ă—ă¾ă—ăŸă€‚" +msgstr "仮想ăƒă‚·ăƒ³ă€Œ%1ă€ă®ăƒ—ăƒ­ă‚»ă‚¹ăŒă€çµ‚äº†ă‚³ăƒ¼ăƒ‰ %2 ă§äºˆæœŸă›ă終了ă—ă¾ă—ăŸă€‚" msgid "The system will not be added." msgstr "ă‚·ă‚¹ăƒ†ăƒ ă¯è¿½å ă•ă‚Œă¾ă›ă‚“。" @@ -2962,7 +3011,7 @@ msgid "Sharpness" msgstr "ă‚·ăƒ£ăƒ¼ăƒ—ăƒă‚¹" msgid "&CGA composite settings..." -msgstr "CGA複åˆăƒ¢ăƒ¼ăƒ‰ă®è¨­å®...(&C)" +msgstr "CGA複åˆăƒ¢ăƒ¼ăƒ‰ă®è¨­å®(&C)..." msgid "CGA composite settings" msgstr "CGA複åˆăƒ¢ăƒ¼ăƒ‰ă®è¨­å®" @@ -2977,7 +3026,7 @@ msgid "Export EDID" msgstr "EDIDă®ă‚¨ă‚¯ă‚¹ăƒăƒ¼ăƒˆ" msgid "EDID file \"%ls\" is too large." -msgstr "EDIDăƒ•ă‚¡ă‚¤ăƒ« \"%ls\" ăŒå¤§ăă™ăă¾ă™ă€‚" +msgstr "EDIDăƒ•ă‚¡ă‚¤ăƒ«ă€Œ%lsă€ăŒå¤§ăă™ăă¾ă™ă€‚" msgid "OpenGL input scale" msgstr "OpenGLă®å…¥å›ă‚¹ă‚±ăƒ¼ăƒ«" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 4474138b2ce..4994e8e6699 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -67,7 +67,7 @@ msgid "&VNC" msgstr "VNC(&V)" msgid "Specify &dimensions..." -msgstr "́°½ í¬ê¸° ́§€́ •하기...(&D)" +msgstr "́°½ í¬ê¸° ́§€́ •하기(&D)..." msgid "Force &4:3 display ratio" msgstr "화면 비́œ΅„ 4:3́œ¼ë¡œ ë§́¶”기(&4)" @@ -273,36 +273,6 @@ msgstr "́´́ „ ́´ë¯¸́§€ 다́‹œ 불러́˜¤ê¸°" msgid "&Folder..." msgstr "í´ë”(&F)..." -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 "환경́„¤́ •" @@ -603,9 +573,6 @@ msgstr "́±„ë„:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "́—´ê¸°(&S)..." - msgid "Sectors:" msgstr "́„¹í„°:" @@ -690,9 +657,6 @@ msgstr "ISABugger ́¥́¹˜" msgid "POST card" msgstr "POST ́¹´ë“œ" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "́˜¤ë¥˜" @@ -852,9 +816,18 @@ msgstr "PCap ́¥́¹˜ê°€ ́—†́µë‹ˆë‹¤" msgid "Invalid PCap device" msgstr "PCap ́¥́¹˜ê°€ ́˜¬ë°”르́§€ ́•́µë‹ˆë‹¤" +msgid "Generic paddle controller(s)" +msgstr "́¼ë°˜ 패들 ́»¨í¸ë¡¤ëŸ¬" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2́¶•, 1ë²„í¼ ́¡°́´́¤í‹±" + msgid "2-axis, 2-button joystick(s)" msgstr "2́¶•, 2ë²„í¼ ́¡°́´́¤í‹±" +msgid "2-axis, 3-button joystick" +msgstr "2́¶•, 3ë²„í¼ ́¡°́´́¤í‹±" + msgid "2-axis, 4-button joystick" msgstr "2́¶•, 4ë²„í¼ ́¡°́´́¤í‹±" @@ -867,35 +840,41 @@ msgstr "2́¶•, 8ë²„í¼ ́¡°́´́¤í‹±" msgid "3-axis, 2-button joystick" msgstr "3́¶•, 2ë²„í¼ ́¡°́´́¤í‹±" +msgid "3-axis, 3-button joystick" +msgstr "3́¶•, 3ë²„í¼ ́¡°́´́¤í‹±" + msgid "3-axis, 4-button joystick" msgstr "3́¶•, 4ë²„í¼ ́¡°́´́¤í‹±" +msgid "4-axis, 2-button joystick" +msgstr "4́¶•, 2ë²„í¼ ́¡°́´́¤í‹±" + +msgid "4-axis, 3-button joystick" +msgstr "4́¶•, 3ë²„í¼ ́¡°́´́¤í‹±" + msgid "4-axis, 4-button joystick" msgstr "4́¶•, 4ë²„í¼ ́¡°́´́¤í‹±" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "2ë²„í¼ ê²Œ́„패드" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3ë²„í¼ ê²Œ́„패드" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4ë²„í¼ ê²Œ́„패드" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "6ë²„í¼ ê²Œ́„패드" -msgid "2-button gamepad(s)" -msgstr "2ë²„í¼ ê²Œ́„패드" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„" -msgid "4-button gamepad" -msgstr "4ë²„í¼ ê²Œ́„패드" +msgid "3-button flight yoke" +msgstr "3ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„" msgid "4-button flight yoke" msgstr "4ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„" @@ -903,11 +882,71 @@ msgstr "4ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„" msgid "2-button flight yoke with throttle" msgstr "2ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„ê³¼ ́¤ë¡œí‹€" +msgid "3-button flight yoke with throttle" +msgstr "3ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„ê³¼ ́¤ë¡œí‹€" + msgid "4-button flight yoke with throttle" msgstr "4ë²„í¼ ë¹„í–‰ ́¡°́¢…ê°„ê³¼ ́¤ë¡œí‹€" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 ́¡°íƒ€ë¥œ (3́¶•, 4버í¼)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "́¡°íƒ€ë¥œ (3́¶•, 2버í¼)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "́¡°íƒ€ë¥œ (3́¶•, 3버í¼)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "́¡°íƒ€ë¥œ (3́¶•, 4버í¼)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "́–´ëŒ‘í„° í¬í•¨ Thrustmaster Formula T1/T2" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "́–´ëŒ‘í„° 미í¬í•¨ Thrustmaster Formula T1/T2" msgid "None" msgstr "́—†́Œ" @@ -978,11 +1017,8 @@ msgstr "́‚¬́©́¤‘́¸ 머́‹ ́´ ́¬ë¶€íŒ…ë©ë‹ˆë‹¤." msgid "Save" msgstr "́ €́¥" -msgid "About 86Box" -msgstr "86Box́— 대해" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "%1́— 대해" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "ê³ ́ „ ́»´í“¨í„° ́—뮬레́´í„°\n\ń €́: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\ń´́ „ 핵́‹¬ 기́—¬́ë¡œë” Sarah Walker, leilei, JohnElliott, greatpsycho 등́´ ́ˆ́µë‹ˆë‹¤.\n\nGNU General Public ë¼́´́„ ́¤ (버́ „ 2 ́´́ƒ)́— ́˜í•´ ë°°í¬ë˜́—ˆ́µë‹ˆë‹¤. ́́„¸í•œ ë‚´́©́€ LICENSE 파́¼́„ ́½́–´ ́£¼́„¸́”." @@ -1332,8 +1368,8 @@ msgstr "́‹œ́¤í…œ" msgid "Storage" msgstr "́¥́¹˜" -msgid "Disk %1: " -msgstr "ë””́¤í¬ %1: " +msgid "Disk %1:" +msgstr "ë””́¤í¬ %1:" msgid "No disks" msgstr "ë””́¤í¬ ́—†́Œ" @@ -1369,10 +1405,10 @@ msgid "Add Existing Hard Disk" msgstr "기́¡´ ́´ë¯¸́§€ ́‚¬́©" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI ë””́¤í¬ ́´ë¯¸́§€ë” 4GB ́´́ƒ́œ¼ë¡œ ́§€́ •í•  ́ˆ˜ ́—†́µë‹ˆë‹¤" +msgstr "HDI ë””́¤í¬ ́´ë¯¸́§€ë” 4GB ́´́ƒ́œ¼ë¡œ ́§€́ •í•  ́ˆ˜ ́—†́µë‹ˆë‹¤." msgid "Disk images cannot be larger than 127 GB." -msgstr "ë””́¤í¬ ́´ë¯¸́§€ë” 127GB ́´́ƒ́œ¼ë¡œ ́§€́ •í•  ́ˆ˜ ́—†́µë‹ˆë‹¤" +msgstr "ë””́¤í¬ ́´ë¯¸́§€ë” 127GB ́´́ƒ́œ¼ë¡œ ́§€́ •í•  ́ˆ˜ ́—†́µë‹ˆë‹¤." msgid "Hard disk images" msgstr "하드 ë””́¤í¬ ́´ë¯¸́§€" @@ -1384,7 +1420,7 @@ 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 형́‹́˜ ́´ë¯¸́§€ë¥¼ ́ƒ́„±í•  ́ˆ˜ ́—†́µë‹ˆë‹¤" +msgstr "512 ë°”́´í¸ ́´́™¸́˜ ́„¹í„° í¬ê¸°ë¥¼ ê°€́§„ HDI ë˜ë” HDX 형́‹́˜ ́´ë¯¸́§€ë¥¼ ́ƒ́„±í•  ́ˆ˜ ́—†́µë‹ˆë‹¤." msgid "Disk image file already exists" msgstr "ë””́¤í¬ ́´ë¯¸́§€ 파́¼́´ ́´ë¯¸ ́¡´́¬í•©ë‹ˆë‹¤" @@ -1477,7 +1513,7 @@ msgid "Parent and child disk timestamps do not match" msgstr "부모 ë””́¤í¬́™€ ́́‹ ë””́¤í¬́˜ 타́„́¤íƒ¬í”„ê°€ ́¼́¹˜í•˜́§€ ́•́µë‹ˆë‹¤" msgid "Could not fix VHD timestamp." -msgstr "VHD 타́„́¤íƒ¬í”„를 ê³ ́¹  ́ˆ˜ ́—†́µë‹ˆë‹¤" +msgstr "VHD 타́„́¤íƒ¬í”„를 ê³ ́¹  ́ˆ˜ ́—†́µë‹ˆë‹¤." msgid "MFM/RLL" msgstr "MFM/RLL" @@ -1651,7 +1687,7 @@ msgid "Show non-&primary monitors" msgstr "기본 모니터가 ́•„닌 모니터 표́‹œ(&P)" msgid "Open screenshots &folder..." -msgstr "́¤í¬ë¦°́ƒ· í´ë” ́—´ê¸°...(&F)" +msgstr "́¤í¬ë¦°́ƒ· í´ë” ́—´ê¸°(&F)..." msgid "Appl&y fullscreen stretch mode when maximized" msgstr "́µœëŒ€í™” ́‹œ ́ „́²´ 화면 비́œ¨ ́ ́©(&Y)" @@ -1723,7 +1759,7 @@ msgid "Couldn't switch to OpenGL context." msgstr "OpenGL ́»¨í…́¤í¸ë¡œ ́ „환할 ́ˆ˜ ́—†́µë‹ˆë‹¤." msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" -msgstr "OpenGL 버́ „ 3.0 ́´́ƒ́´ í•„́”합니다. 현́¬ 버́ „́€ %1.%2́…니다." +msgstr "OpenGL 버́ „ 3.0 ́´́ƒ́´ í•„́”합니다. 현́¬ 버́ „́€ %1.%2́…니다" msgid "Error initializing OpenGL" msgstr "OpenGL ́´ˆê¸°í™” ́¤‘ ́˜¤ë¥˜ ë°œ́ƒ" @@ -1746,8 +1782,8 @@ msgstr "́˜®ê²¼́–´́”" msgid "I Copied It" msgstr "ë³µ́‚¬í–ˆ́µë‹ˆë‹¤" -msgid "86Box Monitor #" -msgstr "86Box 모니터 " +msgid "86Box Monitor #%1" +msgstr "86Box 모니터 %1" msgid "No MCA devices." msgstr "MCA ́¥́¹˜ê°€ ́—†́µë‹ˆë‹¤." @@ -1782,6 +1818,9 @@ msgstr "́–´ëŒ‘í„°:" msgid "VDE Socket:" msgstr "VDE ́†Œ́¼“:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "86Box ́œ ë‹› í…Œ́¤í„°" @@ -1801,7 +1840,7 @@ msgid "Serial port passthrough 4" msgstr "́§ë ¬ í¬í¸ 패́¤́¤ë£¨ 4" msgid "Renderer &options..." -msgstr "ë Œë”러 ́˜µ́…˜...(&O)" +msgstr "ë Œë”러 ́˜µ́…˜(&O)..." msgid "PC/XT Keyboard" msgstr "PC/XT 키보드" @@ -2157,12 +2196,6 @@ msgstr "SID í•„í„° ê°•ë„" msgid "Surround module" msgstr "́„œë¼́´ë“œ 모듈" -msgid "CODEC" -msgstr "́½”ë±" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "́½”ë± ́„¤́ • ́‹œ ́½”ë± ́¸í„°ëŸ½í¸ ́˜¬ë¦¬ê¸°(́¼ë¶€ 드ë¼́´ë²„́— í•„́”)" - msgid "SB Address" msgstr "SB ́£¼́†Œ" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "OPL ́‚¬́©" @@ -2448,9 +2493,6 @@ msgstr "24MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "́‹œê·¸ë§ˆí…” STAC9721T(́¤í…Œë ˆ́˜¤)" -msgid "Classic" -msgstr "í´ë˜́‹" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "GLSL ́˜¤ë¥˜" msgid "Could not load shader: %1" msgstr "́…°́´ë”를 로드할 ́ˆ˜ ́—†́µë‹ˆë‹¤: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL 버́ „ 3.0 ́´́ƒ́´ í•„́”합니다. 현́¬ GLSL 버́ „́€ %1.%2́…니다" - msgid "Could not load texture: %1" msgstr "í…́¤́²˜ë¥¼ 로드할 ́ˆ˜ ́—†́µë‹ˆë‹¤: %1" @@ -2805,6 +2844,9 @@ msgstr "Ctrl+Alt+Esc 보내기" msgid "Toggle fullscreen" msgstr "́ „́²´ 화면 모드 ́ „환" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "́¤í¬ë¦°́ƒ·" @@ -2962,7 +3004,7 @@ msgid "Sharpness" msgstr "́„ ëª…ë„" msgid "&CGA composite settings..." -msgstr "CGA 복합 모드́˜ ́„¤́ •...(&C)" +msgstr "CGA 복합 모드́˜ ́„¤́ •(&C)..." msgid "CGA composite settings" msgstr "CGA 복합 모드́˜ ́„¤́ •" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index 06b7a4f25d0..395a56dc9c8 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -273,36 +273,6 @@ msgstr "Last inn forrige diskfil" msgid "&Folder..." msgstr "&Mappe..." -msgid "Target &framerate" -msgstr "MĂ¥l-&bildefrekvens" - -msgid "&Sync with video" -msgstr "&Synkroniser med 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 "&Velg shader..." - -msgid "&Remove shader" -msgstr "&Fjern shader" - msgid "Preferences" msgstr "Valg" @@ -328,7 +298,7 @@ msgid "&Default" msgstr "&Standard" msgid "Language:" -msgstr "SprĂ¥k" +msgstr "SprĂ¥k:" msgid "Gain" msgstr "Forsterkning" @@ -603,9 +573,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Angi..." - msgid "Sectors:" msgstr "Sektorer:" @@ -690,9 +657,6 @@ msgstr "ISABugger-enhet" msgid "POST card" msgstr "POST-kort" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Feil" @@ -852,9 +816,18 @@ msgstr "Ingen PCap-enheter funnet" msgid "Invalid PCap device" msgstr "Ugyldig PCap-enhet" +msgid "Generic paddle controller(s)" +msgstr "Generisk padle-kontroller(e)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-akset, 1-knapps styrespak(er)" + msgid "2-axis, 2-button joystick(s)" msgstr "2-akset, 2-knapps styrespak(er)" +msgid "2-axis, 3-button joystick" +msgstr "2-akset, 3-knapps styrespak" + msgid "2-axis, 4-button joystick" msgstr "2-akset, 4-knapps styrespak" @@ -867,35 +840,41 @@ msgstr "2-akset, 8-knapps styrespak" msgid "3-axis, 2-button joystick" msgstr "3-akset, 2-knapps styrespak" +msgid "3-axis, 3-button joystick" +msgstr "3-akset, 3-knapps styrespak" + msgid "3-axis, 4-button joystick" msgstr "3-akset, 4-knapps styrespak" +msgid "4-axis, 2-button joystick" +msgstr "4-akset, 2-knapps styrespak" + +msgid "4-axis, 3-button joystick" +msgstr "4-akset, 3-knapps styrespak" + msgid "4-axis, 4-button joystick" msgstr "4-akset, 4-knapps styrespak" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedaler" +msgid "2-button gamepad(s)" +msgstr "2-knapps gamepad(er)" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3-knapps gamepad" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4-knapps gamepad" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Ror-kontrollsystem" +msgid "6-button gamepad" +msgstr "6-knapps gamepad" -msgid "2-button gamepad(s)" -msgstr "2-knapps gamepad(er)" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2-knapps flystyre" -msgid "4-button gamepad" -msgstr "4-knapps gamepad" +msgid "3-button flight yoke" +msgstr "3-knapps flystyre" msgid "4-button flight yoke" msgstr "4-knapps flystyre" @@ -903,11 +882,71 @@ msgstr "4-knapps flystyre" msgid "2-button flight yoke with throttle" msgstr "2-knapps flystyre med gass" +msgid "3-button flight yoke with throttle" +msgstr "3-knapps flystyre med gass" + msgid "4-button flight yoke with throttle" msgstr "4-knapps flystyre med gass" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 Ratt (3-akset, 4-knapps)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Ratt (3-akset, 3-knapps)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Ratt (3-akset, 3-knapps)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Ratt (3-akset, 4-knapps)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedaler" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedaler Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedaler" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedaler Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedaler" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedaler Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedaler" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedaler Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Ror-kontrollsystem" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 med adapter" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 uten adapter" msgid "None" msgstr "Ingen" @@ -978,11 +1017,8 @@ msgstr "Dette vil hard-resette den emulerte maskinen." msgid "Save" msgstr "Lagre" -msgid "About 86Box" -msgstr "Om 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Om %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "En emulator for gamle datamaskiner\n\nForfattere: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne og andre.\n\nMed tidligere kjernebidrag fra Sarah Walker, leilei, JohnElliott, greatpsycho og andre.\n\nUtgitt under GNU General Public License versjon 2 eller senere. Se LICENSE for mer informasjon." @@ -1332,7 +1368,7 @@ msgstr "System" msgid "Storage" msgstr "Lagring" -msgid "Disk %1: " +msgid "Disk %1:" msgstr "Disk %1:" msgid "No disks" @@ -1746,8 +1782,8 @@ msgstr "Jeg flyttet den" msgid "I Copied It" msgstr "Jeg kopierte den" -msgid "86Box Monitor #" -msgstr "86Box-skjerm #" +msgid "86Box Monitor #%1" +msgstr "86Box-skjerm #%1" msgid "No MCA devices." msgstr "Ingen MCA-enheter." @@ -1782,6 +1818,9 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "VDE-kontakt:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "86Box-enhetstester" @@ -2157,12 +2196,6 @@ msgstr "SID-filterstyrke" msgid "Surround module" msgstr "Surround-modul" -msgid "CODEC" -msgstr "Kodek" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Generer kodek-avbrudd ved kodek-oppsett (nødvendig for noen drivere)" - msgid "SB Address" msgstr "SB-adresse" @@ -2178,6 +2211,18 @@ msgstr "WSS-IRQ" msgid "WSS DMA" msgstr "WSS-DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "Aktiver OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klassisk" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "GLSL-feil" msgid "Could not load shader: %1" msgstr "Kunne ikke laste shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL versjon 3.0 eller høyere kreves. NĂ¥værende GLSL-versjon er %1.%2" - msgid "Could not load texture: %1" msgstr "Kunne ikke laste tekstur: %1" @@ -2805,6 +2844,9 @@ msgstr "Send Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Veksle fullskjerm" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Skjermbilde" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index 68bcbc2bfda..b62014ee72b 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -43,7 +43,7 @@ msgid "&Hide status bar" msgstr "&Statusbalk verbergen" msgid "Hide &toolbar" -msgstr "Verberg &toolbar" +msgstr "&Toolbar verbergen" msgid "&Resizeable window" msgstr "&Venster met aanpasbare grootte" @@ -109,7 +109,7 @@ msgid "Fi<er method" msgstr "Filtermethode" msgid "&Nearest" -msgstr "&Dichtsbijzijnde" +msgstr "&Dichtstbijzijnde" msgid "&Linear" msgstr "&Lineair" @@ -220,7 +220,7 @@ msgid "Begin trace" msgstr "Begin traceren" msgid "End trace" -msgstr "Traceren beĂ«indigen" +msgstr "BeĂ«indig traceren" msgid "&Help" msgstr "&Help" @@ -232,19 +232,19 @@ msgid "&About 86Box..." msgstr "&Over 86Box..." msgid "&New image..." -msgstr "&Nieuw image..." +msgstr "&Nieuw imagebestand..." msgid "&Existing image..." -msgstr "&Bestaande image..." +msgstr "&Bestaand imagebestand..." msgid "Existing image (&Write-protected)..." -msgstr "Bestaande image (&Schrijfbeveiligd)..." +msgstr "Bestaand imagebestand (&Schrijfbeveiligd)..." msgid "&Record" msgstr "&Opnemen" msgid "&Play" -msgstr "&Play" +msgstr "&Afspelen" msgid "&Rewind to the beginning" msgstr "&Terugspoelen naar het begin" @@ -256,53 +256,23 @@ msgid "E&ject" msgstr "&Uitwerpen" msgid "&Image..." -msgstr "&Image..." +msgstr "&Imagebestand..." msgid "E&xport to 86F..." msgstr "E&xporteer naar 86F..." msgid "&Mute" -msgstr "&Mute" +msgstr "&Dempen" msgid "E&mpty" -msgstr "E&mpty" +msgstr "&Leeg" msgid "Reload previous image" -msgstr "Herlaad vorige image" +msgstr "Herlaad vorig imagebestand" msgid "&Folder..." msgstr "&Map..." -msgid "Target &framerate" -msgstr "Doel &framerate" - -msgid "&Sync with video" -msgstr "&Synchroniseer met 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 "&Selecteer shader..." - -msgid "&Remove shader" -msgstr "&Remove shader" - msgid "Preferences" msgstr "Voorkeuren" @@ -310,7 +280,7 @@ msgid "Sound Gain" msgstr "Geluidsversterking" msgid "New Image" -msgstr "Nieuw image" +msgstr "Nieuw imagebestand" msgid "Settings" msgstr "Instellingen" @@ -343,7 +313,7 @@ msgid "RPM mode:" msgstr "RPM-modus:" msgid "Progress:" -msgstr "Vooruitgang:" +msgstr "Voortgang:" msgid "Width:" msgstr "Breedte:" @@ -352,7 +322,7 @@ msgid "Height:" msgstr "Hoogte:" msgid "Lock to this size" -msgstr "Leg vast op deze grootte" +msgstr "Vergrendel deze grootte" msgid "Machine type:" msgstr "Machinetype:" @@ -403,10 +373,10 @@ msgid "Dynamic Recompiler" msgstr "Dynamische Recompiler" msgid "CPU frame size" -msgstr "CPU frame grootte" +msgstr "CPU framegrootte" msgid "Larger frames (less smooth)" -msgstr "Groter frames (minder vloeiend)" +msgstr "Grotere frames (minder vloeiend)" msgid "Smaller frames (smoother)" msgstr "Kleinere frames (vloeiender)" @@ -430,7 +400,7 @@ msgid "IBM PS/55 Display Adapter Graphics" msgstr "IBM PS/55 Display Adapter Graphics" msgid "Keyboard:" -msgstr "Toetsenbord" +msgstr "Toetsenbord:" msgid "Keyboard" msgstr "Toetsenbord" @@ -472,13 +442,13 @@ msgid "Sound card #4:" msgstr "Geluidskaart #4:" msgid "MIDI Out Device:" -msgstr "MIDI Out-apparaat:" +msgstr "MIDI Uitvoerapparaat:" msgid "MIDI In Device:" -msgstr "MIDI In-apparaat:" +msgstr "MIDI Invoerapparaat:" msgid "MIDI Out:" -msgstr "Midi Out:" +msgstr "Midi Uit:" msgid "Standalone MPU-401" msgstr "Standalone MPU-401" @@ -550,7 +520,7 @@ msgid "FD Controller:" msgstr "FD-Controller:" msgid "CD-ROM Controller:" -msgstr "CD-ROM controller" +msgstr "CD-ROM controller:" msgid "Tertiary IDE Controller" msgstr "Tertiaire IDE-controller" @@ -603,9 +573,6 @@ msgstr "Kanaal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Specificeer..." - msgid "Sectors:" msgstr "Sectoren:" @@ -649,7 +616,7 @@ msgid "Removable disks:" msgstr "Verwisselbare schijven:" msgid "Removable disk drives:" -msgstr "Verwisselbare schijfstations" +msgstr "Verwisselbare schijfstations:" msgid "ZIP 250" msgstr "ZIP 250" @@ -690,9 +657,6 @@ msgstr "ISABugger-apparaat" msgid "POST card" msgstr "POST-kaart" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Fout" @@ -706,19 +670,19 @@ msgid "Speed" msgstr "Snelheid" msgid "Removable disk %1 (%2): %3" -msgstr "Verwijderbare schijf %1 (%2): %3" +msgstr "Verwijderbare schijf %1 (%2): %3" msgid "&Removable disk %1 (%2): %3" -msgstr "&Verwijderbare schijf %1 (%2): %3" +msgstr "&Verwijderbare schijf %1 (%2): %3" msgid "Removable disk images" -msgstr "Verwijderbare schijf image" +msgstr "Verwijderbaar schijfimagebestand" msgid "Image %1" msgstr "Image %1" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box kon geen bruikbare ROM images vinden.\n\nDownload een ROM set en pak deze uit in de map \"roms\"." +msgstr "86Box kon geen bruikbare ROM imagebestanden vinden.\n\nDownload een ROM set en pak deze uit in de map \"roms\"." msgid "(empty)" msgstr "(leeg)" @@ -814,7 +778,7 @@ msgid "Click to capture mouse" msgstr "Klik om muis vast te leggen" msgid "Press %1 to release mouse" -msgstr "Druk op %1 om de muis los te laten" +msgstr "Druk op %1 om de muis vrij te geven" msgid "Press %1 or middle button to release mouse" msgstr "Druk op %1 of middelste knop om de muis los te laten" @@ -852,9 +816,18 @@ msgstr "Geen PCap-apparaten gevonden" msgid "Invalid PCap device" msgstr "Ongeldig PCap-apparaat" +msgid "Generic paddle controller(s)" +msgstr "Generieke peddelcontroller(s)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick(s) met 2 assen en 1 knoppen" + msgid "2-axis, 2-button joystick(s)" msgstr "Joystick(s) met 2 assen en 2 knoppen" +msgid "2-axis, 3-button joystick" +msgstr "Joystick met 2 assen en 3 knoppen" + msgid "2-axis, 4-button joystick" msgstr "Joystick met 2 assen en 4 knoppen" @@ -867,47 +840,113 @@ msgstr "Joystick met 2 assen en 8 knoppen" msgid "3-axis, 2-button joystick" msgstr "Joystick met 3 assen en 2 knoppen" +msgid "3-axis, 3-button joystick" +msgstr "Joystick met 3 assen en 3 knoppen" + msgid "3-axis, 4-button joystick" msgstr "Joystick met 3 assen en 4 knoppen" +msgid "4-axis, 2-button joystick" +msgstr "Joystick met 4 assen en 2 knoppen" + +msgid "4-axis, 3-button joystick" +msgstr "Joystick met 4 assen en 3 knoppen" + msgid "4-axis, 4-button joystick" msgstr "Joystick met 4 assen en 4 knoppen" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedalen" +msgid "2-button gamepad(s)" +msgstr "2-knops gamepad(s)" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3-knops gamepad" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control systeem" +msgid "4-button gamepad" +msgstr "4-knops gamepad" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Roer Control Systeem" +msgid "6-button gamepad" +msgstr "6-knops gamepad" -msgid "2-button gamepad(s)" -msgstr "2-knops gamepad(s)" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2-knops stuurknuppel" -msgid "4-button gamepad" -msgstr "4-knops gamepad" +msgid "3-button flight yoke" +msgstr "3-knops stuurknuppel" msgid "4-button flight yoke" msgstr "4-knops stuurknuppel" msgid "2-button flight yoke with throttle" -msgstr "2-kops stuurknuppel met gashendel " +msgstr "2-kops stuurknuppel met gashendel" + +msgid "3-button flight yoke with throttle" +msgstr "3-kops stuurknuppel met gashendel" msgid "4-button flight yoke with throttle" -msgstr "2-kops stuurknuppel met gashendel" +msgstr "4-kops stuurknuppel met gashendel" + +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Stuurwiel (3 assen, 2 knoppen)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Stuurwiel (3 assen, 3 knoppen)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Stuurwiel (3 assen, 4 knoppen)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 Stuurwiel (3 assen, 4 knoppen)" +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedalen" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedalen Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedalen" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedalen Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedalen" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedalen Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedalen" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedalen Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control systeem" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Roer Control Systeem" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 met adapter" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 zonder adapter" msgid "None" msgstr "Geen" @@ -973,16 +1012,13 @@ msgid "Do you want to save the settings?" msgstr "Wil je de instellingen opslaan?" msgid "This will hard reset the emulated machine." -msgstr "Dit zal de geĂ«muleerde machine een hard reset geven." +msgstr "Dit zal de geĂ«muleerde machine een harde reset geven." msgid "Save" msgstr "Opslaan" -msgid "About 86Box" -msgstr "Over 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Over %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Een emulator van oude computers\n\nAuteurs: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nMet eerdere bijdragen van Sarah Walker, leilei, JohnElliott, greatpsycho en anderen.\n\nUitgebracht onder de GNU General Public License versie 2 of later. Zie LICENSE voor meer informatie." @@ -1054,10 +1090,10 @@ msgid "Cartridge images" msgstr "Cartridge-images" msgid "Resume execution" -msgstr "Hervat executie" +msgstr "Hervat uitvoering" msgid "Pause execution" -msgstr "Pauze executie" +msgstr "Pauzeer uitvoering" msgid "Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del" @@ -1084,7 +1120,7 @@ msgid "&Start" msgstr "&Start" msgid "Not running" -msgstr "Niet actied" +msgstr "Niet actief" msgid "Running" msgstr "Actief" @@ -1093,10 +1129,10 @@ msgid "Paused" msgstr "Gepauzeerd" msgid "Waiting" -msgstr "aan het wachtend" +msgstr "Aan het wachten" msgid "Powered Off" -msgstr "Sluit af" +msgstr "Uitgeschakeld" msgid "%n running" msgstr "%n actief" @@ -1126,7 +1162,7 @@ msgid "86Box configuration files (86box.cfg)" msgstr "86Box configuratiebestanden (86box.cfg)" msgid "Configuration read failed" -msgstr "Lezen configuratie mislukt" +msgstr "Lezen van configuratie mislukt" msgid "Unable to open the selected configuration file for reading: %1" msgstr "Openen van geselecteerd configuratiebestand voor lezen niet mogelijk: %1" @@ -1138,7 +1174,7 @@ msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM msgstr "%1 machine(s) zijn nu actief. Weet je zeker dat je de VM manager wil afsluiten?" msgid "Add new system wizard" -msgstr "Assistent voor toevoegen van nieuw systeem" +msgstr "Wizard toevoegen van nieuw systeem" msgid "Introduction" msgstr "Introductie" @@ -1186,13 +1222,13 @@ msgid "Directory does not exist" msgstr "Map bestaat niet" msgid "A new directory for the system will be created in the selected directory above" -msgstr "Een nieuwe map voor het systeem wordt aangemaakt in de boven geselecteerde map" +msgstr "Een nieuwe map voor het systeem wordt aangemaakt in de hierboven geselecteerde map" msgid "System location:" msgstr "Systeemlocatie:" msgid "System name and location" -msgstr "Systeemnaam en -locatie" +msgstr "Systeemnaam en locatie" msgid "Enter the name of the system and choose the location" msgstr "Voer de naam in van het systeem en kies een locatie" @@ -1252,7 +1288,7 @@ msgid "Failed to create directory for cloned VM" msgstr "Map aanmaken voor gekloonde VM mislukt" msgid "Failed to clone VM." -msgstr "Kolen van VM mislukt." +msgstr "Klonen van VM mislukt." msgid "Directory in use" msgstr "Map in gebruik" @@ -1303,7 +1339,7 @@ msgid "&Kill" msgstr "&Gedwongen beĂ«indigen" msgid "Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?" -msgstr "Gedwongen beĂ«indiging van een virtuele machine kan dataverlies veroorzaken. Doe dit alleen wanneer het 86Box process is vast gelopen.\n\nWeet je zeker dat je de virtuele machine \"%1\" wil beĂ«indigen?" +msgstr "Gedwongen beĂ«indiging van een virtuele machine kan dataverlies veroorzaken. Doe dit alleen wanneer het 86Box-proces is vast gelopen.\n\nWeet je zeker dat je de virtuele machine \"%1\" wil beĂ«indigen?" msgid "&Delete" msgstr "&Verwijderen" @@ -1332,8 +1368,8 @@ msgstr "Systeem" msgid "Storage" msgstr "Opslag" -msgid "Disk %1: " -msgstr "Schijf %1: " +msgid "Disk %1:" +msgstr "Schijf %1:" msgid "No disks" msgstr "Geen schijven" @@ -1345,10 +1381,10 @@ msgid "Audio:" msgstr "Audio:" msgid "ACPI shutdown" -msgstr "ACPI uitschakeling" +msgstr "ACPI-uitschakeling" msgid "ACP&I shutdown" -msgstr "ACP&I uitschakeling" +msgstr "ACP&I-uitschakeling" msgid "Hard disk (%1)" msgstr "Harde schijf (%1)" @@ -1375,7 +1411,7 @@ msgid "Disk images cannot be larger than 127 GB." msgstr "Schijfimages kunnen niet groter zijn dan 127 GB." msgid "Hard disk images" -msgstr "Harde schijf-image" +msgstr "Harde schijf-images" msgid "Unable to read file" msgstr "Kan bestand niet lezen" @@ -1384,7 +1420,7 @@ msgid "Unable to write file" msgstr "Kan bestand niet schrijven" msgid "HDI or HDX images with a sector size other than 512 are not supported." -msgstr "HDI- of HDX-image met een andere sectorgrootte dan 512 worden niet ondersteund." +msgstr "HDI- of HDX-images met een andere sectorgrootte dan 512 worden niet ondersteund." msgid "Disk image file already exists" msgstr "Schijfimagebestand bestaat al" @@ -1432,7 +1468,7 @@ msgid "Fixed-size VHD" msgstr "VHD met vaste grootte" msgid "Dynamic-size VHD" -msgstr "VHD met dynamisch grootte" +msgstr "VHD met dynamische grootte" msgid "Differencing VHD" msgstr "Verschil-VHD" @@ -1453,7 +1489,7 @@ msgid "Fixed-size VHD (.vhd)" msgstr "VHD met vaste grootte (.vhd)" msgid "Dynamic-size VHD (.vhd)" -msgstr "VHD met dynamisch grootte (.vhd)" +msgstr "VHD met dynamische grootte (.vhd)" msgid "Differencing VHD (.vhd)" msgstr "Verschil-VHD (.vhd)" @@ -1621,7 +1657,7 @@ msgid "Generate" msgstr "Genereren" msgid "Joystick configuration" -msgstr "Joystick configuratie " +msgstr "Joystick configuratie" msgid "Device" msgstr "Apparaat" @@ -1639,7 +1675,7 @@ msgid "List of MCA devices:" msgstr "Lijst van MCA-apparaten:" msgid "&Tablet tool" -msgstr "Tablet-hulpmiddel" +msgstr "&Tablet-hulpmiddel" msgid "About &Qt" msgstr "Over &Qt" @@ -1648,10 +1684,10 @@ msgid "&MCA devices..." msgstr "MCA-apparaten..." msgid "Show non-&primary monitors" -msgstr "Toon niet-primaire monitors" +msgstr "Toon niet-primaire beeldschermen" msgid "Open screenshots &folder..." -msgstr "Map met schermafbeeldingen openen..." +msgstr "&Map met schermafbeeldingen openen..." msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Schakel de volledig scherm-uitrekmodus in bij maximaliseren" @@ -1663,7 +1699,7 @@ msgid "&Pen" msgstr "&Pen" msgid "&Host CD/DVD Drive (%1:)" -msgstr "&Host cd/dvd-station (%1:)" +msgstr "&Host CD/DVD-station (%1:)" msgid "&Connected" msgstr "&Verbonden" @@ -1672,7 +1708,7 @@ msgid "Clear image &history" msgstr "Imagegeschiedenis verwijderen(&H)" msgid "Create..." -msgstr "CreĂ«er..." +msgstr "Aanmaken..." msgid "Host CD/DVD Drive (%1)" msgstr "Host CD/DVD-station (%1)" @@ -1717,10 +1753,10 @@ msgid "Browse..." msgstr "Bladeren..." msgid "Couldn't create OpenGL context." -msgstr "Kan OpenGL context niet aanmaken." +msgstr "Kan OpenGL-context niet aanmaken." msgid "Couldn't switch to OpenGL context." -msgstr "Kan niet overschakelen naar OpenGL context." +msgstr "Kan niet overschakelen naar OpenGL-context." msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" msgstr "OpenGL versie 3.0 of hoger is vereist. De huidige versie is %1.%2" @@ -1746,8 +1782,8 @@ msgstr "Ik heb het verplaatst" msgid "I Copied It" msgstr "Ik heb het gekopieerd" -msgid "86Box Monitor #" -msgstr "86Box Monitor #" +msgid "86Box Monitor #%1" +msgstr "86Box Monitor #%1" msgid "No MCA devices." msgstr "Geen MCA-apparaten." @@ -1782,8 +1818,11 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "VDE-socket:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" -msgstr "86Box apparaattester" +msgstr "86Box Apparaattester" msgid "Novell NetWare 2.x Key Card" msgstr "Novell NetWare 2.x Key Card" @@ -1855,7 +1894,7 @@ msgid "Default Baud rate" msgstr "Standaard baudrate" msgid "[COM] Standard Hayes-compliant Modem" -msgstr "COM] Standaard Hayes-compatibele modem " +msgstr "[COM] Standaard Hayes-compatibele modem" msgid "Roland MT-32 Emulation" msgstr "Roland MT-32-emulatie" @@ -1939,7 +1978,7 @@ msgid "Parallel port IRQ" msgstr "Parallelle poort IRQ" msgid "BIOS Revision" -msgstr "BIOS Revisie" +msgstr "BIOS-Revisie" msgid "BIOS Version" msgstr "BIOS-versie" @@ -2157,12 +2196,6 @@ msgstr "SID-filtersterkte" msgid "Surround module" msgstr "Surroundmodule" -msgid "CODEC" -msgstr "Codec" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Verhoog CODEC interrupt bij CODEC setup (nodig voor sommige stuurprogramma's)" - msgid "SB Address" msgstr "SB-adres" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "OPL inschakelen" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klassiek" - msgid "256 KB" msgstr "256 KB" @@ -2557,16 +2599,16 @@ msgid "Apply overscan deltas" msgstr "Overscan-delta’s toepassen" msgid "Mono Interlaced" -msgstr "Mono geĂ¯nterlaced " +msgstr "Mono Interlaced" msgid "Mono Non-Interlaced" -msgstr "Mono niet geĂ¯nterlaced" +msgstr "Mono Niet-Interlaced" msgid "Color Interlaced" -msgstr "Kleur interlaced" +msgstr "Kleur Interlaced" msgid "Color Non-Interlaced" -msgstr "Kleur niet geĂ¯nterlaced" +msgstr "Kleur Niet-Interlaced" msgid "3Dfx Voodoo Graphics" msgstr "3Dfx Voodoo Graphics" @@ -2653,7 +2695,7 @@ msgid "E&ject %1" msgstr "&Uitwerpen %1" msgid "&Unmute" -msgstr "&Geluid aanzetten" +msgstr "&Dempen opheffen" msgid "Softfloat FPU" msgstr "Softfloat FPU" @@ -2739,9 +2781,6 @@ msgstr "GLSL-fout" msgid "Could not load shader: %1" msgstr "Kon de shader niet laden: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL versie 3.0 of hoger is vereist. Huidige GLSL-versie is %1.%2" - msgid "Could not load texture: %1" msgstr "Kon de textuur niet laden: %1" @@ -2770,7 +2809,7 @@ msgid "Could not load file %1" msgstr "Kon bestand %1 niet laden" msgid "Key Bindings:" -msgstr "Toetskoppelingen" +msgstr "Toetskoppelingen:" msgid "Action" msgstr "Actie" @@ -2779,7 +2818,7 @@ msgid "Keybind" msgstr "Toetskoppeling" msgid "Clear binding" -msgstr "Wis koppelinh" +msgstr "Wis koppeling" msgid "Bind" msgstr "Koppel" @@ -2794,7 +2833,7 @@ msgid "Bind conflict" msgstr "Koppelconflict" msgid "This key combo is already in use." -msgstr "Deze toetsencombinatie is al in gebruik" +msgstr "Deze toetsencombinatie is al in gebruik." msgid "Send Control+Alt+Del" msgstr "Stuur Control+Alt+Del" @@ -2805,6 +2844,9 @@ msgstr "Stuur Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Volledig scherm omschakelen" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Schermafbeelding" @@ -2812,7 +2854,7 @@ msgid "Release mouse pointer" msgstr "Geef muis vrij" msgid "Toggle pause" -msgstr "Pause omschakelen" +msgstr "Pauzeren omschakelen" msgid "Toggle mute" msgstr "Geluiddemping omschakelen" @@ -2833,13 +2875,13 @@ msgid "Remote Switch" msgstr "Externe Switch" msgid "Switch:" -msgstr "Switch" +msgstr "Switch:" msgid "Hub Mode" msgstr "Hub-modus" msgid "Hostname:" -msgstr "Hostname" +msgstr "Hostnaam:" msgid "ISA RAM:" msgstr "ISA RAM:" @@ -2863,10 +2905,10 @@ msgid "An error occurred trying to wipe the NVRAM contents of the virtual machin msgstr "Fout bij Wissen van NVRAM-inhoud van de virtuele machine \"%1\"" msgid "%1 VM Manager" -msgstr "%1 VM Manager" +msgstr "%1 VM Beheerder" msgid "%n disk(s)" -msgstr "%n schijf(en)" +msgstr "%n schijf/schijven" msgid "Unknown Status" msgstr "Onbekende Status" @@ -2875,7 +2917,7 @@ msgid "No Machines Found!" msgstr "Geen Machines Gevonden!" msgid "Check for updates on startup" -msgstr "Controleer op updates bij start" +msgstr "Controleer op updates bij starten" msgid "Unable to determine release information" msgstr "Kan release-informatie niet bepalen" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 4398dcafbcc..97d0afb605d 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -273,36 +273,6 @@ msgstr "PrzeÅ‚aduj poprzedni obraz" msgid "&Folder..." msgstr "&Folder..." -msgid "Target &framerate" -msgstr "Docelowa &liczba klatek na sekundÄ™" - -msgid "&Sync with video" -msgstr "&Zsynchronizuj z 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 "&Wybierz shader..." - -msgid "&Remove shader" -msgstr "&UsuÅ„ shader" - msgid "Preferences" msgstr "Preferencje" @@ -603,9 +573,6 @@ msgstr "KanaÅ‚:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&OkreÅ›l..." - msgid "Sectors:" msgstr "Sektory:" @@ -690,9 +657,6 @@ msgstr "UrzÄ…dzenie ISABugger" msgid "POST card" msgstr "Karta POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Błąd" @@ -852,8 +816,17 @@ msgstr "Nie znaleziono urzÄ…dzeÅ„ PCap" msgid "Invalid PCap device" msgstr "NieprawidÅ‚owe urzÄ…dzenie PCap" +msgid "Generic paddle controller(s)" +msgstr "Generyczny kontroler paddle" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick(i) 2-osiowe, 1-przyciskowe" + msgid "2-axis, 2-button joystick(s)" -msgstr "Joysticki 2-osiowe, 2-przyciskowe" +msgstr "Joystick(i) 2-osiowe, 2-przyciskowe" + +msgid "2-axis, 3-button joystick" +msgstr "Joystick 2-osiowy, 3-przyciskowy" msgid "2-axis, 4-button joystick" msgstr "Joystick 2-osiowy, 4-przyciskowy" @@ -867,35 +840,41 @@ msgstr "Joystick 2-osiowy, 8-przyciskowy" msgid "3-axis, 2-button joystick" msgstr "Joystick 3-osiowy, 2-przyciskowy" +msgid "3-axis, 3-button joystick" +msgstr "Joystick 3-osiowy, 2-przyciskowy" + msgid "3-axis, 4-button joystick" msgstr "Joystick 3-osiowy, 4-przyciskowy" +msgid "4-axis, 2-button joystick" +msgstr "Joystick 4-osiowy, 2-przyciskowy" + +msgid "4-axis, 3-button joystick" +msgstr "Joystick 4-osiowy, 3-przyciskowy" + msgid "4-axis, 4-button joystick" msgstr "Joystick 4-osiowy, 4-przyciskowy" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "Pad(y) z dwoma przyciskami" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Pad z trzema przyciskami" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Pad z czterema przyciskami" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "Pad z szeÅ›cioma przyciskami" -msgid "2-button gamepad(s)" -msgstr "Pad(y) z dwoma przyciskami" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Wolant z dwoma przyciskami" -msgid "4-button gamepad" -msgstr "Pad z czterema przyciskami" +msgid "3-button flight yoke" +msgstr "Wolant z trzema guzikami" msgid "4-button flight yoke" msgstr "Wolant z czterema przyciskami" @@ -903,11 +882,71 @@ msgstr "Wolant z czterema przyciskami" msgid "2-button flight yoke with throttle" msgstr "Wolant z dwoma przyciskami i przepustnicÄ…" +msgid "3-button flight yoke with throttle" +msgstr "Wolant z trzema przyciskami i przepustnicÄ…" + msgid "4-button flight yoke with throttle" msgstr "Wolant z czterema przyciskami i przepustnicÄ…" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Kierownica Win95 (3 osie, 4 przyciski)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Kierownica (3 osie, 2 przyciski)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Kierownica (3 osie, 3 przyciski)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Kierownica (3 osie, 4 przyciski)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 z adapterem" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 bez adaptera" msgid "None" msgstr "Å»aden" @@ -978,11 +1017,8 @@ msgstr "To spowoduje twardy reset wirtualnej maszyny." msgid "Save" msgstr "Zapisz" -msgid "About 86Box" -msgstr "O 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "O %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, i inni.\n\nZ wczeÅ›niejszym wkÅ‚adem od Sarah Walker, leilei, JohnElliott, greatpsycho i innych.\n\nPrzetÅ‚umaczony przez: Lili1228\n\nWydany na licencji GNU General Public License w wersji 2 lub nowszej. Zobacz LICENSE aby uzyskać wiÄ™cej informacji." @@ -1332,8 +1368,8 @@ msgstr "System" msgid "Storage" msgstr "Pamięć" -msgid "Disk %1: " -msgstr "Dysk %1: " +msgid "Disk %1:" +msgstr "Dysk %1:" msgid "No disks" msgstr "Brak dyskĂ³w" @@ -1746,8 +1782,8 @@ msgstr "ZostaÅ‚a przeniesiona" msgid "I Copied It" msgstr "ZostaÅ‚a skopiowana" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box Monitor %1" msgid "No MCA devices." msgstr "Brak urzÄ…dzeÅ„ MCA." @@ -1782,6 +1818,9 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "Gniazdo VDE:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "Tester urzÄ…dzeÅ„ 86Box" @@ -2157,12 +2196,6 @@ msgstr "SiÅ‚a filtra SID" msgid "Surround module" msgstr "ModuÅ‚ Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "PodnieÅ› przerwanie CODEC podczas konfiguracji CODEC-a (wymagane przez niektĂ³re sterowniki)" - msgid "SB Address" msgstr "Adres SB" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "Włącz OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klasyczny" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "Błąd GLSL" msgid "Could not load shader: %1" msgstr "Nie udaÅ‚o siÄ™ wczytać shadera: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Wymagana jest wersja OpenGL 3.0 lub wyższa. Aktualna wersja GLSL to %1.%2" - msgid "Could not load texture: %1" msgstr "Nie udaÅ‚o siÄ™ wczytać tekstury: %1" @@ -2805,6 +2844,9 @@ msgstr "WyÅ›lij Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Przełącz peÅ‚ny ekran" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Zrzut ekranu" @@ -2977,19 +3019,19 @@ msgid "Export EDID" msgstr "Eksportuj EDID" msgid "EDID file \"%ls\" is too large." -msgstr "Plik EDID \"%ls\" jest zbyt duży." +msgstr "Plik EDID â€%ls†jest zbyt duży." msgid "OpenGL input scale" -msgstr "Skala wejÅ›ciowa OpenGL" +msgstr "Skala wejÅ›cia OpenGL" msgid "OpenGL input stretch mode" -msgstr "Tryb rozciÄ…gania wejÅ›ciowego OpenGL" +msgstr "Tryb rozciÄ…gania wejÅ›cia OpenGL" msgid "Color scheme" msgstr "Schemat kolorĂ³w" msgid "Light" -msgstr "ÅwiatÅ‚o" +msgstr "Jasny" msgid "Dark" msgstr "Ciemny" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 010005780e4..d8fddc787fa 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -273,36 +273,6 @@ msgstr "Recarregar imagem anterior" msgid "&Folder..." msgstr "&Pasta..." -msgid "Target &framerate" -msgstr "&Taxa de quadros 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" @@ -603,9 +573,6 @@ msgstr "Canal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Especificar..." - msgid "Sectors:" msgstr "Setores:" @@ -690,9 +657,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa de diagnĂ³stico" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Erro" @@ -784,7 +748,7 @@ msgid "Parallel ports:" msgstr "Portas Paralelas:" msgid "Storage controllers" -msgstr "Controladores de armaz." +msgstr "Controladores de armazenamento" msgid "Hard disks" msgstr "Discos rĂ­gidos" @@ -802,7 +766,7 @@ msgid "Floppy & CD-ROM drives" msgstr "Disquete & CD-ROM" msgid "Other removable devices" -msgstr "Dispos. removĂ­veis" +msgstr "Outros dispositivos removĂ­veis" msgid "Other peripherals" msgstr "Outros perifĂ©ricos" @@ -852,9 +816,18 @@ msgstr "Nenhum dispositivo PCap encontrado" msgid "Invalid PCap device" msgstr "Dispositivo PCap invĂ¡lido" +msgid "Generic paddle controller(s)" +msgstr "Controlador(es) genĂ©rico(s) de raquete" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick(s) de 2 eixos, 1 botões" + msgid "2-axis, 2-button joystick(s)" msgstr "Joystick(s) de 2 eixos, 2 botões" +msgid "2-axis, 3-button joystick" +msgstr "Joystick de 2 eixos, 3 botões" + msgid "2-axis, 4-button joystick" msgstr "Joystick de 2 eixos, 4 botões" @@ -867,35 +840,41 @@ msgstr "Joystick de 2 eixos, 8 botões" msgid "3-axis, 2-button joystick" msgstr "Joystick de 3 eixos, 2 botões" +msgid "3-axis, 3-button joystick" +msgstr "Joystick de 3 eixos, 3 botões" + msgid "3-axis, 4-button joystick" msgstr "Joystick de 3 eixos, 4 botões" +msgid "4-axis, 2-button joystick" +msgstr "Joystick de 4 eixos, 2 botões" + +msgid "4-axis, 3-button joystick" +msgstr "Joystick de 4 eixos, 3 botões" + msgid "4-axis, 4-button joystick" msgstr "Joystick de 4 eixos, 4 botões" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + Pedais CH" +msgid "2-button gamepad(s)" +msgstr "Gamepad(s) de 2 botões" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Gamepad de 3 botões" -msgid "Thrustmaster Flight Control System" -msgstr "Sistema de Controle de Voo Thrustmaster" +msgid "4-button gamepad" +msgstr "Gamepad de 4 botões" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "SCV Thrustmaster + Sistema de Controle de Leme" +msgid "6-button gamepad" +msgstr "Gamepad de 6 botões" -msgid "2-button gamepad(s)" -msgstr "Gamepad(s) de 2 botões" +msgid "Gravis PC GamePad" +msgstr "GamePad Gravis PC" msgid "2-button flight yoke" msgstr "Manche de voo de 2 botões" -msgid "4-button gamepad" -msgstr "Gamepad de 4 botões" +msgid "3-button flight yoke" +msgstr "Manche de voo de 3 botões" msgid "4-button flight yoke" msgstr "Manche de voo de 4 botões" @@ -903,11 +882,71 @@ msgstr "Manche de voo de 4 botões" msgid "2-button flight yoke with throttle" msgstr "Manche de voo de 2 botões com acelerador" +msgid "3-button flight yoke with throttle" +msgstr "Manche de voo de 3 botões com acelerador" + msgid "4-button flight yoke with throttle" msgstr "Manche de voo de 4 botões com acelerador" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volante Win95 (3 eixos, 4 botões)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volante (3 eixos, 2 botões)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volante (3 eixos, 3 botões)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volante (3 eixos, 4 botões)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + Pedais CH" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + Pedais CH Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + Pedais CH" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + Pedais CH Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + Pedais CH" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + Pedais CH Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + Pedais CH" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + Pedais CH Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Sistema de Controle de Voo Thrustmaster" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "SCV Thrustmaster + Sistema de Controle de Leme" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 com adaptador" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 sem adaptador" msgid "None" msgstr "Nenhum" @@ -978,11 +1017,8 @@ 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 "About %1" +msgstr "Sobre o %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, e outros.\n\nCom contribuições anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho, e outros.\n\nTraduzido por: Altieres Lima da Silva, Nelson K. Hennemann Filho\n\nLançado sob a Licença PĂºblica Geral GNU, versĂ£o 2 ou posterior. Veja o arquivo LICENSE para mais informações." @@ -1332,8 +1368,8 @@ msgstr "Sistema" msgid "Storage" msgstr "Armazenamento" -msgid "Disk %1: " -msgstr "Disco %1: " +msgid "Disk %1:" +msgstr "Disco %1:" msgid "No disks" msgstr "Sem discos" @@ -1746,8 +1782,8 @@ msgstr "Movi" msgid "I Copied It" msgstr "Copiei" -msgid "86Box Monitor #" -msgstr "Monitor 86Box nº" +msgid "86Box Monitor #%1" +msgstr "Monitor 86Box nº%1" msgid "No MCA devices." msgstr "Nenhum dispositivo MCA." @@ -1782,6 +1818,9 @@ msgstr "Adaptador:" msgid "VDE Socket:" msgstr "Soquete VDE:" +msgid "TAP Bridge Device:" +msgstr "Dispositivo Ponte TAP:" + msgid "86Box Unit Tester" msgstr "Testador de unidade 86Box" @@ -2157,12 +2196,6 @@ msgstr "Força do Filtro SID" msgid "Surround module" msgstr "MĂ³dulo surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Aumentar a interrupĂ§Ă£o do CODEC na configuraĂ§Ă£o do CODEC (necessĂ¡rio para alguns drivers)" - msgid "SB Address" msgstr "Endereço da SB" @@ -2178,6 +2211,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ RTC" + +msgid "RTC Port Address" +msgstr "Endereço Porta RTC" + +msgid "Onboard RTC" +msgstr "RTC Integrado" + +msgid "Not installed" +msgstr "NĂ£o instalado" + msgid "Enable OPL" msgstr "Ativar OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (estĂ©reo)" -msgid "Classic" -msgstr "ClĂ¡ssico" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "Erro GLSL" msgid "Could not load shader: %1" msgstr "NĂ£o foi possĂ­vel carregar o shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL versĂ£o 3.0 ou superior Ă© exigido. VersĂ£o atual GLSL Ă© %1.%2" - msgid "Could not load texture: %1" msgstr "NĂ£o foi possĂ­vel carregar a textura: %1" @@ -2805,6 +2844,9 @@ msgstr "Enviar Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Alternar tela cheia" +msgid "Toggle UI in fullscreen" +msgstr "Alternar interface em tela cheia" + msgid "Screenshot" msgstr "Captura de tela" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index a33ba0119ad..177ef25f62f 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -1,8 +1,15 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Portuguese (Portugal) \n" +"Language: pt-PT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: pt_PT\n" "X-Source-Language: en_US\n" @@ -178,7 +185,7 @@ msgid "BT&709 (HDTV)" msgstr "BT&709 (HDTV)" msgid "&Average" -msgstr "&Media" +msgstr "&MĂ©dia" msgid "CGA/PCjr/Tandy/E&GA/(S)VGA overscan" msgstr "Overscan de CGA/PCjr/Tandy/E&GA/(S)VGA" @@ -273,36 +280,6 @@ msgstr "Recarregar imagem anterior" msgid "&Folder..." msgstr "&Pasta..." -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" @@ -364,7 +341,7 @@ msgid "Configure" msgstr "Configurar" msgid "CPU:" -msgstr "" +msgstr "Processador:" msgid "CPU type:" msgstr "Tipo do CPU:" @@ -603,9 +580,6 @@ msgstr "Canal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Especificar..." - msgid "Sectors:" msgstr "Sectores:" @@ -690,9 +664,6 @@ msgstr "Dispositivo ISABugger" msgid "POST card" msgstr "Placa POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Erro" @@ -721,7 +692,7 @@ msgid "86Box could not find any usable ROM images.\n\nPlease descarregue um pacote ROM e instale-o na pasta \"roms\"." msgid "(empty)" -msgstr "(empty)" +msgstr "(vazio)" msgid "All files" msgstr "Todos os ficheiros" @@ -852,9 +823,18 @@ msgstr "NĂ£o foi encontrado um dispositivo PCap" msgid "Invalid PCap device" msgstr "Dispositivo PCap invĂ¡lido" +msgid "Generic paddle controller(s)" +msgstr "COntrolador(es) genĂ©rico(s) tipo pĂ¡" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Joystick(s) de 2 eixos, 1 botões" + msgid "2-axis, 2-button joystick(s)" msgstr "Joystick(s) de 2 eixos, 2 botões" +msgid "2-axis, 3-button joystick" +msgstr "Joystick de 2 eixos, 3 botões" + msgid "2-axis, 4-button joystick" msgstr "Joystick de 2 eixos, 4 botões" @@ -867,35 +847,41 @@ msgstr "Joystick de 2 eixos, 8 botões" msgid "3-axis, 2-button joystick" msgstr "Joystick de 3 eixos, 2 botões" +msgid "3-axis, 3-button joystick" +msgstr "Joystick de 3 eixos, 3 botões" + msgid "3-axis, 4-button joystick" msgstr "Joystick de 3 eixos, 4 botões" +msgid "4-axis, 2-button joystick" +msgstr "Joystick de 4 eixos, 2 botões" + +msgid "4-axis, 3-button joystick" +msgstr "Joystick de 4 eixos, 3 botões" + msgid "4-axis, 4-button joystick" msgstr "Joystick de 4 eixos, 4 botões" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "ManĂ­pulo(s) de jogos de 2 botões" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "ManĂ­pulo(s) de jogos de 3 botões" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "ManĂ­pulo(s) de jogos de 4 botões" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "ManĂ­pulo(s) de jogos de 6 botões" -msgid "2-button gamepad(s)" -msgstr "ManĂ­pulo(s) de jogos de 2 botões" +msgid "Gravis PC GamePad" +msgstr "GamePad Gravis PC" msgid "2-button flight yoke" msgstr "ManĂ­pulo de voo de 2 botões" -msgid "4-button gamepad" -msgstr "ManĂ­pulo(s) de jogos de 4 botões" +msgid "3-button flight yoke" +msgstr "ManĂ­pulo de voo de 2 botões" msgid "4-button flight yoke" msgstr "ManĂ­pulo de voo de 4 botões" @@ -903,11 +889,71 @@ msgstr "ManĂ­pulo de voo de 4 botões" msgid "2-button flight yoke with throttle" msgstr "ManĂ­pulo de voo de 2 botões com acelerador" +msgid "3-button flight yoke with throttle" +msgstr "ManĂ­pulo de voo de 3 botões com acelerador" + msgid "4-button flight yoke with throttle" msgstr "ManĂ­pulo de voo de 4 botões com acelerador" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volante Win95 (de 3 eixos, 4 botões)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volante (de 3 eixos, 2 botões)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volante (de 3 eixos, 3 botões)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volante (de 3 eixos, 4 botões)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + Pedais CH" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + Pedais CH Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + Pedais CH" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + Pedais CH Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + Pedais CH" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + Pedais CH Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Sistema de controlo de voo Thrustmaster" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "SCV Thrustmaster + Sistema de controlo do leme" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 com adaptador" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 sem adaptador" msgid "None" msgstr "Nenhum" @@ -958,7 +1004,7 @@ msgid "&File" msgstr "F&icheiro" msgid "&New machine..." -msgstr "&Nova mĂ¡quina" +msgstr "&Nova mĂ¡quina..." msgid "&Check for updates..." msgstr "&Verificar para atualizações..." @@ -978,11 +1024,8 @@ 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 "About %1" +msgstr "Acerca do %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nCom contribuições anteriores de Sarah Walker, leilei, JohnElliott, greatpsycho e outros.\n\nUsado sob a licença GNU General Public License versĂ£o 2 ou posterior. Veja o ficheiro LICENSE para mais informações." @@ -1027,7 +1070,7 @@ msgid "GLSL shaders" msgstr "Shaders GLSL" msgid "You are loading an unsupported configuration" -msgstr "EstĂ¡ a carregar uma configuraĂ§Ă£o sem suporte!" +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." @@ -1135,7 +1178,7 @@ msgid "Use regular expressions in search box" msgstr "Usa expressões regulares na caixa de procura" msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?" -msgstr "%1 mĂ¡quina(s) estĂ£o actualmente activas. Quer mesmo sair do gerenciador de MVs" +msgstr "%1 mĂ¡quina(s) estĂ£o actualmente activas. Quer mesmo sair do gerenciador de MVs?" msgid "Add new system wizard" msgstr "Assistende de adicionamento do novo sistema" @@ -1332,8 +1375,8 @@ msgstr "Sistema" msgid "Storage" msgstr "Armazenamento" -msgid "Disk %1: " -msgstr "Disco %1: " +msgid "Disk %1:" +msgstr "Disco %1:" msgid "No disks" msgstr "Sem discos" @@ -1354,7 +1397,7 @@ msgid "Hard disk (%1)" msgstr "Disco rĂ­gido (%1)" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram!" +msgstr "Unidades CD-ROM com barramento MFM/RLL ou ESDI nunca existiram" msgid "Custom..." msgstr "Personalizado..." @@ -1474,7 +1517,7 @@ msgid "This could mean that the parent image was modified after the differencing 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!" +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." @@ -1657,7 +1700,7 @@ msgid "Appl&y fullscreen stretch mode when maximized" msgstr "Apl&icar o modo de estiramento na tela cheia quando maximizado" msgid "&Cursor/Puck" -msgstr "&Cursor/Puck" +msgstr "&Cursor/Disco" msgid "&Pen" msgstr "C&aneta" @@ -1702,7 +1745,7 @@ msgid " fps" msgstr " fps" msgid "VSync" -msgstr "VSync" +msgstr "SincronizaĂ§Ă£o vertical" msgid "Synchronize with video" msgstr "Sincronizar com vĂ­deo" @@ -1746,8 +1789,8 @@ msgstr "Movi-a" msgid "I Copied It" msgstr "Copiei-a" -msgid "86Box Monitor #" -msgstr "Monitor 86Box " +msgid "86Box Monitor #%1" +msgstr "Monitor 86Box %1" msgid "No MCA devices." msgstr "NĂ£o hĂ¡ dispositivos MCA." @@ -1782,6 +1825,9 @@ msgstr "Adaptador:" msgid "VDE Socket:" msgstr "Tomada VDE:" +msgid "TAP Bridge Device:" +msgstr "Dispositivo Ponte TAP:" + msgid "86Box Unit Tester" msgstr "Testador de unidades 86Box" @@ -2157,12 +2203,6 @@ msgstr "Força do filtro do SID" msgid "Surround module" msgstr "MĂ³dulo Surround" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Ativar a interrupĂ§Ă£o do CODEC na configuraĂ§Ă£o do CODEC (necessĂ¡rio para alguns controladores)" - msgid "SB Address" msgstr "Endereço SB" @@ -2178,6 +2218,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "IRQ RTC" + +msgid "RTC Port Address" +msgstr "Endereço Porta RTC" + +msgid "Onboard RTC" +msgstr "RTC Integrado" + +msgid "Not installed" +msgstr "NĂ£o instalado" + msgid "Enable OPL" msgstr "Ativar OPL" @@ -2266,7 +2318,7 @@ msgid "Video chroma-keying" msgstr "Utilizar a chave chroma do vĂ­deo" msgid "Dithering" -msgstr "Dithering" +msgstr "Pontilhamento" msgid "Enable NMI for CGA emulation" msgstr "Ativar NMI para emulaĂ§Ă£o CGA" @@ -2448,9 +2500,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (estĂ©reo)" -msgid "Classic" -msgstr "ClĂ¡ssico" - msgid "256 KB" msgstr "256 KB" @@ -2707,7 +2756,7 @@ msgid "Unable to find Dot-Matrix fonts" msgstr "NĂ£o foi possĂ­vel encontrar os fontes matriciais de pontos" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P 2 Dot-Matrix Printer." -msgstr "As fontes TrueType no diretĂ³rio \"roms/printer/fonts\" sĂ£o necessĂ¡rias para a emulaĂ§Ă£o da impressora matricial de pontos ESC/P 2 genĂ©rica" +msgstr "As fontes TrueType no diretĂ³rio \"roms/printer/fonts\" sĂ£o necessĂ¡rias para a emulaĂ§Ă£o da impressora matricial de pontos ESC/P 2 genĂ©rica." msgid "Inhibit multimedia keys" msgstr "Deshabilitar teclas de multimĂ­dia" @@ -2739,9 +2788,6 @@ msgstr "Erro de GLSL" msgid "Could not load shader: %1" msgstr "NĂ£o foi possĂ­vel carregar o shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "É requerida a versĂ£o 3.0 ou mais nova do OpenGL. A versĂ£o actual de GLSL Ă© %1.%2" - msgid "Could not load texture: %1" msgstr "NĂ£o foi possĂ­vel carregar a textura: %1" @@ -2805,6 +2851,9 @@ msgstr "Enviar Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Alternar o modo em ecrĂ£ cheio" +msgid "Toggle UI in fullscreen" +msgstr "Alternar interface do utilizador em ecrĂ£ inteiro" + msgid "Screenshot" msgstr "Captura de ecrĂ£" @@ -2833,7 +2882,7 @@ msgid "Remote Switch" msgstr "Comutador remoto" msgid "Switch:" -msgstr "Comutador" +msgstr "Comutador:" msgid "Hub Mode" msgstr "Modo de concentrador" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 2d71499dc4e..0b20956e747 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -76,13 +76,13 @@ msgid "&Window scale factor" msgstr "&ĐœĐ°ÑÑˆÑ‚Đ°Đ± Đ¾ĐºĐ½Đ°" msgid "&0.5x" -msgstr "&0.5x" +msgstr "&0,5x" msgid "&1x" msgstr "&1x" msgid "1.&5x" -msgstr "1.&5x" +msgstr "1,&5x" msgid "&2x" msgstr "&2x" @@ -273,36 +273,6 @@ msgstr "ĐŸĐµÑ€ĐµĐ·Đ°Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¹ Đ¾Đ±Ñ€Đ°Đ·" msgid "&Folder..." 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 "ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Ñ‹" @@ -460,16 +430,16 @@ msgid "Joystick 4..." msgstr "Đ”Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº 4..." msgid "Sound card #1:" -msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 1:" +msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 1:" msgid "Sound card #2:" -msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 2:" +msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 2:" msgid "Sound card #3:" -msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 3:" +msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 3:" msgid "Sound card #4:" -msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 4:" +msgstr "Đ—Đ²ÑƒĐºĐ¾Đ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 4:" msgid "MIDI Out Device:" msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Đ²Ñ‹Đ²Đ¾Đ´Đ° MIDI:" @@ -603,9 +573,6 @@ msgstr "ĐĐ°Đ½Đ°Đ»:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Đ£ĐºĐ°Đ·Đ°Ñ‚ÑŒ..." - msgid "Sectors:" msgstr "Đ¡ĐµĐºÑ‚Đ¾Ñ€Ñ‹:" @@ -690,9 +657,6 @@ msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ ISABugger" msgid "POST card" msgstr "ĐĐ°Ñ€Ñ‚Đ° POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "ĐÑˆĐ¸Đ±ĐºĐ°" @@ -718,7 +682,7 @@ msgid "Image %1" msgstr "ĐĐ±Ñ€Đ°Đ· %1" 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\"." +msgstr "86Box Đ½Đµ ÑĐ¼Đ¾Đ³ Đ½Đ°Đ¹Ñ‚Đ¸ Đ½Đ¸ Đ¾Đ´Đ½Đ¾Đ³Đ¾ Đ¿Đ¾Đ´Ñ…Đ¾Đ´ÑÑ‰ĐµĐ³Đ¾ Đ´Đ»Ñ Đ¸ÑĐ¿Đ¾Đ»ÑŒĐ·Đ¾Đ²Đ°Đ½Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° Ñ ĐŸĐ—Đ£.\n\nĐŸĐ¾Đ¶Đ°Đ»ÑƒĐ¹ÑÑ‚Đ° ÑĐºĐ°Ñ‡Đ°Đ¹Ñ‚Đµ Đ½Đ°Đ±Đ¾Ñ€ ĐŸĐ—Đ£ и Đ¸Đ·Đ²Đ»ĐµĐºĐ¸Ñ‚Đµ ĐµĐ³Đ¾ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ «roms»." msgid "(empty)" msgstr "(Đ¿ÑƒÑÑ‚Đ¾)" @@ -745,16 +709,16 @@ 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. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ¸Đµ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½ÑƒÑ ÑиÑÑ‚ĐµĐ¼Đ½ÑƒÑ Đ¿Đ»Đ°Ñ‚Ñƒ." +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. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ¸Đµ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½ÑƒÑ Đ²Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Ñƒ." +msgstr "Đ’Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° из-за Đ¾Ñ‚ÑутÑÑ‚Đ²Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° ĐµÑ‘ ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đµ roms/video. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ¸Đµ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½ÑƒÑ Đ²Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Ñƒ." msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "Đ’Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° 2 \"%hs\" Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° из-за Đ¾Ñ‚ÑутÑÑ‚Đ²Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° ĐµÑ‘ ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đµ roms/video. Đ’Ñ‚Đ¾Ñ€Đ°Ñ Đ²Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° Đ¾Ñ‚ĐºĐ»ÑÑ‡ĐµĐ½Đ°." +msgstr "Đ’Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° 2 «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° из-за Đ¾Ñ‚ÑутÑÑ‚Đ²Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° ĐµÑ‘ ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đµ roms/video. Đ’Ñ‚Đ¾Ñ€Đ°Ñ Đ²Đ¸Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° Đ¾Ñ‚ĐºĐ»ÑÑ‡ĐµĐ½Đ°." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ \"%hs\" Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ¾ из-за Đ¾Ñ‚ÑутÑÑ‚Đ²Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° ĐµĐ³Đ¾ ĐŸĐ—Đ£. Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Đ¿Ñ€Đ¾Đ¸Đ³Đ½Đ¾Ñ€Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¾." +msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ¾ из-за Đ¾Ñ‚ÑутÑÑ‚Đ²Đ¸Ñ Ñ„Đ°Đ¹Đ»Đ° ĐµĐ³Đ¾ ĐŸĐ—Đ£. Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Đ¿Ñ€Đ¾Đ¸Đ³Đ½Đ¾Ñ€Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ¾." msgid "Machine" msgstr "ĐĐ¾Đ¼Đ¿ÑŒÑÑ‚ĐµÑ€" @@ -852,9 +816,18 @@ msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ° PCap Đ½Đµ Đ½Đ°Đ¹Đ´ĐµĐ½Ñ‹" msgid "Invalid PCap device" msgstr "ĐĐµĐ²ĐµÑ€Đ½Đ¾Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ PCap" +msgid "Generic paddle controller(s)" +msgstr "Đ¡Ñ‚Đ°Đ½Đ´Đ°Ñ€Ñ‚Đ½Ñ‹Đ¹ ĐºĐ¾Đ½Ñ‚Ñ€Đ¾Đ»Đ»ĐµÑ€-ĐºĐ¾Đ»ĐµÑĐ¾" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-Đ¾ÑĐµĐ²Đ¾Đ¹, 1-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "2-axis, 2-button joystick(s)" msgstr "2-Đ¾ÑĐµĐ²Đ¾Đ¹, 2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "2-axis, 3-button joystick" +msgstr "2-Đ¾ÑĐµĐ²Đ¾Đ¹, 3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "2-axis, 4-button joystick" msgstr "2-Đ¾ÑĐµĐ²Đ¾Đ¹, 4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" @@ -867,47 +840,113 @@ msgstr "2-Đ¾ÑĐµĐ²Đ¾Đ¹, 8-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" msgid "3-axis, 2-button joystick" msgstr "3-Đ¾ÑĐµĐ²Đ¾Đ¹, 2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "3-axis, 3-button joystick" +msgstr "3-Đ¾ÑĐµĐ²Đ¾Đ¹, 3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "3-axis, 4-button joystick" msgstr "3-Đ¾ÑĐµĐ²Đ¾Đ¹, 4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "4-axis, 2-button joystick" +msgstr "4-Đ¾ÑĐµĐ²Đ¾Đ¹, 2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + +msgid "4-axis, 3-button joystick" +msgstr "4-Đ¾ÑĐµĐ²Đ¾Đ¹, 3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "4-axis, 4-button joystick" msgstr "4-Đ¾ÑĐµĐ²Đ¾Đ¹, 4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "2-button gamepad(s)" +msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" + +msgid "3-button gamepad" +msgstr "3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" + +msgid "4-button gamepad" +msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" + +msgid "6-button gamepad" +msgstr "6-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" + +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" + +msgid "2-button flight yoke" +msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ»" + +msgid "3-button flight yoke" +msgstr "3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ»" + +msgid "4-button flight yoke" +msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ»" + +msgid "2-button flight yoke with throttle" +msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ» Ñ Đ´Ñ€Đ¾ÑÑĐµĐ»ĐµĐ¼" + +msgid "3-button flight yoke with throttle" +msgstr "3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ» Ñ Đ´Ñ€Đ¾ÑÑĐµĐ»ĐµĐ¼" + +msgid "4-button flight yoke with throttle" +msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ ÑˆÑ‚ÑƒÑ€Đ²Đ°Đ» Ñ Đ´Ñ€Đ¾ÑÑĐµĐ»ĐµĐ¼" + +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Đ ÑƒĐ»ÑŒ (3-Đ¾ÑĐµĐ²Đ¾Đ¹, 2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Đ ÑƒĐ»ÑŒ (3-Đ¾ÑĐµĐ²Đ¾Đ¹, 3-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Đ ÑƒĐ»ÑŒ (3-Đ¾ÑĐµĐ²Đ¾Đ¹, 4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH ĐŸĐµĐ´Đ°Đ»Đ¸" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH ĐŸĐµĐ´Đ°Đ»Đ¸ Pro" + msgid "CH Flightstick Pro" msgstr "CH Flightstick Pro" msgid "CH Flightstick Pro + CH Pedals" msgstr "CH Flightstick Pro + CH ĐŸĐµĐ´Đ°Đ»Đ¸" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH ĐŸĐµĐ´Đ°Đ»Đ¸ Pro" -msgid "Thrustmaster Flight Control System" -msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Đ¿Đ¾Đ»Ñ‘Ñ‚Đ¾Đ¼ Thrustmaster" +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Ñ€ÑƒĐ»ĐµĐ¼" +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH ĐŸĐµĐ´Đ°Đ»Đ¸" -msgid "2-button gamepad(s)" -msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH ĐŸĐµĐ´Đ°Đ»Đ¸ Pro" -msgid "2-button flight yoke" -msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ flight yoke" +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" -msgid "4-button gamepad" -msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH ĐŸĐµĐ´Đ°Đ»Đ¸" -msgid "4-button flight yoke" -msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ flight yoke" +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH ĐŸĐµĐ´Đ°Đ»Đ¸ Pro" -msgid "2-button flight yoke with throttle" -msgstr "2-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ flight yoke Ñ Đ´Ñ€Đ¾ÑÑĐµĐ»ĐµĐ¼" +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" -msgid "4-button flight yoke with throttle" -msgstr "4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹ flight yoke Ñ Đ´Ñ€Đ¾ÑÑĐµĐ»ĐµĐ¼" +msgid "Thrustmaster Flight Control System" +msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Đ¿Đ¾Đ»Ñ‘Ñ‚Đ¾Đ¼ Thrustmaster" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»ĐµĐ½Đ¸Ñ Ñ€ÑƒĐ»Ñ‘Đ¼" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Đ ÑƒĐ»ÑŒ Win95 (3-Đ¾ÑĐµĐ²Đ¾Đ¹, 4-ĐºĐ½Đ¾Đ¿Đ¾Ñ‡Đ½Ñ‹Đ¹)" +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 Ñ Đ°Đ´Đ°Đ¿Ñ‚ĐµÑ€Đ¾Đ¼" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 без Đ°Đ´Đ°Đ¿Ñ‚ĐµÑ€Đ°" msgid "None" msgstr "ĐĐµÑ‚" @@ -978,11 +1017,8 @@ msgstr "Đ­Ñ‚Đ¾ Đ¿Ñ€Đ¸Đ²ĐµĐ´Ñ‘Ñ‚ Đº Ñ…Đ¾Đ»Đ¾Đ´Đ½Đ¾Đ¹ Đ¿ĐµÑ€ĐµĐ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐµ Ñ msgid "Save" msgstr "Đ¡Đ¾Ñ…Ñ€Đ°Đ½Đ¸Ñ‚ÑŒ" -msgid "About 86Box" -msgstr "Đ 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Đ %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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ĐĐ²Ñ‚Đ¾Ñ€Ñ‹: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nĐ¡ Đ¿Ñ€ĐµĐ´Ñ‹Đ´ÑƒÑ‰Đ¸Đ¼Đ¸ Đ¾ÑĐ½Đ¾Đ²Đ½Ñ‹Đ¼Đ¸ Đ¼Đ°Ñ‚ĐµÑ€Đ¸Đ°Đ»Đ°Đ¼Đ¸ Đ¾Ñ‚ Sarah Walker, leilei, JohnElliott, greatpsycho и Đ´Ñ€ÑƒĐ³Đ¸Ñ….\n\nĐ’Ñ‹Đ¿ÑƒÑĐºĐ°ĐµÑ‚ÑÑ Đ¿Đ¾Đ´ Đ»Đ¸Ñ†ĐµĐ½Đ·Đ¸ĐµĐ¹ GNU General Public License Đ²ĐµÑ€Ñии 2 или Đ±Đ¾Đ»ĐµĐµ Đ¿Đ¾Đ·Đ´Đ½ĐµĐ¹. Đ”Đ¾Đ¿Đ¾Đ»Đ½Đ¸Ñ‚ĐµĐ»ÑŒĐ½ÑƒÑ Đ¸Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Đ¸Ñ ÑĐ¼. Đ² Ñ„Đ°Đ¹Đ»Đµ LICENSE." @@ -1237,7 +1273,7 @@ msgid "C&lone..." msgstr "Đ&Đ»Đ¾Đ½Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" -msgstr "Đ’Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ°Ñ Đ¼Đ°ÑˆĐ¸Đ½Đ° \"%1\" (%2) Đ±ÑƒĐ´ĐµÑ‚ ĐºĐ»Đ¾Đ½Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ° Đ²:" +msgstr "Đ’Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ°Ñ Đ¼Đ°ÑˆĐ¸Đ½Đ° «%1» (%2) Đ±ÑƒĐ´ĐµÑ‚ ĐºĐ»Đ¾Đ½Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ° Đ²:" msgid "Directory %1 already exists" msgstr "ĐŸĐ°Đ¿ĐºĐ° %1 ÑƒĐ¶Đµ ÑÑƒÑ‰ĐµÑÑ‚Đ²ÑƒĐµÑ‚" @@ -1303,13 +1339,13 @@ msgid "&Kill" msgstr "&Đ—Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚ÑŒ Đ¿Ñ€Đ¾Ñ†ĐµÑÑ" msgid "Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?" -msgstr "ĐŸÑ€Đ¸Đ½ÑƒĐ´Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Đµ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ¸Đµ Đ¿Ñ€Đ¾Ñ†ĐµÑÑа Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ Đ¼Đ¾Đ¶ĐµÑ‚ Đ¿Ñ€Đ¸Đ²ĐµÑÑ‚Đ¸ Đº Đ¿Đ¾Ñ‚ĐµÑ€Đµ Đ´Đ°Đ½Đ½Ñ‹Ñ…. Đ”ĐµĐ»Đ°Đ¹Ñ‚Đµ ÑÑ‚Đ¾ Ñ‚Đ¾Đ»ÑŒĐºĐ¾ Đ² Ñ‚Đ¾Đ¼ ÑĐ»ÑƒÑ‡Đ°Đµ, еÑли Đ¿Ñ€Đ¾Ñ†ĐµÑÑ 86Box Đ·Đ°Đ²Đ¸Ñ.\n\nĐ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ Đ¿Ñ€Đ¸Đ½ÑƒĐ´Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚ÑŒ Đ¿Ñ€Đ¾Ñ†ĐµÑÑ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ \"%1\"?" +msgstr "ĐŸÑ€Đ¸Đ½ÑƒĐ´Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾Đµ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ¸Đµ Đ¿Ñ€Đ¾Ñ†ĐµÑÑа Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ Đ¼Đ¾Đ¶ĐµÑ‚ Đ¿Ñ€Đ¸Đ²ĐµÑÑ‚Đ¸ Đº Đ¿Đ¾Ñ‚ĐµÑ€Đµ Đ´Đ°Đ½Đ½Ñ‹Ñ…. Đ”ĐµĐ»Đ°Đ¹Ñ‚Đµ ÑÑ‚Đ¾ Ñ‚Đ¾Đ»ÑŒĐºĐ¾ Đ² Ñ‚Đ¾Đ¼ ÑĐ»ÑƒÑ‡Đ°Đµ, еÑли Đ¿Ñ€Đ¾Ñ†ĐµÑÑ 86Box Đ·Đ°Đ²Đ¸Ñ.\n\nĐ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ Đ¿Ñ€Đ¸Đ½ÑƒĐ´Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚ÑŒ Đ¿Ñ€Đ¾Ñ†ĐµÑÑ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ «%1»?" msgid "&Delete" msgstr "&Đ£Đ´Đ°Đ»Đ¸Ñ‚ÑŒ" msgid "Do you really want to delete the virtual machine \"%1\" and all its files? This action cannot be undone!" -msgstr "Đ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½ÑƒÑ Đ¼Đ°ÑˆĐ¸Đ½Ñƒ \"%1\" и Đ²Ñе ĐµÑ‘ Ñ„Đ°Đ¹Đ»Ñ‹? Đ­Ñ‚Đ¾ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Đ½Đµ Đ¼Đ¾Đ¶ĐµÑ‚ Đ±Ñ‹Ñ‚ÑŒ Đ¾Ñ‚Đ¼ĐµĐ½ĐµĐ½Đ¾!" +msgstr "Đ’Ñ‹ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Ñ‚ĐµĐ»ÑŒĐ½Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½ÑƒÑ Đ¼Đ°ÑˆĐ¸Đ½Ñƒ «%1» и Đ²Ñе ĐµÑ‘ Ñ„Đ°Đ¹Đ»Ñ‹? Đ­Ñ‚Đ¾ Đ´ĐµĐ¹ÑÑ‚Đ²Đ¸Đµ Đ½Đµ Đ¼Đ¾Đ¶ĐµÑ‚ Đ±Ñ‹Ñ‚ÑŒ Đ¾Ñ‚Đ¼ĐµĐ½ĐµĐ½Đ¾!" msgid "Show &config file" msgstr "ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚ÑŒ Ñ„Đ°Đ¹Đ» &ĐºĐ¾Đ½Ñ„Đ¸Đ³ÑƒÑ€Đ°Ñ†Đ¸Đ¸" @@ -1332,8 +1368,8 @@ msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ°" msgid "Storage" msgstr "ДиÑĐºĐ¸" -msgid "Disk %1: " -msgstr "ДиÑĐº %1: " +msgid "Disk %1:" +msgstr "ДиÑĐº %1:" msgid "No disks" msgstr "ĐĐµÑ‚ диÑĐºĐ¾Đ²" @@ -1519,13 +1555,13 @@ msgid "720 KB" msgstr "720 ĐĐ‘" msgid "1.2 MB" -msgstr "1.2 ĐœĐ‘" +msgstr "1,2 ĐœĐ‘" msgid "1.25 MB" -msgstr "1.25 ĐœĐ‘" +msgstr "1,25 ĐœĐ‘" msgid "1.44 MB" -msgstr "1.44 ĐœĐ‘" +msgstr "1,44 ĐœĐ‘" msgid "DMF (cluster 1024)" msgstr "DMF (ĐºĐ»Đ°ÑÑ‚ĐµÑ€ 1024)" @@ -1534,40 +1570,40 @@ msgid "DMF (cluster 2048)" msgstr "DMF (ĐºĐ»Đ°ÑÑ‚ĐµÑ€ 2048)" msgid "2.88 MB" -msgstr "2.88 ĐœĐ‘" +msgstr "2,88 ĐœĐ‘" msgid "ZIP 100" msgstr "ZIP 100" msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3.5\" 128 ĐœĐ‘ (ISO 10090)" +msgstr "3,5\" 128 ĐœĐ‘ (ISO 10090)" msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3.5\" 230 ĐœĐ‘ (ISO 13963)" +msgstr "3,5\" 230 ĐœĐ‘ (ISO 13963)" msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3.5\" 540 ĐœĐ‘ (ISO 15498)" +msgstr "3,5\" 540 ĐœĐ‘ (ISO 15498)" msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3.5\" 640 ĐœĐ‘ (ISO 15498)" +msgstr "3,5\" 640 ĐœĐ‘ (ISO 15498)" msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3.5\" 1.3 ГБ (GigaMO)" +msgstr "3,5\" 1,3 ГБ (GigaMO)" msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3.5\" 2.3 ГБ (GigaMO 2)" +msgstr "3,5\" 2,3 ГБ (GigaMO 2)" msgid "5.25\" 600 MB" -msgstr "5.25\" 600 ĐœĐ‘" +msgstr "5,25\" 600 ĐœĐ‘" msgid "5.25\" 650 MB" -msgstr "5.25\" 650 ĐœĐ‘" +msgstr "5,25\" 650 ĐœĐ‘" msgid "5.25\" 1 GB" -msgstr "5.25\" 1 ГБ" +msgstr "5,25\" 1 ГБ" msgid "5.25\" 1.3 GB" -msgstr "5.25\" 1.3 ГБ" +msgstr "5,25\" 1,3 ГБ" msgid "Perfect RPM" msgstr "Đ¢Đ¾Ñ‡Đ½Ñ‹Đ¹ RPM" @@ -1576,7 +1612,7 @@ msgid "1% below perfect RPM" msgstr "Đа 1% Đ¼ĐµĐ´Đ»ĐµĐ½Đ½ĐµĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" msgid "1.5% below perfect RPM" -msgstr "Đа 1.5% Đ¼ĐµĐ´Đ»ĐµĐ½Đ½ĐµĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" +msgstr "Đа 1,5% Đ¼ĐµĐ´Đ»ĐµĐ½Đ½ĐµĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" msgid "2% below perfect RPM" msgstr "Đа 2% Đ¼ĐµĐ´Đ»ĐµĐ½Đ½ĐµĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" @@ -1738,7 +1774,7 @@ msgid "This machine might have been moved or copied." msgstr "Đ’Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾, ÑÑ‚Đ° Đ¼Đ°ÑˆĐ¸Đ½Đ° Đ±Ñ‹Đ»Đ° Đ¿ĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ° или ÑĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Đ§Ñ‚Đ¾Đ±Ñ‹ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡Đ¸Ñ‚ÑŒ Đ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½ÑƒÑ Ñ€Đ°Đ±Đ¾Ñ‚Ñƒ ÑĐµÑ‚Đ¸, 86Box Đ´Đ¾Đ»Đ¶ĐµĐ½ Đ·Đ½Đ°Ñ‚ÑŒ, Đ±Ñ‹Đ»Đ° ли ÑÑ‚Đ° Đ¼Đ°ÑˆĐ¸Đ½Đ° Đ¿ĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ° или ÑĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°.\n\nĐ•Ñли Đ²Ñ‹ Đ½Đµ ÑƒĐ²ĐµÑ€ĐµĐ½Ñ‹, Đ²Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ \"Đ¡ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°\"." +msgstr "Đ§Ñ‚Đ¾Đ±Ñ‹ Đ¾Đ±ĐµÑĐ¿ĐµÑ‡Đ¸Ñ‚ÑŒ Đ¿Ñ€Đ°Đ²Đ¸Đ»ÑŒĐ½ÑƒÑ Ñ€Đ°Đ±Đ¾Ñ‚Ñƒ ÑĐµÑ‚Đ¸, 86Box Đ´Đ¾Đ»Đ¶ĐµĐ½ Đ·Đ½Đ°Ñ‚ÑŒ, Đ±Ñ‹Đ»Đ° ли ÑÑ‚Đ° Đ¼Đ°ÑˆĐ¸Đ½Đ° Đ¿ĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ° или ÑĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°.\n\nĐ•Ñли Đ²Ñ‹ Đ½Đµ ÑƒĐ²ĐµÑ€ĐµĐ½Ñ‹, Đ²Ñ‹Đ±ĐµÑ€Đ¸Ñ‚Đµ Â«Đ¡ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°Â»." msgid "I Moved It" msgstr "ĐŸĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ°" @@ -1746,8 +1782,8 @@ msgstr "ĐŸĐµÑ€ĐµĐ¼ĐµÑ‰ĐµĐ½Đ°" msgid "I Copied It" msgstr "Đ¡ĐºĐ¾Đ¿Đ¸Ñ€Đ¾Đ²Đ°Đ½Đ°" -msgid "86Box Monitor #" -msgstr "86Box Monitor #" +msgid "86Box Monitor #%1" +msgstr "ĐœĐ¾Đ½Đ¸Ñ‚Đ¾Ñ€ 86Box â„– %1" msgid "No MCA devices." msgstr "ĐĐµÑ‚ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ² MCA." @@ -1759,16 +1795,16 @@ msgid "GiB" msgstr "ГиБ" msgid "Network Card #1" -msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 1" +msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 1" msgid "Network Card #2" -msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 2" +msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 2" msgid "Network Card #3" -msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 3" +msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 3" msgid "Network Card #4" -msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° 4" +msgstr "Đ¡ĐµÑ‚ĐµĐ²Đ°Ñ ĐºĐ°Ñ€Ñ‚Đ° â„– 4" msgid "Mode:" msgstr "Đ ĐµĐ¶Đ¸Đ¼:" @@ -1782,6 +1818,9 @@ msgstr "ĐĐ´Đ°Đ¿Ñ‚ĐµÑ€:" msgid "VDE Socket:" msgstr "VDE ÑĐ¾ĐºĐµÑ‚:" +msgid "TAP Bridge Device:" +msgstr "Đ£ÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ¾ Đ¼Đ¾ÑÑ‚Đ° TAP:" + msgid "86Box Unit Tester" msgstr "ĐœĐ¾Đ´ÑƒĐ»ÑŒĐ½Ñ‹Đ¹ Đ¢ĐµÑÑ‚ĐµÑ€ 86Box" @@ -1882,46 +1921,46 @@ msgid "BIOS file" msgstr "Đ¤Đ°Đ¹Đ» BIOS" msgid "BIOS file (ROM #1)" -msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ #1)" +msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ â„– 1)" msgid "BIOS file (ROM #2)" -msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ #2)" +msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ â„– 2)" msgid "BIOS file (ROM #3)" -msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ #3)" +msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ â„– 3)" msgid "BIOS file (ROM #4)" -msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ #4)" +msgstr "Đ¤Đ°Đ¹Đ» BIOS (ĐŸĐ—Đ£ â„– 4)" msgid "BIOS address" msgstr "ĐĐ´Ñ€ĐµÑ BIOS" msgid "BIOS address (ROM #1)" -msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ #1)" +msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ â„– 1)" msgid "BIOS address (ROM #2)" -msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ #2)" +msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ â„– 2)" msgid "BIOS address (ROM #3)" -msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ #3)" +msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ â„– 3)" msgid "BIOS address (ROM #4)" -msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ #4)" +msgstr "ĐĐ´Ñ€ĐµÑ BIOS (ĐŸĐ—Đ£ â„– 4)" msgid "Enable BIOS extension ROM Writes" msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS" msgid "Enable BIOS extension ROM Writes (ROM #1)" -msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ #1)" +msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ â„– 1)" msgid "Enable BIOS extension ROM Writes (ROM #2)" -msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ #2)" +msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ â„– 2)" msgid "Enable BIOS extension ROM Writes (ROM #3)" -msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ #3)" +msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ â„– 3)" msgid "Enable BIOS extension ROM Writes (ROM #4)" -msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ #4)" +msgstr "Đ Đ°Đ·Ñ€ĐµÑˆĐ¸Ñ‚ÑŒ Đ·Đ°Đ¿Đ¸ÑÑŒ Đ² ĐŸĐ—Đ£ Ñ€Đ°ÑÑˆĐ¸Ñ€ĐµĐ½Đ¸Ñ BIOS (ĐŸĐ—Đ£ â„– 4)" msgid "Linear framebuffer base" msgstr "Đ›Đ¸Đ½ĐµĐ¹Đ½Ñ‹Đ¹ Ñ„Ñ€ĐµĐ¹Đ¼Đ±ÑƒÑ„ĐµÑ€" @@ -1969,16 +2008,16 @@ msgid "BIOS size" msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS" msgid "BIOS size (ROM #1)" -msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ #1)" +msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ â„– 1)" msgid "BIOS size (ROM #2)" -msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ #2)" +msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ â„– 2)" msgid "BIOS size (ROM #3)" -msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ #3)" +msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ â„– 3)" msgid "BIOS size (ROM #4)" -msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ #4)" +msgstr "Đ Đ°Đ·Đ¼ĐµÑ€ BIOS (ĐŸĐ—Đ£ â„– 4)" msgid "Map C0000-C7FFF as UMB" msgstr "ĐÑ‚Đ¾Đ±Ñ€Đ°Đ¶ĐµĐ½Đ¸Đµ C0000-C7FFF Đ² ĐºĐ°Ñ‡ĐµÑÑ‚Đ²Đµ UMB" @@ -2146,7 +2185,7 @@ msgid "Enable Game port" msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ¸Đ³Ñ€Đ¾Đ²Đ¾Đ¹ Đ¿Đ¾Ñ€Ñ‚" msgid "Enable Adlib ports" -msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ¿Đ¾Ñ€Ñ‚Ñ‹ Adlib" +msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ¿Đ¾Ñ€Ñ‚Ñ‹ AdLib" msgid "SID Model" msgstr "ĐœĐ¾Đ´ĐµĐ»ÑŒ SID" @@ -2157,12 +2196,6 @@ msgstr "Đ¡Đ¸Đ»Đ° Ñ„Đ¸Đ»ÑŒÑ‚Ñ€Đ° SID" msgid "Surround module" msgstr "ĐœĐ¾Đ´ÑƒĐ»ÑŒ Đ¾Đ±ÑÑ‘Đ¼Đ½Đ¾Đ³Đ¾ Đ·Đ²ÑƒÑ‡Đ°Đ½Đ¸Ñ" -msgid "CODEC" -msgstr "ĐĐ¾Đ´ĐµĐº" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "ĐŸĐ¾Đ´Đ½Đ¸Đ¼Đ°Ñ‚ÑŒ Đ¿Ñ€ĐµÑ€Ñ‹Đ²Đ°Đ½Đ¸Đµ ĐºĐ¾Đ´ĐµĐºĐ° Đ¿Ñ€Đ¸ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐµ ĐºĐ¾Đ´ĐµĐºĐ° (Đ½ĐµĐ¾Đ±Ñ…Đ¾Đ´Đ¸Đ¼Đ¾ Đ½ĐµĐºĐ¾Ñ‚Đ¾Ñ€Ñ‹Đ¼ Đ´Ñ€Đ°Đ¹Đ²ĐµÑ€Đ°Đ¼)" - msgid "SB Address" msgstr "ĐĐ´Ñ€ĐµÑ SB" @@ -2178,6 +2211,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ RTC" + +msgid "RTC Port Address" +msgstr "ĐĐ´Ñ€ĐµÑ Đ¿Đ¾Ñ€Ñ‚Đ° RTC" + +msgid "Onboard RTC" +msgstr "Đ’ÑÑ‚Ñ€Đ¾ĐµĐ½Đ½Ñ‹Đ¹ RTC" + +msgid "Not installed" +msgstr "Đе уÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½" + msgid "Enable OPL" msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ OPL" @@ -2218,7 +2263,7 @@ msgid "GUS type" msgstr "Đ¢Đ¸Đ¿ GUS" msgid "Enable 0x04 \"Exit 86Box\" command" -msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñƒ 0x04 \"Đ’Ñ‹Ñ…Đ¾Đ´ из 86Box\"" +msgstr "Đ’ĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñƒ 0x04 Â«Đ’Ñ‹Ñ…Đ¾Đ´ из 86Box»" msgid "Display type" msgstr "Đ¢Đ¸Đ¿ диÑĐ¿Đ»ĐµÑ" @@ -2395,10 +2440,10 @@ msgid "Five + 2 Wheels" msgstr "ĐŸÑть + 2 ĐºĐ¾Đ»ĐµÑа" msgid "A3 - SMT2 Serial / SMT3(R)V" -msgstr "A3 - SMT2 Đ¿Đ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Đ°Ñ / SMT3(R)V" +msgstr "A3 - SMT2 Đ¿Đ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹ / SMT3(R)V" msgid "Q1 - SMT3(R) Serial" -msgstr "Q1 - SMT3(R) Đ¿Đ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Đ°Ñ" +msgstr "Q1 - SMT3(R) Đ¿Đ¾ÑĐ»ĐµĐ´Đ¾Đ²Đ°Ñ‚ĐµĐ»ÑŒĐ½Ñ‹Đ¹" msgid "8 KB" msgstr "8 ĐĐ‘" @@ -2448,9 +2493,6 @@ msgstr "24 ĐœĐ‘" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (ÑÑ‚ĐµÑ€ĐµĐ¾)" -msgid "Classic" -msgstr "ĐлаÑÑĐ¸Ñ‡ĐµÑĐºĐ¸Đ¹" - msgid "256 KB" msgstr "256 ĐĐ‘" @@ -2707,7 +2749,7 @@ msgid "Unable to find Dot-Matrix fonts" msgstr "ĐĐµĐ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾ Đ½Đ°Đ¹Ñ‚Đ¸ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Ñ‹Đµ ÑˆÑ€Đ¸Ñ„Ñ‚Ñ‹" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P 2 Dot-Matrix Printer." -msgstr "Đ¨Ñ€Đ¸Ñ„Ñ‚Ñ‹ TrueType Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đµ \"roms/printer/fonts\" Đ½ĐµĐ¾Đ±Ñ…Đ¾Đ´Đ¸Đ¼Ñ‹ Đ´Đ»Ñ ÑĐ¼ÑƒĐ»ÑÑ†Đ¸Đ¸ ÑÑ‚Đ°Đ½Đ´Đ°Ñ€Ñ‚Đ½Đ¾Đ³Đ¾ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Đ¾Đ³Đ¾ Đ¿Ñ€Đ¸Đ½Ñ‚ĐµÑ€Đ° ESC/P 2." +msgstr "Đ¨Ñ€Đ¸Ñ„Ñ‚Ñ‹ TrueType Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³Đµ «roms/printer/fonts» Đ½ĐµĐ¾Đ±Ñ…Đ¾Đ´Đ¸Đ¼Ñ‹ Đ´Đ»Ñ ÑĐ¼ÑƒĐ»ÑÑ†Đ¸Đ¸ ÑÑ‚Đ°Đ½Đ´Đ°Ñ€Ñ‚Đ½Đ¾Đ³Đ¾ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Đ¾Đ³Đ¾ Đ¿Ñ€Đ¸Đ½Ñ‚ĐµÑ€Đ° ESC/P 2." msgid "Inhibit multimedia keys" msgstr "ĐŸĐµÑ€ĐµÑ…Đ²Đ°Ñ‚Ñ‹Đ²Đ°Ñ‚ÑŒ Đ¼ÑƒĐ»ÑŒÑ‚Đ¸Đ¼ĐµĐ´Đ¸Đ¹Đ½Ñ‹Đµ ĐºĐ»Đ°Đ²Đ¸ÑˆĐ¸" @@ -2739,9 +2781,6 @@ msgstr "ĐÑˆĐ¸Đ±ĐºĐ° GLSL" msgid "Could not load shader: %1" msgstr "Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ ÑˆĐµĐ¹Đ´ĐµÑ€: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Đ¢Ñ€ĐµĐ±ÑƒĐµÑ‚ÑÑ OpenGL Đ²ĐµÑ€Ñии 3.0 или Đ²Ñ‹ÑˆĐµ. Đ¢ĐµĐºÑƒÑ‰Đ°Ñ Đ²ĐµÑ€ÑĐ¸Ñ GLSL %1.%2" - msgid "Could not load texture: %1" msgstr "Đе ÑƒĐ´Đ°Đ»Đ¾ÑÑŒ Đ·Đ°Đ³Ñ€ÑƒĐ·Đ¸Ñ‚ÑŒ Ñ‚ĐµĐºÑтуру: %1" @@ -2805,6 +2844,9 @@ msgstr "ĐÑ‚Đ¿Ñ€Đ°Đ²Đ¸Ñ‚ÑŒ Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ Đ¿Đ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Ñ‹Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼" +msgid "Toggle UI in fullscreen" +msgstr "ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡Đ¸Ñ‚ÑŒ UI Đ² Đ¿Đ¾Đ»Đ½Đ¾ÑĐºÑ€Đ°Đ½Đ½Đ¾Đ¼ Ñ€ĐµĐ¶Đ¸Đ¼Đµ" + msgid "Screenshot" msgstr "Đ¡ĐºÑ€Đ¸Đ½ÑˆĐ¾Ñ‚" @@ -2851,16 +2893,16 @@ msgid "&Wipe NVRAM" msgstr "&Đ¡Ñ‚ĐµÑ€ĐµÑ‚ÑŒ NVRAM" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "Đ­Ñ‚Đ¾ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ Đ²Ñе Ñ„Đ°Đ¹Đ»Ñ‹ NVRAM (и ÑĐ²ÑĐ·Đ°Đ½Đ½Ñ‹Đµ) Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹, Ñ€Đ°ÑĐ¿Đ¾Đ»Đ¾Đ¶ĐµĐ½Đ½Đ¾Đ¹ Đ² Đ¿Đ¾Đ´Đ¿Đ°Đ¿ĐºĐµ \"nvr\". Đ’Đ°Đ¼ Đ¿Ñ€Đ¸Đ´Ñ‘Ñ‚ÑÑ ÑĐ½Đ¾Đ²Đ° Ñ€ĐµĐºĐ¾Đ½Ñ„Đ¸Đ³ÑƒÑ€Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ BIOS (и, Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾, Đ´Ñ€ÑƒĐ³Đ¸Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ° Đ²Đ½ÑƒÑ‚Ñ€Đ¸ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹), еÑли Đ¿Ñ€Đ¸Đ¼ĐµĐ½Đ¸Đ¼Đ¾.\n\nĐ’Ñ‹ ÑƒĐ²ĐµÑ€ĐµĐ½Ñ‹, Ñ‡Ñ‚Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑÑ‚ĐµÑ€ĐµÑ‚ÑŒ Đ²ÑÑ‘ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ \"%1\"?" +msgstr "Đ­Ñ‚Đ¾ ÑƒĐ´Đ°Đ»Đ¸Ñ‚ Đ²Ñе Ñ„Đ°Đ¹Đ»Ñ‹ NVRAM (и ÑĐ²ÑĐ·Đ°Đ½Đ½Ñ‹Đµ) Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹, Ñ€Đ°ÑĐ¿Đ¾Đ»Đ¾Đ¶ĐµĐ½Đ½Đ¾Đ¹ Đ² Đ¿Đ¾Đ´Đ¿Đ°Đ¿ĐºĐµ «nvr». Đ’Đ°Đ¼ Đ¿Ñ€Đ¸Đ´Ñ‘Ñ‚ÑÑ ÑĐ½Đ¾Đ²Đ° Ñ€ĐµĐºĐ¾Đ½Ñ„Đ¸Đ³ÑƒÑ€Đ¸Ñ€Đ¾Đ²Đ°Ñ‚ÑŒ Đ½Đ°ÑÑ‚Ñ€Đ¾Đ¹ĐºĐ¸ BIOS (и, Đ²Đ¾Đ·Đ¼Đ¾Đ¶Đ½Đ¾, Đ´Ñ€ÑƒĐ³Đ¸Đµ уÑÑ‚Ñ€Đ¾Đ¹ÑÑ‚Đ²Đ° Đ²Đ½ÑƒÑ‚Ñ€Đ¸ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹), еÑли Đ¿Ñ€Đ¸Đ¼ĐµĐ½Đ¸Đ¼Đ¾.\n\nĐ’Ñ‹ ÑƒĐ²ĐµÑ€ĐµĐ½Ñ‹, Ñ‡Ñ‚Đ¾ Ñ…Đ¾Ñ‚Đ¸Ñ‚Đµ ÑÑ‚ĐµÑ€ĐµÑ‚ÑŒ Đ²ÑÑ‘ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ «%1»?" msgid "Success" msgstr "Đ£ÑĐ¿ĐµÑˆĐ½Đ¾" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "Đ£ÑĐ¿ĐµÑˆĐ½Đ¾ ÑÑ‚Ñ‘Ñ€Ñ‚Đ¾ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ \"%1\"" +msgstr "Đ£ÑĐ¿ĐµÑˆĐ½Đ¾ ÑÑ‚Ñ‘Ñ€Ñ‚Đ¾ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ «%1»" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" -msgstr "ĐŸÑ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° Đ¿Ñ€Đ¸ Đ¿Đ¾Đ¿Ñ‹Ñ‚ĐºĐµ ÑÑ‚ĐµÑ€ĐµÑ‚ÑŒ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ \"%1\"" +msgstr "ĐŸÑ€Đ¾Đ¸Đ·Đ¾ÑˆĐ»Đ° Đ¾ÑˆĐ¸Đ±ĐºĐ° Đ¿Ñ€Đ¸ Đ¿Đ¾Đ¿Ñ‹Ñ‚ĐºĐµ ÑÑ‚ĐµÑ€ĐµÑ‚ÑŒ ÑĐ¾Đ´ĐµÑ€Đ¶Đ¸Đ¼Đ¾Đµ NVRAM Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ «%1»" msgid "%1 VM Manager" msgstr "ĐœĐµĐ½ĐµĐ´Đ¶ĐµÑ€ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Ñ‹Ñ… Đ¼Đ°ÑˆĐ¸Đ½ %1" @@ -2938,7 +2980,7 @@ msgid "Virtual machine crash" msgstr "Đ¡Đ±Đ¾Đ¹ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹" msgid "The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2." -msgstr "ĐŸÑ€Đ¾Ñ†ĐµÑÑ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ \"%1\" Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Đ»ÑÑ Ñ ĐºĐ¾Đ´Đ¾Đ¼ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ¸Ñ %2." +msgstr "ĐŸÑ€Đ¾Ñ†ĐµÑÑ Đ²Đ¸Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Đ¹ Đ¼Đ°ÑˆĐ¸Đ½Ñ‹ «%1» Đ½ĐµĐ¾Đ¶Đ¸Đ´Đ°Đ½Đ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Đ»ÑÑ Ñ ĐºĐ¾Đ´Đ¾Đ¼ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ¸Ñ %2." msgid "The system will not be added." msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° Đ½Đµ Đ±ÑƒĐ´ĐµÑ‚ Đ´Đ¾Đ±Đ°Đ²Đ»ĐµĐ½Đ°." @@ -2977,7 +3019,7 @@ msgid "Export EDID" msgstr "Đ­ĐºÑĐ¿Đ¾Ñ€Ñ‚ EDID" msgid "EDID file \"%ls\" is too large." -msgstr "Đ¤Đ°Đ¹Đ» EDID \"%ls\" ÑĐ»Đ¸ÑˆĐºĐ¾Đ¼ Đ²ĐµĐ»Đ¸Đº." +msgstr "Đ¤Đ°Đ¹Đ» EDID «%ls» ÑĐ»Đ¸ÑˆĐºĐ¾Đ¼ Đ²ĐµĐ»Đ¸Đº." msgid "OpenGL input scale" msgstr "ĐœĐ°ÑÑˆÑ‚Đ°Đ± Đ²Đ²Đ¾Đ´Đ° OpenGL" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 436c8c674e1..5f84e59fe84 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -1,8 +1,14 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Slovak \n" +"Language: sk-SK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: sk_SK\n" "X-Source-Language: en_US\n" @@ -214,7 +220,7 @@ msgid "Enable &Discord integration" msgstr "Povolenie integrĂ¡cie s &Discordem" msgid "Sound &gain..." -msgstr "&Zosilnenie zvuku" +msgstr "&Zosilnenie zvuku..." msgid "Begin trace" msgstr "ZaÄaÅ¥ trace" @@ -226,10 +232,10 @@ msgid "&Help" msgstr "&Pomoc" msgid "&Documentation..." -msgstr "&DokumentĂ¡cia" +msgstr "&DokumentĂ¡cia..." msgid "&About 86Box..." -msgstr "&O programu 86Box" +msgstr "&O programu 86Box..." msgid "&New image..." msgstr "&NovĂ½ obraz..." @@ -273,36 +279,6 @@ msgstr "NaÄĂ­taÅ¥ znova predchĂ¡dzajĂºci obraz" msgid "&Folder..." msgstr "&Zložka..." -msgid "Target &framerate" -msgstr "&CieľovĂ¡ snĂ­mkovĂ¡ frekvencia" - -msgid "&Sync with video" -msgstr "&SynchronizovaÅ¥ s obrazom" - -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 "&ZvoliÅ¥ shader..." - -msgid "&Remove shader" -msgstr "&OdobraÅ¥ shader" - msgid "Preferences" msgstr "Predvoľby" @@ -478,7 +454,7 @@ msgid "MIDI In Device:" msgstr "Zariadenie pre MIDI vstup:" msgid "MIDI Out:" -msgstr "MIDI vĂ½stup" +msgstr "MIDI vĂ½stup:" msgid "Standalone MPU-401" msgstr "SamostatnĂ½ MPU-401" @@ -559,7 +535,7 @@ msgid "Quaternary IDE Controller" msgstr "Å tvrtĂ½ radiÄ IDE" msgid "Hard disk" -msgstr "RadiÄ CD-ROM:" +msgstr "PevnĂ½ disk" msgid "SCSI" msgstr "SCSI" @@ -603,9 +579,6 @@ msgstr "KanĂ¡l:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&ZadaÅ¥..." - msgid "Sectors:" msgstr "Sektory:" @@ -690,9 +663,6 @@ msgstr "Zariadenie ISABugger" msgid "POST card" msgstr "Karta pre kĂ³dy POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Chyba" @@ -852,9 +822,18 @@ msgstr "Neboli nĂ¡jdenĂ© žiadne PCap zariadenia" msgid "Invalid PCap device" msgstr "NeplatnĂ© PCap zariadenie" +msgid "Generic paddle controller(s)" +msgstr "GenerickĂ½ ovlĂ¡daÄ pĂ¡dla" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-osovĂ½, 1-tlaÄidlovĂ½ joystick" + msgid "2-axis, 2-button joystick(s)" msgstr "2-osovĂ½, 2-tlaÄidlovĂ½ joystick" +msgid "2-axis, 3-button joystick" +msgstr "2-osovĂ½, 4-tlaÄidlovĂ½ joystick" + msgid "2-axis, 4-button joystick" msgstr "2-osovĂ½, 4-tlaÄidlovĂ½ joystick" @@ -867,35 +846,41 @@ msgstr "2-osovĂ½, 8-tlaÄidlovĂ½ joystick" msgid "3-axis, 2-button joystick" msgstr "3-osovĂ½, 2-tlaÄidlovĂ½ joystick" +msgid "3-axis, 3-button joystick" +msgstr "3-osovĂ½, 3-tlaÄidlovĂ½ joystick" + msgid "3-axis, 4-button joystick" msgstr "3-osovĂ½, 4-tlaÄidlovĂ½ joystick" +msgid "4-axis, 2-button joystick" +msgstr "4-osovĂ½, 2-tlaÄidlovĂ½ joystick" + +msgid "4-axis, 3-button joystick" +msgstr "4-osovĂ½, 3-tlaÄidlovĂ½ joystick" + msgid "4-axis, 4-button joystick" msgstr "4-osovĂ½, 4-tlaÄidlovĂ½ joystick" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "OvlĂ¡daÄ s 2 tlaÄidlami" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "OvlĂ¡daÄ so 3 tlaÄidlami" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "OvlĂ¡daÄ so 4 tlaÄidlami" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "OvlĂ¡daÄ so 6 tlaÄidlami" -msgid "2-button gamepad(s)" -msgstr "OvlĂ¡daÄ s 2 tlaÄidlami" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "LeteckĂ½ knipl s 2 tlaÄidlami" -msgid "4-button gamepad" -msgstr "OvlĂ¡daÄ so 4 tlaÄidlami" +msgid "3-button flight yoke" +msgstr "LeteckĂ½ knipl s 3 tlaÄidlami" msgid "4-button flight yoke" msgstr "LeteckĂ½ knipl so 4 tlaÄidlami" @@ -903,11 +888,71 @@ msgstr "LeteckĂ½ knipl so 4 tlaÄidlami" msgid "2-button flight yoke with throttle" msgstr "LeteckĂ½ knipl s 2 tlaÄidlami a pĂ¡kou" +msgid "3-button flight yoke with throttle" +msgstr "LeteckĂ½ knipl s 3 tlaÄidlami a pĂ¡kou" + msgid "4-button flight yoke with throttle" msgstr "LeteckĂ½ knipl s 4 tlaÄidlami a pĂ¡kou" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volant pre Windows 95 (3 osy, 4 tlaÄĂ­tka)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volant (3 osy, 2 tlaÄĂ­tka)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volant (3 osy, 3 tlaÄĂ­tka)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volant (3 osy, 4 tlaÄĂ­tka)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 s adaptĂ©rom" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 bez adaptĂ©ru" msgid "None" msgstr "Žiadne" @@ -978,11 +1023,8 @@ msgstr "PokraÄovanĂ­m sa resetuje emulovanĂ½ poÄĂ­taÄ." msgid "Save" msgstr "UložiÅ¥" -msgid "About 86Box" -msgstr "O programe 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "O programe %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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Äov\n\nAutori: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nS predchĂ¡dzajĂºcimi hlavnĂ½mi prĂ­spevkami od Sarah Walker, leilei, JohnElliott, greatpsycho a ÄalÅ¡Ă­ch.\n\nZverejnenĂ© pod licenciou GNU General Public License verzie 2 alebo novÅ¡ej. Pozri sĂºbor LICENSE pre viac informĂ¡ciĂ­." @@ -1186,7 +1228,7 @@ msgid "Directory does not exist" msgstr "AdresĂ¡r neexistuje" msgid "A new directory for the system will be created in the selected directory above" -msgstr "Pre tento systĂ©m bude vytvorenĂ½ novĂ½ adresĂ¡r vo vyššie zvolenom adresĂ¡ri." +msgstr "Pre tento systĂ©m bude vytvorenĂ½ novĂ½ adresĂ¡r vo vyššie zvolenom adresĂ¡ri" msgid "System location:" msgstr "Umiestnenie systĂ©mu:" @@ -1240,7 +1282,7 @@ msgid "Virtual machine \"%1\" (%2) will be cloned into:" msgstr "VirtuĂ¡lny poÄĂ­taÄ \"%1\" (%2) bude klonovanĂ½ do:" msgid "Directory %1 already exists" -msgstr "AdresĂ¡r %1 už existuje." +msgstr "AdresĂ¡r %1 už existuje" msgid "You cannot use the following characters in the name: %1" msgstr "V nĂ¡zve nemožno použiÅ¥ nasledujĂºce znaky: %1" @@ -1332,8 +1374,8 @@ msgstr "SystĂ©m" msgid "Storage" msgstr "Ăložisko" -msgid "Disk %1: " -msgstr "Disk %1: " +msgid "Disk %1:" +msgstr "Disk %1:" msgid "No disks" msgstr "Žiadne disky" @@ -1746,8 +1788,8 @@ msgstr "Presunul som ho" msgid "I Copied It" msgstr "SkopĂ­roval som ho" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box Monitor %1" msgid "No MCA devices." msgstr "Žiadne zariadenia MCA." @@ -1782,6 +1824,9 @@ msgstr "AdaptĂ©r:" msgid "VDE Socket:" msgstr "ZĂ¡suvka VDE:" +msgid "TAP Bridge Device:" +msgstr "MostovĂ© zariadenie TAP:" + msgid "86Box Unit Tester" msgstr "86Box Unit Tester" @@ -2157,12 +2202,6 @@ msgstr "Sila filtra SID" msgid "Surround module" msgstr "Surround modul" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "ZvĂ½Å¡enie preruÅ¡enia CODEC pri nastavenĂ­ CODEC (potrebnĂ© v niektorĂ½ch ovlĂ¡daÄoch)" - msgid "SB Address" msgstr "Adresa SB" @@ -2178,6 +2217,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "IRQ hodin reĂ¡lneho Äasu" + +msgid "RTC Port Address" +msgstr "Adresa hodin reĂ¡lneho Äasu" + +msgid "Onboard RTC" +msgstr "IntegrovanĂ© hodiny reĂ¡lneho Äasu" + +msgid "Not installed" +msgstr "Nie je nainÅ¡talovanĂ©" + msgid "Enable OPL" msgstr "Povolenie OPL" @@ -2448,9 +2499,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "KlasickĂ©" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2787,6 @@ msgstr "Chyba GLSL" msgid "Could not load shader: %1" msgstr "Nebol možnĂ© naÄĂ­taÅ¥ shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Je vyžadovanĂ¡ verzia OpenGL 3.0 alebo vyššia. AktuĂ¡lna verzia GLSL je %1.%2" - msgid "Could not load texture: %1" msgstr "Nebolo možnĂ© naÄĂ­taÅ¥ textĂºru: %1" @@ -2767,10 +2812,10 @@ msgid "Move down" msgstr "PosunĂºÅ¥ nižšie" msgid "Could not load file %1" -msgstr "Nebolo možnĂ© možnĂ© naÄĂ­taÅ¥ sĂºbor %1" +msgstr "Nebolo možnĂ© naÄĂ­taÅ¥ sĂºbor %1" msgid "Key Bindings:" -msgstr "Nastavenie klĂ¡vesov" +msgstr "Nastavenie klĂ¡vesov:" msgid "Action" msgstr "Akcia" @@ -2788,7 +2833,7 @@ msgid "Bind Key" msgstr "NastaviÅ¥ klĂ¡vesu" msgid "Enter key combo:" -msgstr "Zadajte kombinĂ¡ciu klĂ¡vesov" +msgstr "Zadajte kombinĂ¡ciu klĂ¡vesov:" msgid "Bind conflict" msgstr "Konflikt nastavenĂ­" @@ -2805,6 +2850,9 @@ msgstr "StlaÄte Ctrl+Alt+Esc" msgid "Toggle fullscreen" msgstr "PrepnĂºÅ¥ režim celej obrazovky" +msgid "Toggle UI in fullscreen" +msgstr "PrepnĂºÅ¥ pouÅ¾Ă­vateľskĂ© rozhranie v režime celej obrazovky" + msgid "Screenshot" msgstr "ZhotoviÅ¥ snĂ­mku obrazovky" @@ -2839,7 +2887,7 @@ msgid "Hub Mode" msgstr "Režim hubu" msgid "Hostname:" -msgstr "HostiteľskĂ© meno" +msgstr "HostiteľskĂ© meno:" msgid "ISA RAM:" msgstr "ISA pamĂ¤Å¥ RAM:" @@ -2857,7 +2905,7 @@ msgid "Success" msgstr "Ăspech" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "Obsah NVRAM virtuĂ¡lneho poÄĂ­taÄa \"%1\" bol ĂºspeÅ¡ne vymazanĂ½." +msgstr "Obsah NVRAM virtuĂ¡lneho poÄĂ­taÄa \"%1\" bol ĂºspeÅ¡ne vymazanĂ½" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" msgstr "Pri pokuse o vymazanie obsahu NVRAM virtuĂ¡lneho poÄĂ­taÄa \"%1\" doÅ¡lo k chybe" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 8ef710a15a5..b654c988967 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Slovenian " +"\n" +"Language: sl-SI\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: sl_SI\n" "X-Source-Language: en_US\n" @@ -273,36 +281,6 @@ msgstr "Naloži zadnjo sliko" msgid "&Folder..." msgstr "&Mapa..." -msgid "Target &framerate" -msgstr "&Ciljno Å¡t. kadrov 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" @@ -603,9 +581,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&DoloÄi..." - msgid "Sectors:" msgstr "Sektorji:" @@ -690,9 +665,6 @@ msgstr "Naprava ISABugger" msgid "POST card" msgstr "Kartica POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Napaka" @@ -852,9 +824,18 @@ msgstr "Najdena ni bila nobena naprava PCap" msgid "Invalid PCap device" msgstr "Neveljavna naprava PCap" +msgid "Generic paddle controller(s)" +msgstr "GeneriÄni krmilnik z lopatico" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Igralna palica z 2 osema, 1 gumboma" + msgid "2-axis, 2-button joystick(s)" msgstr "Igralna palica z 2 osema, 2 gumboma" +msgid "2-axis, 3-button joystick" +msgstr "Igralna palica z 2 osema, 3 gumbi" + msgid "2-axis, 4-button joystick" msgstr "Igralna palica z 2 osema, 4 gumbi" @@ -865,37 +846,43 @@ msgid "2-axis, 8-button joystick" msgstr "Igralna palica z 2 osema, 8 gumbi" msgid "3-axis, 2-button joystick" -msgstr "Igralna palica s 3 osmi, 2 gumboma" +msgstr "Igralna palica s 3 osmi, 2 gumbi" + +msgid "3-axis, 3-button joystick" +msgstr "Igralna palica s 3 osmi, 3 gumbi" msgid "3-axis, 4-button joystick" msgstr "Igralna palica s 3 osmi, 4 gumbi" +msgid "4-axis, 2-button joystick" +msgstr "Igralna palica s 4 osmi, 2 gumbi" + +msgid "4-axis, 3-button joystick" +msgstr "Igralna palica s 4 osmi, 3 gumbi" + msgid "4-axis, 4-button joystick" msgstr "Igralna palica s 4 osmi, 4 gumbi" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "Igralna ploÅ¡Äica z 2 gumboma" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Igralna ploÅ¡Äica s 3 gumbi" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Igralna ploÅ¡Äica s 4 gumbi" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "Igralna ploÅ¡Äica s 6 gumbi" -msgid "2-button gamepad(s)" -msgstr "Igralna ploÅ¡Äica z 2 gumboma" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Letalski krmilni drog z 2 gumbi" -msgid "4-button gamepad" -msgstr "Igralna ploÅ¡Äica s 4 gumbi" +msgid "3-button flight yoke" +msgstr "Letalski krmilni drog z 3 gumbi" msgid "4-button flight yoke" msgstr "Letalski krmilni drog s 4 gumbi" @@ -903,11 +890,71 @@ msgstr "Letalski krmilni drog s 4 gumbi" msgid "2-button flight yoke with throttle" msgstr "Letalski krmilni drog z 2 gumbi gumboma roÄico za plin" +msgid "3-button flight yoke with throttle" +msgstr "Letalski krmilni drog s 3 gumbi z roÄico za plin" + msgid "4-button flight yoke with throttle" msgstr "Letalski krmilni drog s 4 gumbi z roÄico za plin" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Volan Win95 s 3 osmi, 4 gumbi" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "Volan s 3 osmi, 2 gumbi" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "Volan s 3 osmi, 3 gumbi" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "Volan s 3 osmi, 4 gumbi" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 s pretvornikom" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 brez pretvornika" msgid "None" msgstr "Brez" @@ -978,11 +1025,8 @@ 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 "About %1" +msgstr "O programu %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne in drugi.\n\nS prejÅ¡njimi prispevki Sarah Walker, leilei, JohnElliott, greatpsycho in drugih.\n\nIzdano pod licenco GNU General Public License razliÄica 2 ali novejÅ¡a. Glej datoteko LICENSE za veÄ informacij." @@ -1228,7 +1272,7 @@ msgid "Open p&rinter tray..." msgstr "Odpri pladenj &tiskalnika..." msgid "Set &icon..." -msgstr "Izberi &ikono" +msgstr "Izberi &ikono..." msgid "Select an icon" msgstr "Izberi ikono" @@ -1332,8 +1376,8 @@ msgstr "Sistem" msgid "Storage" msgstr "Shramba" -msgid "Disk %1: " -msgstr "Disk %1: " +msgid "Disk %1:" +msgstr "Disk %1:" msgid "No disks" msgstr "Ni diskov" @@ -1746,8 +1790,8 @@ msgstr "Premaknil sem jo" msgid "I Copied It" msgstr "Kopiral sem jo" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box Monitor %1" msgid "No MCA devices." msgstr "Ni naprav MCA." @@ -1782,6 +1826,9 @@ msgstr "Mrežna kartica:" msgid "VDE Socket:" msgstr "VtiÄnica VDE:" +msgid "TAP Bridge Device:" +msgstr "Mostovna naprava TAP:" + msgid "86Box Unit Tester" msgstr "Tester enote 86Box" @@ -2157,12 +2204,6 @@ msgstr "Jakost filtra SID-a" msgid "Surround module" msgstr "Prostorski modul" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Dvigni prekinitev za CODEC ob nastavitvi CODEC-a (to potrebujejo nekateri gonilniki)" - msgid "SB Address" msgstr "Naslov SB" @@ -2178,6 +2219,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ ure v realnem Äasu" + +msgid "RTC Port Address" +msgstr "Naslov ure v realnem Äasu" + +msgid "Onboard RTC" +msgstr "Integrirana ura v realnem Äasu" + +msgid "Not installed" +msgstr "Ni nameÅ¡Äen" + msgid "Enable OPL" msgstr "OmogoÄi OPL" @@ -2448,9 +2501,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "KlasiÄni" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2789,6 @@ msgstr "Napaka GLSL" msgid "Could not load shader: %1" msgstr "Ni bilo mogoÄe naložiti senÄilnika: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "Potrebna je OpenGL razliÄica 3.0 ali novejÅ¡a. Trenutna razliÄica GLSL je %1.%2" - msgid "Could not load texture: %1" msgstr "Ni bilo mogoÄe naložiti teksture: %1" @@ -2770,7 +2817,7 @@ msgid "Could not load file %1" msgstr "Ni bilo mogoÄe naložiti datoteke %1" msgid "Key Bindings:" -msgstr "Kombinacije tipk" +msgstr "Kombinacije tipk:" msgid "Action" msgstr "Dejanje" @@ -2805,6 +2852,9 @@ msgstr "PoÅ¡lji Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Preklopi celozaslonski naÄin" +msgid "Toggle UI in fullscreen" +msgstr "Preklopi uporabniÅ¡ki vmesnik v naÄinu polnega zaslona" + msgid "Screenshot" msgstr "Zajem zaslona" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 6f014e2ddac..ff0774bed8e 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -273,36 +273,6 @@ msgstr "Ladda om föregĂ¥ende avbildning" msgid "&Folder..." msgstr "&Mapp..." -msgid "Target &framerate" -msgstr "MĂ¥l för &bildhastighet" - -msgid "&Sync with video" -msgstr "&Synkronisera med bild" - -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 "&Välj shader..." - -msgid "&Remove shader" -msgstr "&Ta bort shader" - msgid "Preferences" msgstr "Preferenser" @@ -603,9 +573,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Specificera..." - msgid "Sectors:" msgstr "Sektorer:" @@ -690,9 +657,6 @@ msgstr "ISABugger-enhet" msgid "POST card" msgstr "POST-kort" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Fel" @@ -852,9 +816,18 @@ msgstr "Inga PCap-enheter hittade" msgid "Invalid PCap device" msgstr "Ogiltig PCap-enhet" +msgid "Generic paddle controller(s)" +msgstr "Generisk paddelkontroll(er)" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Styrspak med 2 axlar och 1 knappar" + msgid "2-axis, 2-button joystick(s)" msgstr "Styrspak med 2 axlar och 2 knappar" +msgid "2-axis, 3-button joystick" +msgstr "Styrspak med 2 axlar och 3 knappar" + msgid "2-axis, 4-button joystick" msgstr "Styrspak med 2 axlar och 4 knappar" @@ -867,35 +840,41 @@ msgstr "Styrspak med 2 axlar och 8 knappar" msgid "3-axis, 2-button joystick" msgstr "Styrspak med 3 axlar och 2 knappar" +msgid "3-axis, 3-button joystick" +msgstr "Styrspak med 3 axlar och 2 knappar" + msgid "3-axis, 4-button joystick" msgstr "Styrspak med 3 axlar och 4 knappar" +msgid "4-axis, 2-button joystick" +msgstr "Styrspak med 4 axlar och 2 knappar" + +msgid "4-axis, 3-button joystick" +msgstr "Styrspak med 4 axlar och 3 knappar" + msgid "4-axis, 4-button joystick" msgstr "Styrspak med 4 axlar och 4 knappar" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH-pedaler" +msgid "2-button gamepad(s)" +msgstr "Handkontroll(er) med tvĂ¥ knappar" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Handkontroll med tre knappar" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Handkontroll med fyra knappar" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "Handkontroll med sex knappar" -msgid "2-button gamepad(s)" -msgstr "Handkontroll(er) med tvĂ¥ knappar" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "Styrspak med tvĂ¥ knappar" -msgid "4-button gamepad" -msgstr "Handkontroll med fyra knappar" +msgid "3-button flight yoke" +msgstr "Styrspak med tre knappar" msgid "4-button flight yoke" msgstr "Styrspak med fyra knappar" @@ -903,11 +882,71 @@ msgstr "Styrspak med fyra knappar" msgid "2-button flight yoke with throttle" msgstr "Styrspak med tvĂ¥ knappar och gas" +msgid "3-button flight yoke with throttle" +msgstr "Styrspak med tre knappar och gas" + msgid "4-button flight yoke with throttle" msgstr "Styrspak med fyra knappar och gas" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95-ratt (tre axlar, fyra knappar)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "ratt (tre axlar, tvĂ¥ knappar)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "ratt (tre axlar, tre knappar)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "ratt (tre axlar, fyra knappar)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH-pedaler" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH-pedaler Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH-pedaler" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH-pedaler Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH-pedaler" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH-pedaler Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH-pedaler" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH-pedaler Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 med adapter" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 utan adapter" msgid "None" msgstr "Ingen" @@ -978,11 +1017,8 @@ msgstr "Detta kommer att göra en hĂ¥rd omstart av den emulerade maskinen." msgid "Save" msgstr "Spara" -msgid "About 86Box" -msgstr "Om 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Om %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "En emulator av gamla datorer\n\nUpphovsmän: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, med flera.\n\nMed tidigare grundbidrag frĂ¥n Sarah Walker, leilei, JohnElliott, greatpsycho, med flera.\n\nSläppt under GNU General Public License upplaga 2 eller senare. Se LICENSE för mer information." @@ -1332,7 +1368,7 @@ msgstr "System" msgid "Storage" msgstr "Lagring" -msgid "Disk %1: " +msgid "Disk %1:" msgstr "Disk %1:" msgid "No disks" @@ -1746,8 +1782,8 @@ msgstr "Jag flyttade den" msgid "I Copied It" msgstr "Jag kopierade den" -msgid "86Box Monitor #" -msgstr "86Box skärm #" +msgid "86Box Monitor #%1" +msgstr "86Box skärm #%1" msgid "No MCA devices." msgstr "Inga MCA-enheter." @@ -1782,6 +1818,9 @@ msgstr "Adapter:" msgid "VDE Socket:" msgstr "VDE-sockel:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "86Box enhetsprövare" @@ -1978,7 +2017,7 @@ msgid "BIOS size (ROM #3)" msgstr "Storlek pĂ¥ BIOS (ROM #3)" msgid "BIOS size (ROM #4)" -msgstr "Storlek pĂ¥ BIOS (BIOS #4)" +msgstr "Storlek pĂ¥ BIOS (ROM #4)" msgid "Map C0000-C7FFF as UMB" msgstr "Kartlägg C0000-C7FFF som UMB" @@ -2157,12 +2196,6 @@ msgstr "SID filetstyrka" msgid "Surround module" msgstr "Sorround-modul" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Ă–ka avbrottsnummer för CODEC vid CODEC-installation (krävs av vissa drivrutiner)" - msgid "SB Address" msgstr "Adress för SB" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "Aktivera OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klassisk" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "GLSL-fel" msgid "Could not load shader: %1" msgstr "Kunde inte ladda shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL version 3.0 eller högre krävs. Nuvarande GLSL-version är %1.%2" - msgid "Could not load texture: %1" msgstr "Kunde inte ladda textur: %1" @@ -2805,6 +2844,9 @@ msgstr "Skicka Ctrl+Alt+Esc" msgid "Toggle fullscreen" msgstr "Helskärm" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Skärmbild" @@ -2857,10 +2899,10 @@ msgid "Success" msgstr "Lyckades" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "Lyckades tömma allt NVRAM-innehĂ¥ll för den virtuella maskinen \"%1\"." +msgstr "Lyckades tömma allt NVRAM-innehĂ¥ll för den virtuella maskinen \"%1\"" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" -msgstr "Ett fel uppstod vid försök att tömma NVRAM-innehĂ¥llet för den virtuella maskinen \"%1\"." +msgstr "Ett fel uppstod vid försök att tömma NVRAM-innehĂ¥llet för den virtuella maskinen \"%1\"" msgid "%1 VM Manager" msgstr "%1 VM-hanterare" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 073572e1b0b..02bf881a59d 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -273,36 +273,6 @@ msgstr "Ă–nceki görĂ¼ntĂ¼yĂ¼ yeniden seç" msgid "&Folder..." msgstr "&Klasör seç..." -msgid "Target &framerate" -msgstr "Hedef &kare hızı 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" @@ -586,10 +556,10 @@ msgid "Firmware Version" msgstr "Bellenim SĂ¼rĂ¼mĂ¼" msgid "&New..." -msgstr "&Yeni görĂ¼ntĂ¼ oluÅŸtur" +msgstr "&Yeni görĂ¼ntĂ¼ oluÅŸtur..." msgid "&Existing..." -msgstr "&GörĂ¼ntĂ¼ dosyası seç" +msgstr "&GörĂ¼ntĂ¼ dosyası seç..." msgid "&Remove" msgstr "&Kaldır" @@ -603,9 +573,6 @@ msgstr "Kanal:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Belirle..." - msgid "Sectors:" msgstr "Sektörler:" @@ -690,9 +657,6 @@ msgstr "ISABugger cihazı" msgid "POST card" msgstr "POST kartı" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Hata" @@ -852,9 +816,18 @@ msgstr "Herhangi bir PCap cihazı bulunamadı" msgid "Invalid PCap device" msgstr "Geçersiz PCap cihazı" +msgid "Generic paddle controller(s)" +msgstr "Genel kĂ¼rek kontrol cihazları" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2 eksenli, 1 dĂ¼ÄŸmeli oyun kolları" + msgid "2-axis, 2-button joystick(s)" msgstr "2 eksenli, 2 dĂ¼ÄŸmeli oyun kolları" +msgid "2-axis, 3-button joystick" +msgstr "2 eksenli, 3 dĂ¼ÄŸmeli oyun kolu" + msgid "2-axis, 4-button joystick" msgstr "2 eksenli, 4 dĂ¼ÄŸmeli oyun kolu" @@ -867,35 +840,41 @@ msgstr "2 eksenli, 8 dĂ¼ÄŸmeli oyun kolu" msgid "3-axis, 2-button joystick" msgstr "3 eksenli, 2 dĂ¼ÄŸmeli oyun kollu" +msgid "3-axis, 3-button joystick" +msgstr "3 eksenli, 3 dĂ¼ÄŸmeli oyun kolu" + msgid "3-axis, 4-button joystick" msgstr "3 eksenli, 4 dĂ¼ÄŸmeli oyun kolu" +msgid "4-axis, 2-button joystick" +msgstr "4 eksenli, 2 dĂ¼ÄŸmeli oyun kolu" + +msgid "4-axis, 3-button joystick" +msgstr "4 eksenli, 3 dĂ¼ÄŸmeli oyun kolu" + msgid "4-axis, 4-button joystick" msgstr "4 eksenli, 4 dĂ¼ÄŸmeli oyun kolu" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "2 dĂ¼ÄŸmeli oyun tablası" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3 dĂ¼ÄŸmeli oyun tablası" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4 dĂ¼ÄŸmeli oyun tablası" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "6 dĂ¼ÄŸmeli oyun tablası" -msgid "2-button gamepad(s)" -msgstr "2 dĂ¼ÄŸmeli oyun tablası" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2 dĂ¼ÄŸmeli uçuÅŸ dĂ¼meni" -msgid "4-button gamepad" -msgstr "4 dĂ¼ÄŸmeli oyun tablası" +msgid "3-button flight yoke" +msgstr "3 dĂ¼ÄŸmeli uçuÅŸ dĂ¼meni" msgid "4-button flight yoke" msgstr "4 dĂ¼ÄŸmeli uçuÅŸ dĂ¼meni" @@ -903,11 +882,71 @@ msgstr "4 dĂ¼ÄŸmeli uçuÅŸ dĂ¼meni" msgid "2-button flight yoke with throttle" msgstr "2 dĂ¼ÄŸmeli, gaz kollu uçuÅŸ dĂ¼meni" +msgid "3-button flight yoke with throttle" +msgstr "3 dĂ¼ÄŸmeli, gaz kollu uçuÅŸ dĂ¼meni" + msgid "4-button flight yoke with throttle" msgstr "4 dĂ¼ÄŸmeli, gaz kollu uçuÅŸ dĂ¼meni" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 direksiyonu (3 eksenli, 4 dĂ¼ÄŸmeli)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "direksiyonu (3 eksenli, 2 dĂ¼ÄŸmeli)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "direksiyonu (3 eksenli, 3 dĂ¼ÄŸmeli)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "direksiyonu (3 eksenli, 4 dĂ¼ÄŸmeli)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "AdaptörlĂ¼ Thrustmaster Formula T1/T2" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "AdaptörsĂ¼z Thrustmaster Formula T1/T2" msgid "None" msgstr "Hiçbiri" @@ -978,11 +1017,8 @@ msgstr "Bu iÅŸlem makineyi yeniden baÅŸlamaya zorlayacak." msgid "Save" msgstr "Kaydet" -msgid "About 86Box" -msgstr "86Box hakkında" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "%1 hakkında" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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\nYapımcılar: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne ve diÄŸerleri.\n\nSarah Walker, leilei, JohnElliott, greatpsycho, ve diÄŸerlerinin önceki katkılarıyla birlikte.\n\nGNU Genel Kamu Lisansı versiyon 2 veya sonrası altında yayınlanmıştır. Daha fazla bilgi için LICENSE kısmını gözden geçirin." @@ -1117,7 +1153,7 @@ msgid "System Directory:" msgstr "Sistem Dizini:" msgid "Choose directory" -msgstr "Dizin seç:" +msgstr "Dizin seç" msgid "Choose configuration file" msgstr "Yapılandırma dosyası seç" @@ -1192,7 +1228,7 @@ msgid "System location:" msgstr "Sistem yeri:" msgid "System name and location" -msgstr "Sistem adı ve yeri:" +msgstr "Sistem adı ve yeri" msgid "Enter the name of the system and choose the location" msgstr "Sistemin adını girin ve yerini seçin" @@ -1204,7 +1240,7 @@ msgid "Please enter a system name" msgstr "LĂ¼tfen bir sistem adı girin" msgid "Display name (optional):" -msgstr "GörĂ¼ntĂ¼ adı (isteÄŸe baÄŸlı)" +msgstr "GörĂ¼ntĂ¼ adı (isteÄŸe baÄŸlı):" msgid "Display name:" msgstr "GörĂ¼ntĂ¼ adı:" @@ -1216,7 +1252,7 @@ msgid "Enter the new display name (blank to reset)" msgstr "Yeni görĂ¼nĂ¼ adını girin (sıfırlamak için boÅŸ bırakın)" msgid "Change &display name..." -msgstr "GörĂ¼ntĂ¼ adını &deÄŸiÅŸtirin" +msgstr "GörĂ¼ntĂ¼ adını &deÄŸiÅŸtirin..." msgid "Context Menu" msgstr "BaÄŸlam MenĂ¼sĂ¼" @@ -1252,7 +1288,7 @@ msgid "Failed to create directory for cloned VM" msgstr "Klonlanmış VM için dizin oluÅŸturulamadı" msgid "Failed to clone VM." -msgstr "VM klonlanamadı" +msgstr "VM klonlanamadı." msgid "Directory in use" msgstr "Dizin kullanımda" @@ -1332,8 +1368,8 @@ msgstr "Sistem" msgid "Storage" msgstr "Depolama" -msgid "Disk %1: " -msgstr "Disk %1: " +msgid "Disk %1:" +msgstr "Disk %1:" msgid "No disks" msgstr "Disk yok" @@ -1746,8 +1782,8 @@ msgstr "Taşındı" msgid "I Copied It" msgstr "Kopyalandı" -msgid "86Box Monitor #" -msgstr "86Box Monitör #" +msgid "86Box Monitor #%1" +msgstr "86Box Monitör #%1" msgid "No MCA devices." msgstr "MCA cihazı yok." @@ -1782,6 +1818,9 @@ msgstr "Adaptör:" msgid "VDE Socket:" msgstr "VDE Soketi:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "86Box Test Cihazı" @@ -2157,12 +2196,6 @@ msgstr "SID Filtre GĂ¼cĂ¼" msgid "Surround module" msgstr "Surround modĂ¼lĂ¼" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "CODEC kurulumunda CODEC kesmesini yĂ¼kselt (bazı sĂ¼rĂ¼cĂ¼ler tarafından gereklidir)" - msgid "SB Address" msgstr "SB adresi" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "OPL'yi etkinleÅŸtir" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (stereo)" -msgid "Classic" -msgstr "Klasik" - msgid "256 KB" msgstr "256 KB" @@ -2739,17 +2781,14 @@ msgstr "GLSL Hatası" msgid "Could not load shader: %1" msgstr "%1 gölgelendiricisi yĂ¼klenemedi" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL sĂ¼rĂ¼m 3.0 veya daha yĂ¼kseÄŸi gereklidir. Åu anki GLSL sĂ¼rĂ¼mĂ¼ %1.%2" - msgid "Could not load texture: %1" msgstr "%1 dokusu yĂ¼klenemedi" msgid "Could not compile shader:\n\n%1" -msgstr "%1 gölgelendiricisi derlenemedi" +msgstr "Gölgelendirici derlenemedi:\n\n%1" msgid "Program not linked:\n\n%1" -msgstr "%1 programı baÄŸlanamadı" +msgstr "Program baÄŸlanamadı:\n\n%1" msgid "Shader Manager" msgstr "Gölgelendirici Yöneticisi" @@ -2770,7 +2809,7 @@ msgid "Could not load file %1" msgstr "%1 dosyası yĂ¼klenemedi" msgid "Key Bindings:" -msgstr "TuÅŸ BaÄŸlamaları" +msgstr "TuÅŸ BaÄŸlamaları:" msgid "Action" msgstr "Eylem" @@ -2805,6 +2844,9 @@ msgstr "Control+Alt+Escape gönder" msgid "Toggle fullscreen" msgstr "Tam ekran modunu ayarla" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Ekran görĂ¼ntĂ¼sĂ¼" @@ -2839,7 +2881,7 @@ msgid "Hub Mode" msgstr "Hub Modu" msgid "Hostname:" -msgstr "Ana bilgisayar adı" +msgstr "Ana bilgisayar adı:" msgid "ISA RAM:" msgstr "ISA RAM:" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 8228b7ae425..e98da1f0c76 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -1,8 +1,16 @@ msgid "" msgstr "" +"PO-Revision-Date: 2025-11-29 00:34+0000\n" +"Last-Translator: OBattler \n" +"Language-Team: Ukrainian " +"\n" +"Language: uk-UA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.12.2\n" "X-Language: uk_UA\n" "X-Source-Language: en_US\n" @@ -61,7 +69,7 @@ msgid "&Qt (Software)" msgstr "&Qt (Software)" msgid "Open&GL (3.0 Core)" -msgstr "Open&GL (3.0)" +msgstr "Open&GL (3.0 Core)" msgid "&VNC" msgstr "&VNC" @@ -76,13 +84,13 @@ msgid "&Window scale factor" msgstr "&ĐœĐ°ÑÑˆÑ‚Đ°Đ± Đ²Ñ–ĐºĐ½Đ°" msgid "&0.5x" -msgstr "&0.5x" +msgstr "&0,5x" msgid "&1x" msgstr "&1x" msgid "1.&5x" -msgstr "1.&5x" +msgstr "1,&5x" msgid "&2x" msgstr "&2x" @@ -273,36 +281,6 @@ msgstr "Đ—Đ½Đ¾Đ²Ñƒ Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶Đ¸Ñ‚Đ¸ Đ¿Đ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¹ Đ¾Đ±Ñ€Đ°Đ·" msgid "&Folder..." 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 "ĐŸĐ°Ñ€Đ°Đ¼ĐµÑ‚Ñ€Đ¸" @@ -603,9 +581,6 @@ msgstr "ĐĐ°Đ½Đ°Đ»:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "&Đ’ĐºĐ°Đ·Đ°Ñ‚Đ¸..." - msgid "Sectors:" msgstr "Đ¡ĐµĐºÑ‚Đ¾Ñ€Đ°:" @@ -690,9 +665,6 @@ msgstr "ĐŸÑ€Đ¸ÑÑ‚Ñ€Ñ–Đ¹ ISABugger" msgid "POST card" msgstr "ĐĐ°Ñ€Ñ‚Đ° POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "ĐŸĐ¾Đ¼Đ¸Đ»ĐºĐ°" @@ -718,7 +690,7 @@ msgid "Image %1" msgstr "ĐĐ±Ñ€Đ°Đ· %1" 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\"." +msgstr "86Box Đ½Đµ Đ·Đ¼Ñ–Đ³ Đ·Đ½Đ°Đ¹Ñ‚Đ¸ Đ¶Đ¾Đ´Đ½Đ¾Đ³Đ¾ Đ²Ñ–Đ´Đ¿Đ¾Đ²Ñ–Đ´Đ½Đ¾Đ³Đ¾ Đ´Đ»Ñ Đ²Đ¸ĐºĐ¾Ñ€Đ¸ÑÑ‚Đ°Đ½Đ½Ñ Ñ„Đ°Đ¹Đ»Ñƒ Đ· ĐŸĐ—Đ£.\n\nĐ‘ÑƒĐ´ÑŒ лаÑĐºĐ° Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶Ñ‚Đµ Đ½Đ°Đ±Ñ–Ñ€ ĐŸĐ—Đ£ Ñ– Đ²Đ¸Ñ‚ÑĐ³Đ½Ñ–Ñ‚ÑŒ Đ¹Đ¾Đ³Đ¾ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ³ «roms»." msgid "(empty)" msgstr "(Đ¿Đ¾Ñ€Đ¾Đ¶Đ½ÑŒĐ¾)" @@ -745,16 +717,16 @@ 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. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Ñƒ ÑиÑÑ‚ĐµĐ¼Đ½Ñƒ Đ¿Đ»Đ°Ñ‚Ñƒ." +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. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Ñƒ Đ²Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Ñƒ." +msgstr "Đ’Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Ñ‡ĐµÑ€ĐµĐ· Đ²Ñ–Đ´ÑÑƒÑ‚Đ½Ñ–Ñть Ñ„Đ°Đ¹Đ»Ñƒ Ñ—Ñ— ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ·Ñ– roms/video. ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ Đ½Đ° Đ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Ñƒ Đ²Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Ñƒ." msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "Đ’Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° 2 \"%hs\" Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Ñ‡ĐµÑ€ĐµĐ· Đ²Ñ–Đ´ÑÑƒÑ‚Đ½Ñ–Ñть Ñ„Đ°Đ¹Đ»Ñƒ Ñ—Ñ— ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ·Ñ– roms/video. Đ’Ñ–Đ´ĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ Đ´Ñ€ÑƒĐ³Đ¾Ñ— Đ²Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ¸." +msgstr "Đ’Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ° 2 «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ° Ñ‡ĐµÑ€ĐµĐ· Đ²Ñ–Đ´ÑÑƒÑ‚Đ½Ñ–Ñть Ñ„Đ°Đ¹Đ»Ñƒ Ñ—Ñ— ĐŸĐ—Đ£ Đ² ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ·Ñ– roms/video. Đ’Ñ–Đ´ĐºĐ»ÑÑ‡ĐµĐ½Đ½Ñ Đ´Ñ€ÑƒĐ³Đ¾Ñ— Đ²Ñ–Đ´ĐµĐ¾ĐºĐ°Ñ€Ñ‚Đ¸." msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "ĐŸÑ€Đ¸ÑÑ‚Ñ€Ñ–Đ¹ \"%hs\" Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ¸Đ¹ Ñ‡ĐµÑ€ĐµĐ· Đ²Ñ–Đ´ÑÑƒÑ‚Đ½Ñ–Ñть Ñ„Đ°Đ¹Đ»Ñƒ Đ¹Đ¾Đ³Đ¾ ĐŸĐ—Đ£. Đ†Đ³Đ½Đ¾Ñ€ÑƒĐ²Đ°Đ½Đ½Ñ Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ." +msgstr "ĐŸÑ€Đ¸ÑÑ‚Ñ€Ñ–Đ¹ «%hs» Đ½ĐµĐ´Đ¾ÑÑ‚ÑƒĐ¿Đ½Đ¸Đ¹ Ñ‡ĐµÑ€ĐµĐ· Đ²Ñ–Đ´ÑÑƒÑ‚Đ½Ñ–Ñть Ñ„Đ°Đ¹Đ»Ñƒ Đ¹Đ¾Đ³Đ¾ ĐŸĐ—Đ£. Đ†Đ³Đ½Đ¾Ñ€ÑƒĐ²Đ°Đ½Đ½Ñ Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ." msgid "Machine" msgstr "ĐĐ¾Đ¼Đ¿'ÑÑ‚ĐµÑ€" @@ -852,9 +824,18 @@ msgstr "ĐŸÑ€Đ¸ÑÑ‚Ñ€Đ¾Ñ— PCap Đ½Đµ Đ·Đ½Đ°Đ¹Đ´ĐµĐ½Ñ–" msgid "Invalid PCap device" msgstr "ĐĐµĐ²Ñ–Ñ€Đ½Đ¸Đ¹ Đ¿Ñ€Đ¸ÑÑ‚Ñ€Ñ–Đ¹ PCap" +msgid "Generic paddle controller(s)" +msgstr "Đ—Đ°Đ³Đ°Đ»ÑŒĐ½Đ¸Đ¹ ĐºĐ¾Đ½Ñ‚Ñ€Đ¾Đ»ĐµÑ€(и) Đ²ĐµÑла" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 1-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "2-axis, 2-button joystick(s)" msgstr "2-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "2-axis, 3-button joystick" +msgstr "2-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "2-axis, 4-button joystick" msgstr "2-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" @@ -867,35 +848,41 @@ msgstr "2-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 8-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" msgid "3-axis, 2-button joystick" msgstr "3-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "3-axis, 3-button joystick" +msgstr "3-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "3-axis, 4-button joystick" msgstr "3-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" +msgid "4-axis, 2-button joystick" +msgstr "4-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + +msgid "4-axis, 3-button joystick" +msgstr "4-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" + msgid "4-axis, 4-button joystick" msgstr "4-Đ¾ÑÑŒĐ¾Đ²Đ¸Đ¹, 4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ´Đ¶Đ¾Đ¹ÑÑ‚Đ¸Đº" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" +msgid "2-button gamepad(s)" +msgstr "2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH ĐŸĐµĐ´Đ°Đ»Ñ–" +msgid "3-button gamepad" +msgstr "3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "4-button gamepad" +msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" -msgid "Thrustmaster Flight Control System" -msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»Ñ–Đ½Đ½Ñ Đ¿Đ¾Đ»ÑŒĐ¾Ñ‚Đ¾Đ¼ Thrustmaster" +msgid "6-button gamepad" +msgstr "6-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»Ñ–Đ½Đ½Ñ ĐºĐµÑ€Đ¼Đ¾Đ¼" - -msgid "2-button gamepad(s)" -msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke" -msgid "4-button gamepad" -msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" +msgid "3-button flight yoke" +msgstr "3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ Đ³ĐµĐ¹Đ¼Đ¿Đ°Đ´" msgid "4-button flight yoke" msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke" @@ -903,11 +890,71 @@ msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke" msgid "2-button flight yoke with throttle" msgstr "2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke Đ· Đ´Ñ€Đ¾ÑĐµĐ»ĐµĐ¼" +msgid "3-button flight yoke with throttle" +msgstr "3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke Đ· Đ´Ñ€Đ¾ÑĐµĐ»ĐµĐ¼" + msgid "4-button flight yoke with throttle" msgstr "4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đ¸Đ¹ flight yoke Đ· Đ´Ñ€Đ¾ÑĐµĐ»ĐµĐ¼" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "ĐĐµÑ€Đ¼Đ¾ Win95 (3-Đ¾ÑÑŒĐ¾Đ²Đµ, 4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đµ)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "ĐĐµÑ€Đ¼Đ¾ (3-Đ¾ÑÑŒĐ¾Đ²Đµ, 2-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đµ)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "ĐĐµÑ€Đ¼Đ¾ (3-Đ¾ÑÑŒĐ¾Đ²Đµ, 3-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đµ)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "ĐĐµÑ€Đ¼Đ¾ (3-Đ¾ÑÑŒĐ¾Đ²Đµ, 4-ĐºĐ½Đ¾Đ¿ĐºĐ¾Đ²Đµ)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH ĐŸĐµĐ´Đ°Đ»Ñ–" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH ĐŸĐµĐ´Đ°Đ»Ñ– Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH ĐŸĐµĐ´Đ°Đ»Ñ–" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH ĐŸĐµĐ´Đ°Đ»Ñ– Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH ĐŸĐµĐ´Đ°Đ»Ñ–" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH ĐŸĐµĐ´Đ°Đ»Ñ– Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH ĐŸĐµĐ´Đ°Đ»Ñ–" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH ĐŸĐµĐ´Đ°Đ»Ñ– Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»Ñ–Đ½Đ½Ñ Đ¿Đ¾Đ»ÑŒĐ¾Ñ‚Đ¾Đ¼ Thrustmaster" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° ÑƒĐ¿Ñ€Đ°Đ²Đ»Ñ–Đ½Đ½Ñ ĐºĐµÑ€Đ¼Đ¾Đ¼" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 Đ· Đ°Đ´Đ°Đ¿Ñ‚ĐµÑ€Đ¾Đ¼" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 без Đ°Đ´Đ°Đ¿Ñ‚ĐµÑ€Đ°" msgid "None" msgstr "ĐÑ–" @@ -978,11 +1025,8 @@ msgstr "Це Đ¿Ñ€Đ¸Đ·Đ²ĐµĐ´Đµ Đ´Đ¾ Ñ…Đ¾Đ»Đ¾Đ´Đ½Đ¾Ñ— Đ¿ĐµÑ€ĐµĐ·Đ°Đ³Ñ€ÑƒĐ·ĐºĐ¸ е msgid "Save" msgstr "Đ—Đ±ĐµÑ€ĐµĐ³Ñ‚Đ¸" -msgid "About 86Box" -msgstr "ĐŸÑ€Đ¾ 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "ĐŸÑ€Đ¾ %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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ĐĐ²Ñ‚Đ¾Ñ€Đ¸: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nĐ— Đ¿Đ¾Đ¿ĐµÑ€ĐµĐ´Đ½Ñ–Đ¼Đ¸ Đ¾ÑĐ½Đ¾Đ²Đ½Đ¸Đ¼Đ¸ Đ²Đ½ĐµÑĐºĐ°Đ¼Đ¸ Sarah Walker, leilei, JohnElliott, greatpsycho Ñ‚Đ° Ñ–Đ½ÑˆĐ¸Ñ….\n\nĐ’Đ¸Đ¿ÑƒÑĐºĐ°Ñ”Ñ‚ÑÑ Đ¿Ñ–Đ´ Đ»Ñ–Ñ†ĐµĐ½Đ·Ñ–Ñ”Ñ GNU General Public License Đ²ĐµÑ€ÑÑ–Ñ— 2 Đ°Đ±Đ¾ Đ±Ñ–Đ»ÑŒÑˆĐµ Đ¿Ñ–Đ·Đ½Ñ–ÑˆĐµ. Đ”Đ¾Đ´Đ°Đ´ĐºĐ¾Đ²Ñƒ Ñ–Đ½Ñ„Đ¾Ñ€Đ¼Đ°Ñ†Ñ–Ñ ÑĐ¼. у Ñ„Đ°Đ¹Đ»Ñ– LICENSE." @@ -1237,7 +1281,7 @@ msgid "C&lone..." msgstr "Đ&Đ»Đ¾Đ½ÑƒĐ²Đ°Ñ‚Đ¸..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" -msgstr "Đ’Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ° Đ¼Đ°ÑˆĐ¸Đ½Đ° \"%1\" (%2) Đ±ÑƒĐ´Đµ ĐºĐ»Đ¾Đ½Đ¾Đ²Đ°Đ½Đ° Đ²:" +msgstr "Đ’Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ° Đ¼Đ°ÑˆĐ¸Đ½Đ° «%1» (%2) Đ±ÑƒĐ´Đµ ĐºĐ»Đ¾Đ½Đ¾Đ²Đ°Đ½Đ° Đ²:" msgid "Directory %1 already exists" msgstr "ĐŸĐ°Đ¿ĐºĐ° %1 Đ²Đ¶Đµ Ñ–ÑĐ½ÑƒÑ”" @@ -1303,13 +1347,13 @@ msgid "&Kill" msgstr "&Đ—Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚Đ¸ Đ¿Ñ€Đ¾Ñ†ĐµÑ" msgid "Killing a virtual machine can cause data loss. Only do this if the 86Box process gets stuck.\n\nDo you really wish to kill the virtual machine \"%1\"?" -msgstr "ĐŸÑ€Đ¸Đ¼ÑƒÑĐ¾Đ²Đµ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ½Ñ Đ¿Ñ€Đ¾Ñ†ĐµÑу Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ Đ¼Đ¾Đ¶Đµ Đ¿Ñ€Đ¸Đ·Đ²ĐµÑÑ‚Đ¸ Đ´Đ¾ Đ²Ñ‚Ñ€Đ°Ñ‚Đ¸ Đ´Đ°Đ½Đ¸Ñ…. Đ Đ¾Đ±Ñ–Ñ‚ÑŒ Ñ†Đµ Ñ‚Ñ–Đ»ÑŒĐºĐ¸ Đ² Ñ‚Đ¾Đ¼Ñƒ Đ²Đ¸Đ¿Đ°Đ´ĐºÑƒ, ÑĐºÑ‰Đ¾ Đ¿Ñ€Đ¾Ñ†ĐµÑ 86Box Đ·Đ°Đ²Đ¸Ñ.\n\nВи Đ´Ñ–Đ¹ÑĐ½Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ Đ¿Ñ€Đ¸Đ¼ÑƒÑĐ¾Đ²Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚Đ¸ Đ¿Ñ€Đ¾Ñ†ĐµÑ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ \"%1\"?" +msgstr "ĐŸÑ€Đ¸Đ¼ÑƒÑĐ¾Đ²Đµ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ½Ñ Đ¿Ñ€Đ¾Ñ†ĐµÑу Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ Đ¼Đ¾Đ¶Đµ Đ¿Ñ€Đ¸Đ·Đ²ĐµÑÑ‚Đ¸ Đ´Đ¾ Đ²Ñ‚Ñ€Đ°Ñ‚Đ¸ Đ´Đ°Đ½Đ¸Ñ…. Đ Đ¾Đ±Ñ–Ñ‚ÑŒ Ñ†Đµ Ñ‚Ñ–Đ»ÑŒĐºĐ¸ Đ² Ñ‚Đ¾Đ¼Ñƒ Đ²Đ¸Đ¿Đ°Đ´ĐºÑƒ, ÑĐºÑ‰Đ¾ Đ¿Ñ€Đ¾Ñ†ĐµÑ 86Box Đ·Đ°Đ²Đ¸Ñ.\n\nВи Đ´Ñ–Đ¹ÑĐ½Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ Đ¿Ñ€Đ¸Đ¼ÑƒÑĐ¾Đ²Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Ñ‚Đ¸ Đ¿Ñ€Đ¾Ñ†ĐµÑ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ «%1»?" msgid "&Delete" msgstr "&Đ’Đ¸Đ´Đ°Đ»Đ¸Ñ‚Đ¸" msgid "Do you really want to delete the virtual machine \"%1\" and all its files? This action cannot be undone!" -msgstr "Ви Đ´Ñ–Đ¹ÑĐ½Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ Đ²Đ¸Đ´Đ°Đ»Đ¸Ñ‚Đ¸ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Ñƒ Đ¼Đ°ÑˆĐ¸Đ½Ñƒ \"%1\" Ñ– Đ²ÑÑ– Ñ—Ñ— Ñ„Đ°Đ¹Đ»Đ¸? Đ¦Ñ Đ´Ñ–Ñ Đ½Đµ Đ¼Đ¾Đ¶Đ½Đ° ÑĐºĐ°ÑÑƒĐ²Đ°Ñ‚Đ¸!" +msgstr "Ви Đ´Ñ–Đ¹ÑĐ½Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ Đ²Đ¸Đ´Đ°Đ»Đ¸Ñ‚Đ¸ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Ñƒ Đ¼Đ°ÑˆĐ¸Đ½Ñƒ «%1» Ñ– Đ²ÑÑ– Ñ—Ñ— Ñ„Đ°Đ¹Đ»Đ¸? Đ¦Ñ Đ´Ñ–Ñ Đ½Đµ Đ¼Đ¾Đ¶Đ½Đ° ÑĐºĐ°ÑÑƒĐ²Đ°Ñ‚Đ¸!" msgid "Show &config file" msgstr "ĐŸĐ¾ĐºĐ°Đ·Đ°Ñ‚Đ¸ Ñ„Đ°Đ¹Đ» &ĐºĐ¾Đ½Ñ„Ñ–Đ³ÑƒÑ€Đ°Ñ†Ñ–Ñ—" @@ -1332,8 +1376,8 @@ msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ°" msgid "Storage" msgstr "ДиÑĐºĐ¸" -msgid "Disk %1: " -msgstr "ДиÑĐº %1: " +msgid "Disk %1:" +msgstr "ДиÑĐº %1:" msgid "No disks" msgstr "ĐĐµĐ¼Đ°Ñ” диÑĐºÑ–Đ²" @@ -1519,13 +1563,13 @@ msgid "720 KB" msgstr "720 ĐĐ‘" msgid "1.2 MB" -msgstr "1.2 ĐœĐ‘" +msgstr "1,2 ĐœĐ‘" msgid "1.25 MB" -msgstr "1.25 ĐœĐ‘" +msgstr "1,25 ĐœĐ‘" msgid "1.44 MB" -msgstr "1.44 ĐœĐ‘" +msgstr "1,44 ĐœĐ‘" msgid "DMF (cluster 1024)" msgstr "DMF (ĐºĐ»Đ°ÑÑ‚ĐµÑ€ 1024)" @@ -1534,40 +1578,40 @@ msgid "DMF (cluster 2048)" msgstr "DMF (ĐºĐ»Đ°ÑÑ‚ĐµÑ€ 2048)" msgid "2.88 MB" -msgstr "2.88 ĐœĐ‘" +msgstr "2,88 ĐœĐ‘" msgid "ZIP 100" msgstr "ZIP 100" msgid "3.5\" 128 MB (ISO 10090)" -msgstr "3.5\" 128 ĐœĐ‘ (ISO 10090)" +msgstr "3,5\" 128 ĐœĐ‘ (ISO 10090)" msgid "3.5\" 230 MB (ISO 13963)" -msgstr "3.5\" 230 ĐœĐ‘ (ISO 13963)" +msgstr "3,5\" 230 ĐœĐ‘ (ISO 13963)" msgid "3.5\" 540 MB (ISO 15498)" -msgstr "3.5\" 540 ĐœĐ‘ (ISO 15498)" +msgstr "3,5\" 540 ĐœĐ‘ (ISO 15498)" msgid "3.5\" 640 MB (ISO 15498)" -msgstr "3.5\" 640 ĐœĐ‘ (ISO 15498)" +msgstr "3,5\" 640 ĐœĐ‘ (ISO 15498)" msgid "3.5\" 1.3 GB (GigaMO)" -msgstr "3.5\" 1.3 ГБ (GigaMO)" +msgstr "3,5\" 1,3 ГБ (GigaMO)" msgid "3.5\" 2.3 GB (GigaMO 2)" -msgstr "3.5\" 2.3 ГБ (GigaMO 2)" +msgstr "3,5\" 2,3 ГБ (GigaMO 2)" msgid "5.25\" 600 MB" -msgstr "5.25\" 600 ĐœĐ‘" +msgstr "5,25\" 600 ĐœĐ‘" msgid "5.25\" 650 MB" -msgstr "5.25\" 650 ĐœĐ‘" +msgstr "5,25\" 650 ĐœĐ‘" msgid "5.25\" 1 GB" -msgstr "5.25\" 1 ГБ" +msgstr "5,25\" 1 ГБ" msgid "5.25\" 1.3 GB" -msgstr "5.25\" 1.3 ГБ" +msgstr "5,25\" 1,3 ГБ" msgid "Perfect RPM" msgstr "Đ¢Đ¾Ñ‡Đ½Đ¸Đ¹ RPM" @@ -1576,7 +1620,7 @@ msgid "1% below perfect RPM" msgstr "Đа 1% Đ¿Đ¾Đ²Ñ–Đ»ÑŒĐ½Ñ–ÑˆĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" msgid "1.5% below perfect RPM" -msgstr "Đа 1.5% Đ¿Đ¾Đ²Ñ–Đ»ÑŒĐ½Ñ–ÑˆĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" +msgstr "Đа 1,5% Đ¿Đ¾Đ²Ñ–Đ»ÑŒĐ½Ñ–ÑˆĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" msgid "2% below perfect RPM" msgstr "Đа 2% Đ¿Đ¾Đ²Ñ–Đ»ÑŒĐ½Ñ–ÑˆĐµ Ñ‚Đ¾Ñ‡Đ½Đ¾Đ³Đ¾ RPM" @@ -1714,7 +1758,7 @@ msgid "Remove" msgstr "Đ’Đ¸Đ´Đ°Đ»Đ¸Ñ‚Đ¸" msgid "Browse..." -msgstr "ĐŸĐµÑ€ĐµĐ³Đ»ÑĐ½ÑƒÑ‚Đ¸..." +msgstr "ĐĐ³Đ»ÑĐ´..." msgid "Couldn't create OpenGL context." msgstr "Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ ÑÑ‚Đ²Đ¾Ñ€Đ¸Ñ‚Đ¸ ĐºĐ¾Đ½Ñ‚ĐµĐºÑÑ‚ OpenGL." @@ -1738,7 +1782,7 @@ msgid "This machine might have been moved or copied." msgstr "Đ¦Ñ Đ¼Đ°ÑˆĐ¸Đ½Ñƒ Đ¼Đ¾Đ³Đ»Đ¸ Đ¿ĐµÑ€ĐµĐ¼Ñ–ÑÑ‚Đ¸Ñ‚Đ¸ Đ°Đ±Đ¾ ÑĐºĐ¾Đ¿Ñ–ÑĐ²Đ°Ñ‚Đ¸." msgid "In order to ensure proper networking functionality, 86Box needs to know if this machine was moved or copied.\n\nSelect \"I Copied It\" if you are not sure." -msgstr "Đ©Đ¾Đ± Đ·Đ°Đ±ĐµĐ·Đ¿ĐµÑ‡Đ¸Ñ‚Đ¸ Đ½Đ°Đ»ĐµĐ¶Đ½Ñƒ Đ¼ĐµÑ€ĐµĐ¶ĐµĐ²Ñƒ Ñ„ÑƒĐ½ĐºÑ†Ñ–Đ¾Đ½Đ°Đ»ÑŒĐ½Ñ–Ñть, 86Box Đ¿Đ¾Đ²Đ¸Đ½ĐµĐ½ Đ·Đ½Đ°Ñ‚Đ¸, Ñ‡Đ¸ Đ¼Đ°ÑˆĐ¸Đ½Đ° Đ±ÑƒĐ»Đ° Đ¿ĐµÑ€ĐµĐ¼Ñ–Ñ‰ĐµĐ½Đ° Đ°Đ±Đ¾ ÑĐºĐ¾Đ¿Ñ–Đ¹Đ¾Đ²Đ°Đ½Đ°.\n\nĐ¯ĐºÑ‰Đ¾ Đ²Đ¸ Đ½Đµ Đ²Đ¿ĐµĐ²Đ½ĐµĐ½Ñ–, Đ²Đ¸Đ±ĐµÑ€Ñ–Ñ‚Đµ \"Đ¡ĐºĐ¾Đ¿Ñ–Đ¹Đ¾Đ²Đ°Đ½Đ°\"." +msgstr "Đ©Đ¾Đ± Đ·Đ°Đ±ĐµĐ·Đ¿ĐµÑ‡Đ¸Ñ‚Đ¸ Đ½Đ°Đ»ĐµĐ¶Đ½Ñƒ Đ¼ĐµÑ€ĐµĐ¶ĐµĐ²Ñƒ Ñ„ÑƒĐ½ĐºÑ†Ñ–Đ¾Đ½Đ°Đ»ÑŒĐ½Ñ–Ñть, 86Box Đ¿Đ¾Đ²Đ¸Đ½ĐµĐ½ Đ·Đ½Đ°Ñ‚Đ¸, Ñ‡Đ¸ Đ¼Đ°ÑˆĐ¸Đ½Đ° Đ±ÑƒĐ»Đ° Đ¿ĐµÑ€ĐµĐ¼Ñ–Ñ‰ĐµĐ½Đ° Đ°Đ±Đ¾ ÑĐºĐ¾Đ¿Ñ–Đ¹Đ¾Đ²Đ°Đ½Đ°.\n\nĐ¯ĐºÑ‰Đ¾ Đ²Đ¸ Đ½Đµ Đ²Đ¿ĐµĐ²Đ½ĐµĐ½Ñ–, Đ²Đ¸Đ±ĐµÑ€Ñ–Ñ‚Đµ Â«Đ¡ĐºĐ¾Đ¿Ñ–Đ¹Đ¾Đ²Đ°Đ½Đ°Â»." msgid "I Moved It" msgstr "ĐŸĐµÑ€ĐµĐ¼Ñ–Ñ‰ĐµĐ½Đ°" @@ -1746,8 +1790,8 @@ msgstr "ĐŸĐµÑ€ĐµĐ¼Ñ–Ñ‰ĐµĐ½Đ°" msgid "I Copied It" msgstr "Đ¡ĐºĐ¾Đ¿Ñ–Đ¹Đ¾Đ²Đ°Đ½Đ°" -msgid "86Box Monitor #" -msgstr "ĐœĐ¾Đ½Ñ–Ñ‚Đ¾Ñ€ 86Box " +msgid "86Box Monitor #%1" +msgstr "ĐœĐ¾Đ½Ñ–Ñ‚Đ¾Ñ€ 86Box %1" msgid "No MCA devices." msgstr "ĐÑ–ÑĐºĐ¸Ñ… Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ—Đ² MCA." @@ -1782,6 +1826,9 @@ msgstr "ĐĐ´Đ°Đ¿Ñ‚ĐµÑ€:" msgid "VDE Socket:" msgstr "VDE ÑĐ¾ĐºĐµÑ‚:" +msgid "TAP Bridge Device:" +msgstr "ĐŸÑ€Đ¸ÑÑ‚Ñ€Ñ–Đ¹ Đ¼Đ¾ÑÑ‚Đ° TAP:" + msgid "86Box Unit Tester" msgstr "Đ¢ĐµÑÑ‚ĐµÑ€ Đ±Đ»Đ¾ĐºÑ–Đ² 86Box" @@ -2157,12 +2204,6 @@ msgstr "Đ¡Đ¸Đ»Đ° Ñ„Ñ–Đ»ÑŒÑ‚Ñ€Đ° SID" msgid "Surround module" msgstr "ĐœĐ¾Đ´ÑƒĐ»ÑŒ Đ¾Đ±'Ñ”Đ¼Đ½Đ¾Đ³Đ¾ Đ·Đ²ÑƒÑ‡Đ°Đ½Đ½Ñ" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "ĐŸÑ–Đ´Đ½Ñ–Đ¼Đ°Ñ‚Đ¸ Đ¿ĐµÑ€ĐµÑ€Đ¸Đ²Đ°Đ½Đ½Ñ CODEC Đ¿Ñ–Đ´ Ñ‡Đ°Ñ Đ²ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½Đ½Ñ CODEC (Đ¿Đ¾Ñ‚Ñ€Ñ–Đ±Đ½Đ¾ Đ´Đ»Ñ Đ´ĐµÑĐºĐ¸Ñ… Đ´Ñ€Đ°Đ¹Đ²ĐµÑ€Ñ–Đ²)" - msgid "SB Address" msgstr "ĐĐ´Ñ€ĐµÑа SB" @@ -2178,6 +2219,18 @@ msgstr "IRQ WSS" msgid "WSS DMA" msgstr "DMA WSS" +msgid "RTC IRQ" +msgstr "IRQ RTC" + +msgid "RTC Port Address" +msgstr "ĐĐ´Ñ€ĐµÑа Đ¿Đ¾Ñ€Ñ‚Ñƒ RTC" + +msgid "Onboard RTC" +msgstr "Đ’Đ±ÑƒĐ´Đ¾Đ²Đ°Đ½Đ¸Đ¹ RTC" + +msgid "Not installed" +msgstr "Đе Đ²ÑÑ‚Đ°Đ½Đ¾Đ²Đ»ĐµĐ½" + msgid "Enable OPL" msgstr "Đ’Đ²Ñ–Đ¼ĐºĐ½ÑƒÑ‚Đ¸ OPL" @@ -2218,7 +2271,7 @@ msgid "GUS type" msgstr "Đ¢Đ¸Đ¿ GUS" msgid "Enable 0x04 \"Exit 86Box\" command" -msgstr "Đ£Đ²Ñ–Đ¼ĐºĐ½ÑƒÑ‚Đ¸ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñƒ 0x04 \"Đ’Đ¸Ñ…Ñ–Đ´ Đ· 86Box\"." +msgstr "Đ£Đ²Ñ–Đ¼ĐºĐ½ÑƒÑ‚Đ¸ ĐºĐ¾Đ¼Đ°Đ½Đ´Ñƒ 0x04 Â«Đ’Đ¸Ñ…Ñ–Đ´ Đ· 86Box»" msgid "Display type" msgstr "Đ¢Đ¸Đ¿ Đ²Ñ–Đ´Đ¾Đ±Ñ€Đ°Đ¶ĐµĐ½Đ½Ñ" @@ -2448,9 +2501,6 @@ msgstr "24 ĐœĐ‘" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (ÑÑ‚ĐµÑ€ĐµĐ¾)" -msgid "Classic" -msgstr "ĐлаÑĐ¸Ñ‡Đ½Đ¸Đ¹" - msgid "256 KB" msgstr "256 ĐĐ‘" @@ -2707,7 +2757,7 @@ msgid "Unable to find Dot-Matrix fonts" msgstr "ĐĐµĐ¼Đ¾Đ¶Đ»Đ¸Đ²Đ¾ Đ·Đ½Đ°Đ¹Ñ‚Đ¸ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Ñ– ÑˆÑ€Đ¸Ñ„Ñ‚Đ¸" msgid "TrueType fonts in the \"roms/printer/fonts\" directory are required for the emulation of the Generic ESC/P 2 Dot-Matrix Printer." -msgstr "Đ¨Ñ€Đ¸Ñ„Ñ‚Đ¸ TrueType у ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ·Ñ– \"roms/printer/fonts\" Đ¿Đ¾Ñ‚Ñ€Ñ–Đ±Đ½Ñ– Đ´Đ»Ñ ĐµĐ¼ÑƒĐ»Ñції Đ·Đ°Đ³Đ°Đ»ÑŒĐ½Đ¾Đ³Đ¾ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Đ¾Đ³Đ¾ Đ¿Ñ€Đ¸Đ½Ñ‚ĐµÑ€Đ° Generic ESC/P 2." +msgstr "Đ¨Ñ€Đ¸Ñ„Ñ‚Đ¸ TrueType у ĐºĐ°Ñ‚Đ°Đ»Đ¾Đ·Ñ– «roms/printer/fonts» Đ¿Đ¾Ñ‚Ñ€Ñ–Đ±Đ½Ñ– Đ´Đ»Ñ ĐµĐ¼ÑƒĐ»Ñції Đ·Đ°Đ³Đ°Đ»ÑŒĐ½Đ¾Đ³Đ¾ Đ¼Đ°Ñ‚Ñ€Đ¸Ñ‡Đ½Đ¾Đ³Đ¾ Đ¿Ñ€Đ¸Đ½Ñ‚ĐµÑ€Đ° Generic ESC/P 2." msgid "Inhibit multimedia keys" msgstr "ĐŸĐµÑ€ĐµÑ…Đ¾Đ¿Đ»ÑĐ²Đ°Ñ‚Đ¸ Đ¼ÑƒĐ»ÑŒÑ‚Đ¸Đ¼ĐµĐ´Ñ–Đ¹Đ½Ñ– ĐºĐ»Đ°Đ²Ñ–ÑˆÑ–" @@ -2739,9 +2789,6 @@ msgstr "ĐŸĐ¾Đ¼Đ¸Đ»ĐºĐ° GLSL" msgid "Could not load shader: %1" msgstr "Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶Đ¸Ñ‚Đ¸ ÑˆĐµĐ¹Đ´ĐµÑ€: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "ĐŸĐ¾Ñ‚Ñ€Ñ–Đ±Đ½Đ° OpenGL Đ²ĐµÑ€ÑÑ–Ñ— 3.0 Đ°Đ±Đ¾ Đ²Đ¸Ñ‰Đµ. ĐŸĐ¾Ñ‚Đ¾Ñ‡Đ½Đ° Đ²ĐµÑ€ÑÑ–Ñ GLSL %1.%2" - msgid "Could not load texture: %1" msgstr "Đе Đ²Đ´Đ°Đ»Đ¾ÑÑ Đ·Đ°Đ²Đ°Đ½Ñ‚Đ°Đ¶Đ¸Ñ‚Đ¸ Ñ‚ĐµĐºÑтуру: %1" @@ -2805,6 +2852,9 @@ msgstr "ĐĐ°Đ´Ñ–ÑĐ»Đ°Ñ‚Đ¸ Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡Đ¸Ñ‚Đ¸ Đ¿Đ¾Đ²Đ½Đ¾ĐµĐºÑ€Đ°Đ½Đ½Đ¸Đ¹ Ñ€ĐµĐ¶Đ¸Đ¼" +msgid "Toggle UI in fullscreen" +msgstr "ĐŸĐµÑ€ĐµĐºĐ»ÑÑ‡Đ¸Ñ‚Đ¸ UI Đ² Đ¿Đ¾Đ²Đ½Đ¾ĐµĐºÑ€Đ°Đ½Đ½Đ¾Đ¼Ñƒ Ñ€ĐµĐ¶Đ¸Đ¼Ñ–" + msgid "Screenshot" msgstr "Đ¡ĐºÑ€Ñ–Đ½ÑˆĐ¾Ñ‚" @@ -2851,16 +2901,16 @@ msgid "&Wipe NVRAM" msgstr "&Đ¡Ñ‚ĐµÑ€Ñ‚Đ¸ NVRAM" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "Це Đ²Đ¸Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ²ÑÑ– Ñ„Đ°Đ¹Đ»Đ¸ NVRAM (Ñ– Đ¿Đ¾Đ²'ÑĐ·Đ°Đ½Ñ–) Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸, Ñ€Đ¾Đ·Ñ‚Đ°ÑˆĐ¾Đ²Đ°Đ½Đ¾Ñ— Đ² Đ¿Ñ–Đ´Đ¿Đ°Đ¿Ñ†Ñ– «nvr». Đ’Đ°Đ¼ Đ´Đ¾Đ²ĐµĐ´ĐµÑ‚ÑŒÑÑ Đ·Đ½Đ¾Đ²Ñƒ Đ½Đ°Đ»Đ°ÑˆÑ‚ÑƒĐ²Đ°Ñ‚Đ¸ BIOS (Ñ–, Đ¼Đ¾Đ¶Đ»Đ¸Đ²Đ¾, Ñ–Đ½ÑˆÑ– Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ— Đ²ÑĐµÑ€ĐµĐ´Đ¸Đ½Ñ– Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸), ÑĐºÑ‰Đ¾ Ñ†Đµ Đ½ĐµĐ¾Đ±Ñ…Ñ–Đ´Đ½Đ¾. Ви Đ²Đ¿ĐµĐ²Đ½ĐµĐ½Ñ–, Ñ‰Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ ÑÑ‚ĐµÑ€Ñ‚Đ¸ Đ²ĐµÑÑŒ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ \"%1\"?" +msgstr "Це Đ²Đ¸Đ´Đ°Đ»Đ¸Ñ‚ÑŒ Đ²ÑÑ– Ñ„Đ°Đ¹Đ»Đ¸ NVRAM (Ñ– Đ¿Đ¾Đ²'ÑĐ·Đ°Đ½Ñ–) Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸, Ñ€Đ¾Đ·Ñ‚Đ°ÑˆĐ¾Đ²Đ°Đ½Đ¾Ñ— Đ² Đ¿Ñ–Đ´Đ¿Đ°Đ¿Ñ†Ñ– «nvr». Đ’Đ°Đ¼ Đ´Đ¾Đ²ĐµĐ´ĐµÑ‚ÑŒÑÑ Đ·Đ½Đ¾Đ²Ñƒ Đ½Đ°Đ»Đ°ÑˆÑ‚ÑƒĐ²Đ°Ñ‚Đ¸ BIOS (Ñ–, Đ¼Đ¾Đ¶Đ»Đ¸Đ²Đ¾, Ñ–Đ½ÑˆÑ– Đ¿Ñ€Đ¸ÑÑ‚Ñ€Đ¾Ñ— Đ²ÑĐµÑ€ĐµĐ´Đ¸Đ½Ñ– Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸), ÑĐºÑ‰Đ¾ Ñ†Đµ Đ½ĐµĐ¾Đ±Ñ…Ñ–Đ´Đ½Đ¾.\n\nВи Đ²Đ¿ĐµĐ²Đ½ĐµĐ½Ñ–, Ñ‰Đ¾ Ñ…Đ¾Ñ‡ĐµÑ‚Đµ ÑÑ‚ĐµÑ€Ñ‚Đ¸ Đ²ĐµÑÑŒ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ «%1»?" msgid "Success" msgstr "Đ£ÑĐ¿Ñ–ÑˆĐ½Đ¾" msgid "Successfully wiped the NVRAM contents of the virtual machine \"%1\"" -msgstr "Đ£ÑĐ¿Ñ–ÑˆĐ½Đ¾ ÑÑ‚ĐµÑ€Ñ‚Đ¾ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ \"%1\"" +msgstr "Đ£ÑĐ¿Ñ–ÑˆĐ½Đ¾ ÑÑ‚ĐµÑ€Ñ‚Đ¾ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ «%1»" msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" -msgstr "Đ¡Ñ‚Đ°Đ»Đ°ÑÑ Đ¿Đ¾Đ¼Đ¸Đ»ĐºĐ° Đ¿Ñ€Đ¸ ÑĐ¿Ñ€Đ¾Đ±Ñ– ÑÑ‚ĐµÑ€Ñ‚Đ¸ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ \"%1\"" +msgstr "Đ¡Ñ‚Đ°Đ»Đ°ÑÑ Đ¿Đ¾Đ¼Đ¸Đ»ĐºĐ° Đ¿Ñ€Đ¸ ÑĐ¿Ñ€Đ¾Đ±Ñ– ÑÑ‚ĐµÑ€Ñ‚Đ¸ Đ²Đ¼Ñ–ÑÑ‚ NVRAM Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ «%1»" msgid "%1 VM Manager" msgstr "ĐœĐµĐ½ĐµĐ´Đ¶ĐµÑ€ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¸Ñ… Đ¼Đ°ÑˆĐ¸Đ½ %1" @@ -2938,7 +2988,7 @@ msgid "Virtual machine crash" msgstr "Đ—Đ±Ñ–Đ¹ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸" msgid "The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2." -msgstr "ĐŸÑ€Đ¾Ñ†ĐµÑ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ \"%1\" Đ½ĐµÑĐ¿Đ¾Đ´Ñ–Đ²Đ°Đ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Đ²ÑÑ Đ· ĐºĐ¾Đ´Đ¾Đ¼ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ½Ñ %2." +msgstr "ĐŸÑ€Đ¾Ñ†ĐµÑ Đ²Ñ–Ñ€Ñ‚ÑƒĐ°Đ»ÑŒĐ½Đ¾Ñ— Đ¼Đ°ÑˆĐ¸Đ½Đ¸ «%1» Đ½ĐµÑĐ¿Đ¾Đ´Ñ–Đ²Đ°Đ½Đ¾ Đ·Đ°Đ²ĐµÑ€ÑˆĐ¸Đ²ÑÑ Đ· ĐºĐ¾Đ´Đ¾Đ¼ Đ·Đ°Đ²ĐµÑ€ÑˆĐµĐ½Đ½Ñ %2." msgid "The system will not be added." msgstr "Đ¡Đ¸ÑÑ‚ĐµĐ¼Đ° Đ½Đµ Đ±ÑƒĐ´Đµ Đ´Đ¾Đ´Đ°Đ½Đ°." @@ -2977,7 +3027,7 @@ msgid "Export EDID" msgstr "Đ•ĐºÑĐ¿Đ¾Ñ€Ñ‚ EDID" msgid "EDID file \"%ls\" is too large." -msgstr "Đ¤Đ°Đ¹Đ» EDID \"%ls\" Đ·Đ°Đ½Đ°Đ´Ñ‚Đ¾ Đ²ĐµĐ»Đ¸ĐºĐ¸Đ¹." +msgstr "Đ¤Đ°Đ¹Đ» EDID «%ls» Đ·Đ°Đ½Đ°Đ´Ñ‚Đ¾ Đ²ĐµĐ»Đ¸ĐºĐ¸Đ¹." msgid "OpenGL input scale" msgstr "Đ¨ĐºĐ°Đ»Đ° Đ²Đ²ĐµĐ´ĐµĐ½Đ½Ñ OpenGL" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 24decb5228d..09d5defa3d3 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -196,7 +196,7 @@ msgid "&Settings..." msgstr "&CĂ i đặt..." msgid "Settings..." -msgstr "CĂ i đặt" +msgstr "CĂ i đặt..." msgid "&Update status bar icons" msgstr "Cậ&p nhật biểu tượng thanh trạng thĂ¡i" @@ -271,37 +271,7 @@ msgid "Reload previous image" msgstr "Load đĩa trước Ä‘Ă³" msgid "&Folder..." -msgstr "Thư mụ&c" - -msgid "Target &framerate" -msgstr "Số khung hình mục tiĂªu" - -msgid "&Sync with video" -msgstr "Äồng bá»™ &vá»›i 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 "&Chá»n shader..." - -msgid "&Remove shader" -msgstr "&Bá» shader" +msgstr "Thư mụ&c..." msgid "Preferences" msgstr "TĂ¹y biến" @@ -603,9 +573,6 @@ msgstr "KĂªnh:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "Chỉ &rõ..." - msgid "Sectors:" msgstr "Sector:" @@ -690,9 +657,6 @@ msgstr "Thiết bị ISABugger" msgid "POST card" msgstr "Thẻ POST" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "Lá»—i" @@ -852,9 +816,18 @@ msgstr "KhĂ´ng tìm thấy thiết bị PCap" msgid "Invalid PCap device" msgstr "Thiết bị PCap khĂ´ng hợp quy" +msgid "Generic paddle controller(s)" +msgstr "Bá»™ Ä‘iá»u khiển dạng mĂ¡i chèo thĂ´ng dụng" + +msgid "2-axis, 1-button joystick(s)" +msgstr "Cần Ä‘iá»u khiển hai trục, má»™t nĂºt" + msgid "2-axis, 2-button joystick(s)" msgstr "Cần Ä‘iá»u khiển hai trục, hai nĂºt" +msgid "2-axis, 3-button joystick" +msgstr "Cần Ä‘iá»u khiển hai trục, ba nĂºt" + msgid "2-axis, 4-button joystick" msgstr "Cần Ä‘iá»u khiển hai trục, bốn nĂºt" @@ -867,35 +840,41 @@ msgstr "Cần Ä‘iá»u khiển hai trục, tĂ¡m nĂºt" msgid "3-axis, 2-button joystick" msgstr "Cần Ä‘iá»u khiển ba trục, hai nĂºt" +msgid "3-axis, 3-button joystick" +msgstr "Cần Ä‘iá»u khiển ba trục, ba nĂºt" + msgid "3-axis, 4-button joystick" msgstr "Cần Ä‘iá»u khiển ba trục, bốn nĂºt" +msgid "4-axis, 2-button joystick" +msgstr "Cần Ä‘iá»u khiển bốn trục, hai nĂºt" + +msgid "4-axis, 3-button joystick" +msgstr "Cần Ä‘iá»u khiển bốn trục, ba nĂºt" + msgid "4-axis, 4-button joystick" msgstr "Cần Ä‘iá»u khiển bốn trục, bốn nĂºt" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + bĂ n giậm CH" +msgid "2-button gamepad(s)" +msgstr "Tay cầm game hai nĂºt" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "Tay cầm game ba nĂºt" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "Tay cầm game bốn nĂºt" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Hệ thống bĂ¡nh lĂ¡i" +msgid "6-button gamepad" +msgstr "Tay cầm game sĂ¡u nĂºt" -msgid "2-button gamepad(s)" -msgstr "Tay cầm game hai nĂºt" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "VĂ´ lăng mĂ¡y bay hai nĂºt" -msgid "4-button gamepad" -msgstr "Tay cầm game bốn nĂºt" +msgid "3-button flight yoke" +msgstr "VĂ´ lăng mĂ¡y bay ba nĂºt" msgid "4-button flight yoke" msgstr "VĂ´ lăng mĂ¡y bay bốn nĂºt" @@ -903,11 +882,71 @@ msgstr "VĂ´ lăng mĂ¡y bay bốn nĂºt" msgid "2-button flight yoke with throttle" msgstr "VĂ´ lăng mĂ¡y bay hai nĂºt cĂ³ cần ga" +msgid "3-button flight yoke with throttle" +msgstr "VĂ´ lăng mĂ¡y bay ba nĂºt cĂ³ cần ga" + msgid "4-button flight yoke with throttle" msgstr "VĂ´ lăng mĂ¡y bay bốn nĂºt cĂ³ cần ga" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "VĂ´ lăng Win95 (ba trục, bốn nĂºt)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "VĂ´ lăng (ba trục, hai nĂºt)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "VĂ´ lăng (ba trục, ba nĂºt)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "VĂ´ lăng (ba trục, bốn nĂºt)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + bĂ n giậm CH" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + bĂ n giậm CH Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + bĂ n giậm CH" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + bĂ n giậm CH Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + bĂ n giậm CH" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + bĂ n giậm CH Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + bĂ n giậm CH" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + bĂ n giậm CH Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Hệ thống bĂ¡nh lĂ¡i" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "Thrustmaster Formula T1/T2 kèm bá»™ chuyển đổi" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "Thrustmaster Formula T1/T2 khĂ´ng kèm bá»™ chuyển đổi" msgid "None" msgstr "KhĂ´ng cĂ³" @@ -958,7 +997,7 @@ msgid "&File" msgstr "&Tập tin" msgid "&New machine..." -msgstr "MĂ¡y &má»›i" +msgstr "MĂ¡y &má»›i..." msgid "&Check for updates..." msgstr "Kiểm tra &cập nhật..." @@ -978,11 +1017,8 @@ msgstr "Lệnh nĂ y sẽ buá»™c khởi động lại mĂ¡y ảo." msgid "Save" msgstr "Lưu" -msgid "About 86Box" -msgstr "Vá» 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "Vá» %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information." msgstr "Trình giả lập cĂ¡c dĂ²ng mĂ¡y tĂ­nh cổ.\n\nTĂ¡c giả: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, cĂ¹ng những ngưá»i khĂ¡c.\n\nCĂ¹ng vá»›i những Ä‘Ă³ng gĂ³p cốt cĂ¡n từ Sarah Walker, leilei, JohnElliott, greatpsycho, vĂ  má»™t số ngưá»i khĂ¡c.\n\nPhĂ¡t hĂ nh dưới giấy phĂ©p GNU General Public License version 2 trở Ä‘i. Äá»c LICENSE để biết thĂªm thĂ´ng tin." @@ -1027,7 +1063,7 @@ msgid "GLSL shaders" msgstr "Shader GLSL" msgid "You are loading an unsupported configuration" -msgstr "Bạn Ä‘ang load tinh chỉnh khĂ´ng được há»— trợ." +msgstr "Bạn Ä‘ang load tinh chỉnh khĂ´ng được há»— trợ" 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 "Phần chá»n loại CPU dá»±a trĂªn mẫu mĂ¡y Ä‘Ă£ chá»n bị vĂ´ hiệu hĂ³a.\n\ná» Ä‘Ă¢y bạn cĂ³ thể chá»n loại CPU cĂ³ thể khĂ´ng tương thĂ­ch vá»›i mẫu mĂ¡y hiện tại. Tuy nhiĂªn bạn cĂ³ thể gặp vấn đỠtương khắc vá»›i BIOS hay phần má»m khĂ¡c.\n\nViệc bật tĂ¹y chá»n nĂ y lĂªn khĂ´ng được khuyến cĂ¡o chĂ­nh thức vĂ  cĂ¡c bản bug report (bĂ¡o lá»—i) vá»›i ná»™i dung tương tá»± sẽ bị coi lĂ  phạm quy vĂ  Ä‘Ă³ng." @@ -1216,25 +1252,25 @@ msgid "Enter the new display name (blank to reset)" msgstr "Äiá»n tĂªn hiển thị má»›i (để trống để đặt lại)" msgid "Change &display name..." -msgstr "Thay đổi tĂªn hiển thị" +msgstr "Thay đổi tĂªn hiển thị..." msgid "Context Menu" msgstr "Menu ngữ cảnh" msgid "&Open folder..." -msgstr "Mở thư mục" +msgstr "Mở thư mục..." msgid "Open p&rinter tray..." -msgstr "Mở khay mĂ¡y in" +msgstr "Mở khay mĂ¡y in..." msgid "Set &icon..." -msgstr "Äặt biểu trưng" +msgstr "Äặt biểu trưng..." msgid "Select an icon" msgstr "Chá»n má»™t biểu trưng" msgid "C&lone..." -msgstr "Tạo bản sao" +msgstr "Tạo bản sao..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" msgstr "MĂ¡y ảo \"%1\" (%2) sẽ được sao chĂ©p vĂ o:" @@ -1332,8 +1368,8 @@ msgstr "Hệ thống" msgid "Storage" msgstr "Lưu trữ" -msgid "Disk %1: " -msgstr "ÄÄ©a %1: " +msgid "Disk %1:" +msgstr "ÄÄ©a %1:" msgid "No disks" msgstr "KhĂ´ng cĂ³ đĩa" @@ -1746,8 +1782,8 @@ msgstr "TĂ´i Ä‘Ă£ di chuyển nĂ³" msgid "I Copied It" msgstr "TĂ´i Ä‘Ă£ sao chĂ©p nĂ³" -msgid "86Box Monitor #" -msgstr "MĂ n hình 86box #" +msgid "86Box Monitor #%1" +msgstr "MĂ n hình 86Box #%1" msgid "No MCA devices." msgstr "KhĂ´ng cĂ³ thiết bị MCA." @@ -1782,6 +1818,9 @@ msgstr "Bá»™ chuyển đổi:" msgid "VDE Socket:" msgstr "á»” cắm VDE:" +msgid "TAP Bridge Device:" +msgstr "" + msgid "86Box Unit Tester" msgstr "Trình kiểm tra đơn vị 86box" @@ -2157,12 +2196,6 @@ msgstr "Cưá»ng độ bá»™ lá»c SID" msgid "Surround module" msgstr "MĂ´ Ä‘un vĂ²m" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "Tăng ngắt CODEC trĂªn thiết lập CODEC (cần bởi má»™t số trình Ä‘iá»u khiển)" - msgid "SB Address" msgstr "Äịa chỉ SB" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "" + +msgid "RTC Port Address" +msgstr "" + +msgid "Onboard RTC" +msgstr "" + +msgid "Not installed" +msgstr "" + msgid "Enable OPL" msgstr "Bật OPL" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "Sigmatel Stac9721T (Ă¢m thanh nổi)" -msgid "Classic" -msgstr "Cổ Ä‘iển" - msgid "256 KB" msgstr "256 KB" @@ -2739,9 +2781,6 @@ msgstr "Lá»—i GLSL" msgid "Could not load shader: %1" msgstr "KhĂ´ng thể nạp shader: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "YĂªu cầu OpenGL bản 3.0 trở lĂªn. Hiện tại bản GLSL lĂ  %1.%2" - msgid "Could not load texture: %1" msgstr "KhĂ´ng thể nạp texture: %1" @@ -2788,7 +2827,7 @@ msgid "Bind Key" msgstr "Gắn phĂ­m" msgid "Enter key combo:" -msgstr "Nhập tổ hợp phĂ­m" +msgstr "Nhập tổ hợp phĂ­m:" msgid "Bind conflict" msgstr "Gắn phĂ­m trĂ¹ng lặp" @@ -2805,6 +2844,9 @@ msgstr "Gá»­i Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "Bật/tắt toĂ n mĂ n hình" +msgid "Toggle UI in fullscreen" +msgstr "" + msgid "Screenshot" msgstr "Chụp mĂ n hình" @@ -2902,13 +2944,13 @@ msgid "build" msgstr "bản dá»±ng" msgid "You are currently running version %1." -msgstr "Bạn Ä‘ang chạy phiĂªn bản %1" +msgstr "Bạn Ä‘ang chạy phiĂªn bản %1." msgid "Version %1 is now available." msgstr "PhiĂªn bản %1 hiện Ä‘Ă£ ra mắt." msgid "You are currently running build %1." -msgstr "Bạn Ä‘ang chạy bản dá»±ng %1" +msgstr "Bạn Ä‘ang chạy bản dá»±ng %1." msgid "Build %1 is now available." msgstr "Bản dá»±ng %1 hiện Ä‘Ă£ ra mắt." diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 48ffc0dc90b..96951cdd75b 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -67,7 +67,7 @@ msgid "&VNC" msgstr "VNC(&V)" msgid "Specify &dimensions..." -msgstr "指å®çª—å£å¤§å°...(&D)" +msgstr "指å®çª—å£å¤§å°(&D)..." msgid "Force &4:3 display ratio" msgstr "强制 4:3 显示比例(&4)" @@ -109,10 +109,10 @@ msgid "Fi<er method" msgstr "过滤方å¼(&L)" msgid "&Nearest" -msgstr "邻近(&N)" +msgstr "è¿‘é‚»å–æ ·(&N)" msgid "&Linear" -msgstr "线性(&L)" +msgstr "线性过滤(&L)" msgid "Hi&DPI scaling" msgstr "HiDPI 缩放(&D)" @@ -196,7 +196,7 @@ msgid "&Settings..." msgstr "设置(&S)..." msgid "Settings..." -msgstr "设置" +msgstr "设置..." msgid "&Update status bar icons" msgstr "æ›´æ–°ç¶æ€æ å›¾æ ‡(&U)" @@ -273,36 +273,6 @@ msgstr "载入ä¸ä¸€ä¸ªæ˜ åƒ" msgid "&Folder..." msgstr "文件夹(&F)..." -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 "首选项" @@ -394,7 +364,7 @@ msgid "Disabled" msgstr "ç¦ç”¨" msgid "Enabled (local time)" -msgstr "å¯ç”¨ (本地时间)" +msgstr "å¯ç”¨ (本地时区)" msgid "Enabled (UTC)" msgstr "å¯ç”¨ (UTC)" @@ -484,10 +454,10 @@ msgid "Standalone MPU-401" msgstr "独立 MPU-401" msgid "Use FLOAT32 sound" -msgstr "使用å•精度浮点 (FLOAT32) 音频" +msgstr "使用å•精度浮点(FLOAT32)音频" msgid "FM synth driver" -msgstr "FM synth driver" +msgstr "FMåˆæˆå™¨é©±å¨" msgid "Nuked (more accurate)" msgstr "Nuked (更准确)" @@ -550,7 +520,7 @@ msgid "FD Controller:" msgstr "软盘æ§åˆ¶å™¨:" msgid "CD-ROM Controller:" -msgstr "CD-ROM æ§åˆ¶å™¨" +msgstr "CD-ROM æ§åˆ¶å™¨:" msgid "Tertiary IDE Controller" msgstr "第三 IDE æ§åˆ¶å™¨" @@ -603,9 +573,6 @@ msgstr "é€é“:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "指å®(&S)..." - msgid "Sectors:" msgstr "扇区(S):" @@ -690,9 +657,6 @@ msgstr "ISABugger 设备" msgid "POST card" msgstr "自检 (POST) å¡" -msgid "86Box" -msgstr "86Box" - msgid "Error" msgstr "错误" @@ -852,9 +816,18 @@ msgstr "未找到 PCap 设备" msgid "Invalid PCap device" msgstr "无效 PCap 设备" +msgid "Generic paddle controller(s)" +msgstr "é€ç”¨æ¡¨å¼æ§åˆ¶å™¨" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2 è½´, 1 é”®æ“纵æ†" + msgid "2-axis, 2-button joystick(s)" msgstr "2 è½´, 2 é”®æ“纵æ†" +msgid "2-axis, 3-button joystick" +msgstr "2 è½´, 3 é”®æ“纵æ†" + msgid "2-axis, 4-button joystick" msgstr "2 è½´, 4 é”®æ“纵æ†" @@ -867,35 +840,41 @@ msgstr "2 è½´, 8 é”®æ“纵æ†" msgid "3-axis, 2-button joystick" msgstr "3 è½´, 2 é”®æ“纵æ†" +msgid "3-axis, 3-button joystick" +msgstr "3 è½´, 3 é”®æ“纵æ†" + msgid "3-axis, 4-button joystick" msgstr "3 è½´, 4 é”®æ“纵æ†" +msgid "4-axis, 2-button joystick" +msgstr "4 è½´, 2 é”®æ“纵æ†" + +msgid "4-axis, 3-button joystick" +msgstr "4 è½´, 3 é”®æ“纵æ†" + msgid "4-axis, 4-button joystick" msgstr "4 è½´, 4 é”®æ“纵æ†" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "2 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "6 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" -msgid "2-button gamepad(s)" -msgstr "2 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2 按钮é£è¡Œæ‘‡æ†" -msgid "4-button gamepad" -msgstr "4 æŒ‰é’®æ¸¸æˆæ‰‹æŸ„" +msgid "3-button flight yoke" +msgstr "3 按钮é£è¡Œæ‘‡æ†" msgid "4-button flight yoke" msgstr "4 按钮é£è¡Œæ‘‡æ†" @@ -903,11 +882,71 @@ msgstr "4 按钮é£è¡Œæ‘‡æ†" msgid "2-button flight yoke with throttle" msgstr "2 按钮带油门é£è¡Œæ‘‡æ†" +msgid "3-button flight yoke with throttle" +msgstr "3 按钮带油门é£è¡Œæ‘‡æ†" + msgid "4-button flight yoke with throttle" msgstr "4 按钮带油门é£è¡Œæ‘‡æ†" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 æ–¹å‘盘 (3 è½´, 4 é”®)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "æ–¹å‘盘 (3 è½´, 2 é”®)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "æ–¹å‘盘 (3 è½´, 3 é”®)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "æ–¹å‘盘 (3 è½´, 4 é”®)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "带适é…器 Thrustmaster Formula T1/T2" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "ä¸å¸¦é€‚é…器 Thrustmaster Formula T1/T2" msgid "None" msgstr "æ— " @@ -978,11 +1017,8 @@ msgstr "æ­¤æ“作将硬é‡ç½®æ¨¡æ‹Ÿå™¨ă€‚" msgid "Save" msgstr "ä¿å­˜" -msgid "About 86Box" -msgstr "å…³äº 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "å…³äº %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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作者: Miran GrÄa (OBattler)ă€RichardG867ă€Jasmine Iwanekă€TC1995ă€coldbrewedă€Teemu Korhonen (Manaatti)ă€Joakim L. Giljeă€Adrien Moulin (elyosh)ă€Daniel Balsom (gloriouscow)ă€Cacodemon345ă€Fred N. van Kempen (waltje)ă€Tiseno100ă€reenigne ç­‰äººă€‚\n\n感谢 Sarah Walkeră€leileiă€JohnElliottă€greatpsycho å’Œå…¶ä»–äººç„æ ¸å¿ƒè´¡çŒ®ă€‚\n\næœ¬è½¯ä»¶ä¾æ® GNU é€ç”¨å…¬å…±è®¸å¯è¯ç¬¬äºŒç‰ˆæˆ–更新版本å‘å¸ƒă€‚è¯¦æƒ…è§ LICENSE æ–‡ä»¶ă€‚" @@ -1114,7 +1150,7 @@ msgid "VMs: %1" msgstr "è™æ‹Ÿæœº: %1" msgid "System Directory:" -msgstr "系统目录" +msgstr "系统目录:" msgid "Choose directory" msgstr "选择目录" @@ -1135,7 +1171,7 @@ msgid "Use regular expressions in search box" msgstr "在æœç´¢æ¡†ä¸­ä½¿ç”¨æ­£åˆ™è¡¨è¾¾å¼" msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?" -msgstr "%1 计算机当å‰å¤„äºæ´»å¨ç¶æ€ă€‚您确å®è¦é€€å‡ºè™æ‹Ÿæœºç®¡ç†å™¨å—?" +msgstr "%1 个计算机当å‰å¤„äºæ´»å¨ç¶æ€ă€‚您确å®è¦é€€å‡ºè™æ‹Ÿæœºç®¡ç†å™¨å—?" msgid "Add new system wizard" msgstr "æ·»å æ–°ç³»ç»Ÿå‘导" @@ -1204,7 +1240,7 @@ msgid "Please enter a system name" msgstr "请输入系统åç§°" msgid "Display name (optional):" -msgstr "显示åç§° (å¯é€‰)" +msgstr "显示åç§° (å¯é€‰):" msgid "Display name:" msgstr "显示åç§°:" @@ -1243,7 +1279,7 @@ msgid "Directory %1 already exists" msgstr "目录 %1 已存在" msgid "You cannot use the following characters in the name: %1" -msgstr " %1: å称中ä¸èƒ½ä½¿ç”¨ä»¥ä¸‹å­—符: %1" +msgstr "å称中ä¸èƒ½ä½¿ç”¨ä»¥ä¸‹å­—符: %1" msgid "Clone" msgstr "å…‹é†" @@ -1332,8 +1368,8 @@ msgstr "系统" msgid "Storage" msgstr "存储" -msgid "Disk %1: " -msgstr "ç£ç›˜ %1" +msgid "Disk %1:" +msgstr "ç£ç›˜ %1:" msgid "No disks" msgstr "æ— ç£ç›˜" @@ -1651,7 +1687,7 @@ msgid "Show non-&primary monitors" msgstr "显示éä¸»è¦æ˜¾ç¤ºå™¨(&P)" msgid "Open screenshots &folder..." -msgstr "打开å±å¹•截图文件夹...(&F)" +msgstr "打开å±å¹•截图文件夹(&F)..." msgid "Appl&y fullscreen stretch mode when maximized" msgstr "æœ€å¤§åŒ–æ—¶åº”ç”¨å…¨å±æ‹‰ä¼¸æ¨¡å¼(&Y)" @@ -1746,8 +1782,8 @@ msgstr "我已移å¨è¿™å°æœºå™¨" msgid "I Copied It" msgstr "我已å¤åˆ¶è¿™å°æœºå™¨" -msgid "86Box Monitor #" -msgstr "86Box 显示器 #" +msgid "86Box Monitor #%1" +msgstr "86Box 显示器 #%1" msgid "No MCA devices." msgstr "æ—  MCA è®¾å¤‡ă€‚" @@ -1782,8 +1818,11 @@ msgstr "适é…器:" msgid "VDE Socket:" msgstr "VDE 套æ¥å­—:" +msgid "TAP Bridge Device:" +msgstr "TAP æ¡¥æ¥è®¾å¤‡:" + msgid "86Box Unit Tester" -msgstr "86Box 装置测试仪" +msgstr "86Box å•元测试工具" msgid "Novell NetWare 2.x Key Card" msgstr "Novell NetWare 2.x 密钥å¡" @@ -1801,7 +1840,7 @@ msgid "Serial port passthrough 4" msgstr "串å£ç›´é€ 4" msgid "Renderer &options..." -msgstr "渲染器选项...(&O)" +msgstr "渲染器选项(&O)..." msgid "PC/XT Keyboard" msgstr "PC/XT 键盘" @@ -2095,7 +2134,7 @@ msgid "MAC Address" msgstr "MAC 地å€" msgid "MAC Address OUI" -msgstr "MAC 地å€ç„ OUI" +msgstr "MAC 地å€ç»„织唯一标识符" msgid "Enable BIOS" msgstr "å¯ç”¨ BIOS" @@ -2157,12 +2196,6 @@ msgstr "SID 滤镜强度" msgid "Surround module" msgstr "ç¯ç»•声模å—" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "在 CODEC è®¾ç½®æ—¶å¼•å‘ CODEC 中断(æŸäº›é©±å¨ç¨‹åºéœ€è¦ï¼‰ă€‚" - msgid "SB Address" msgstr "Sound Blaster 地å€" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "宿—¶æ—¶é’Ÿç„IRQ" + +msgid "RTC Port Address" +msgstr "宿—¶æ—¶é’Ÿç„端å£åœ°å€" + +msgid "Onboard RTC" +msgstr "æ¿è½½å®æ—¶æ—¶é’Ÿ" + +msgid "Not installed" +msgstr "未安装" + msgid "Enable OPL" msgstr "å¯ç”¨ OPL" @@ -2305,7 +2350,7 @@ msgid "Transfer Speed" msgstr "传输速度" msgid "EMS mode" -msgstr "EMS (扩展内存)模å¼" +msgstr "EMS(扩展内存)模å¼" msgid "EMS Address" msgstr "EMS 地å€" @@ -2446,10 +2491,7 @@ msgid "24 MB" msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" -msgstr "SigmaTel STAC9721T (立体声)" - -msgid "Classic" -msgstr "ç»å…¸" +msgstr "SigmaTel STAC9721T(立体声)" msgid "256 KB" msgstr "256 KB" @@ -2644,7 +2686,7 @@ msgid "Named Pipe (Server)" msgstr "命å管é“(æœå¡å™¨ï¼‰" msgid "Named Pipe (Client)" -msgstr "命åç®¡é“ (客户端) " +msgstr "命åç®¡é“ (客户端)" msgid "Host Serial Passthrough" msgstr "主机串å£ç›´é€" @@ -2739,9 +2781,6 @@ msgstr "GLSL 错误" msgid "Could not load shader: %1" msgstr "无法å è½½ç€è‰²å™¨ï¼%1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "OpenGL 版本需è¦è¾¾åˆ° 3.0 æˆ–æ›´é«˜ă€‚å½“å‰ GLSL 版本为 %1.%2" - msgid "Could not load texture: %1" msgstr "无法å è½½æè´¨ï¼%1" @@ -2770,7 +2809,7 @@ msgid "Could not load file %1" msgstr "无法å è½½æ–‡ä»¶ %1" msgid "Key Bindings:" -msgstr "按键绑å®" +msgstr "按键绑å®:" msgid "Action" msgstr "å¨ä½œ" @@ -2788,7 +2827,7 @@ msgid "Bind Key" msgstr "ç»‘å®æŒ‰é”®" msgid "Enter key combo:" -msgstr "输入按键组åˆ" +msgstr "输入按键组åˆ:" msgid "Bind conflict" msgstr "绑å®å†²çª" @@ -2805,6 +2844,9 @@ msgstr "å‘é€ Ctrl+Alt+Esc" msgid "Toggle fullscreen" msgstr "切æ¢å…¨å±" +msgid "Toggle UI in fullscreen" +msgstr "åœ¨å…¨å±æ¨¡å¼ä¸‹æ¿€æ´»èœå•æ " + msgid "Screenshot" msgstr "截图" @@ -2902,13 +2944,13 @@ msgid "build" msgstr "æ„建" msgid "You are currently running version %1." -msgstr "æ‚¨å½“å‰æ­£åœ¨è¿è¡Œç‰ˆæœ¬ %1 。" +msgstr "æ‚¨å½“å‰æ­£åœ¨è¿è¡Œç‰ˆæœ¬ %1。" msgid "Version %1 is now available." msgstr "版本 %1ç°å·²å¯ç”¨ă€‚" msgid "You are currently running build %1." -msgstr "æ‚¨å½“å‰æ­£åœ¨è¿è¡Œæ„建 %1 。" +msgstr "æ‚¨å½“å‰æ­£åœ¨è¿è¡Œæ„建 %1。" msgid "Build %1 is now available." msgstr "æ„建 %1ç°å·²å¯ç”¨ă€‚" @@ -2929,7 +2971,7 @@ msgid "86Box Update" msgstr "86Box æ›´æ–°" msgid "Release notes:" -msgstr "å‘行版说æ˜" +msgstr "å‘行版说æ˜:" msgid "%1 Hz" msgstr "%1 Hz" @@ -2962,7 +3004,7 @@ msgid "Sharpness" msgstr "é”度" msgid "&CGA composite settings..." -msgstr "CGA å¤åˆæ¨¡å¼è®¾ç½®...(&C)" +msgstr "CGA å¤åˆæ¨¡å¼è®¾ç½®(&C)..." msgid "CGA composite settings" msgstr "CGA å¤åˆæ¨¡å¼è®¾ç½®" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 1732cb91425..d17f369230c 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -67,7 +67,7 @@ msgid "&VNC" msgstr "VNC(&V)" msgid "Specify &dimensions..." -msgstr "指å®è¦–窗大å°...(&D)" +msgstr "指å®è¦–窗大å°(&D)..." msgid "Force &4:3 display ratio" msgstr "強制 4:3 顯示比例(&4)" @@ -121,10 +121,10 @@ msgid "&Fullscreen" msgstr "å…¨è¢å¹•(&F)" msgid "Fullscreen &stretch mode" -msgstr "å…¨è¢å¹•拉伸模å¼(&S)" +msgstr "å…¨è¢å¹•延展模å¼(&S)" msgid "&Full screen stretch" -msgstr "å…¨è¢å¹•拉伸(&F)" +msgstr "å…¨è¢å¹•延展(&F)" msgid "&4:3" msgstr "4:3(&4)" @@ -142,7 +142,7 @@ msgid "EGA/(S)&VGA settings" msgstr "EGA/(S)VGA 設å®(&V)" msgid "&Inverted VGA monitor" -msgstr "VGA 顯示器å色顯示(&I)" +msgstr "VGA 監視器å色顯示(&I)" msgid "VGA screen &type" msgstr "VGA è¢å¹•é¡å‹(&T)" @@ -154,22 +154,22 @@ msgid "RGB (no brown)" msgstr "RGB (無棕色)" msgid "&RGB Grayscale" -msgstr "RGB ç°åº¦(&R)" +msgstr "RGB ç°é(&R)" msgid "Generic RGBI color monitor" msgstr "é€ç”¨ RGBI 彩色監視器" msgid "&Amber monitor" -msgstr "ç¥ç€è‰²å–®è‰²é¡¯ç¤ºå™¨(&A)" +msgstr "ç¥ç€è‰²å–®è‰²ç›£è¦–器(&A)" msgid "&Green monitor" -msgstr "綠色單色顯示器(&G)" +msgstr "綠色單色監視器(&G)" msgid "&White monitor" -msgstr "白色單色顯示器(&W)" +msgstr "白色單色監視器(&W)" msgid "Grayscale &conversion type" -msgstr "ç°åº¦è½‰æ›é¡å‹(&C)" +msgstr "ç°é轉æ›é¡å‹(&C)" msgid "BT&601 (NTSC/PAL)" msgstr "BT601 (NTSC/PAL)(&6)" @@ -187,7 +187,7 @@ msgid "Change contrast for &monochrome display" msgstr "è®æ›´å–®è‰²é¡¯ç¤ºå°æ¯”度(&M)" msgid "&Media" -msgstr "介質(&M)" +msgstr "媒體(&M)" msgid "&Tools" msgstr "工具(&T)" @@ -232,13 +232,13 @@ msgid "&About 86Box..." msgstr "關於 86Box(&A)..." msgid "&New image..." -msgstr "æ–°å¢æ˜ åƒ(&N)..." +msgstr "æ–°å¢å½±åƒ(&N)..." msgid "&Existing image..." -msgstr "é–‹å•Ÿå·²å­˜åœ¨ç„æ˜ åƒ(&E)..." +msgstr "開啟已存在ç„å½±åƒ(&E)..." msgid "Existing image (&Write-protected)..." -msgstr "é–‹å•Ÿå·²å­˜åœ¨ç„æ˜ åƒä¸¦å¯«ä¿è­·(&W)..." +msgstr "以防寫ä¿è­·é–‹å•Ÿå·²å­˜åœ¨ç„å½±åƒ(&W)..." msgid "&Record" msgstr "錄製(&R)" @@ -256,7 +256,7 @@ msgid "E&ject" msgstr "退出(&J)" msgid "&Image..." -msgstr "映åƒ(&I)..." +msgstr "å½±åƒ(&I)..." msgid "E&xport to 86F..." msgstr "匯出為 86F æ ¼å¼(&x)..." @@ -268,41 +268,11 @@ msgid "E&mpty" msgstr "空置光碟機(&M)" msgid "Reload previous image" -msgstr "載入ä¸ä¸€å€‹æ˜ åƒ" +msgstr "載入ä¸ä¸€å€‹å½±åƒ" msgid "&Folder..." msgstr "資料夾(&F)..." -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 "å好設å®" @@ -310,7 +280,7 @@ msgid "Sound Gain" msgstr "音é‡å¢ç›" msgid "New Image" -msgstr "æ–°å¢æ˜ åƒ" +msgstr "æ–°å¢å½±åƒ" msgid "Settings" msgstr "設å®" @@ -376,7 +346,7 @@ msgid "Frequency:" msgstr "é »ç‡:" msgid "FPU:" -msgstr "æµ®é»è™•ç†å™¨ (FPU):" +msgstr "æµ®é»é‹ç®—器 (FPU):" msgid "Wait states:" msgstr "等待狀態 (WS):" @@ -421,10 +391,10 @@ msgid "Voodoo 1 or 2 Graphics" msgstr "Voodoo 1 或 2 圖形" msgid "IBM 8514/A Graphics" -msgstr "IBM 8514/A Graphics" +msgstr "IBM 8514/A 圖形" msgid "XGA Graphics" -msgstr "XGA Graphics" +msgstr "XGA 圖形" msgid "IBM PS/55 Display Adapter Graphics" msgstr "IBM PS/55 顯示介é¢å¡åœ–å½¢" @@ -487,7 +457,7 @@ msgid "Use FLOAT32 sound" msgstr "ä½¿ç”¨å–®ç²¾åº¦æµ®é» (FLOAT32) 音è¨" msgid "FM synth driver" -msgstr "FM synth driver" +msgstr "FM åˆæˆé©…動器" msgid "Nuked (more accurate)" msgstr "Nuked (更準確)" @@ -550,7 +520,7 @@ msgid "FD Controller:" msgstr "軟碟æ§åˆ¶å™¨:" msgid "CD-ROM Controller:" -msgstr "CD-ROM æ§åˆ¶å™¨" +msgstr "CD-ROM æ§åˆ¶å™¨:" msgid "Tertiary IDE Controller" msgstr "第三 IDE æ§åˆ¶å™¨" @@ -589,7 +559,7 @@ msgid "&New..." msgstr "æ–°å¢(&N)..." msgid "&Existing..." -msgstr "已有映åƒ(&E)..." +msgstr "已有影åƒ(&E)..." msgid "&Remove" msgstr "移除(&R)" @@ -603,9 +573,6 @@ msgstr "é€é“:" msgid "ID:" msgstr "ID:" -msgid "&Specify..." -msgstr "指å®(&S)..." - msgid "Sectors:" msgstr "ç£å€(S):" @@ -622,7 +589,7 @@ msgid "Type:" msgstr "é¡å‹:" msgid "Image Format:" -msgstr "æ˜ åƒæ ¼å¼:" +msgstr "å½±åƒæ ¼å¼:" msgid "Block Size:" msgstr "å€å¡å¤§å°:" @@ -646,10 +613,10 @@ msgid "MO:" msgstr "ç£å…‰ç¢Ÿ:" msgid "Removable disks:" -msgstr "å¯ç§»é™¤:" +msgstr "å¯ç§»é™¤ç£ç¢Ÿ:" msgid "Removable disk drives:" -msgstr "å¯ç§»é™¤ç£ç¢Ÿ:" +msgstr "å¯ç§»é™¤ç£ç¢Ÿæ©Ÿ:" msgid "ZIP 250" msgstr "ZIP 250" @@ -688,10 +655,7 @@ msgid "ISABugger device" msgstr "ISABugger è£ç½®" msgid "POST card" -msgstr "自檢 (POST) å¡" - -msgid "86Box" -msgstr "86Box" +msgstr "自我檢測 (POST) å¡" msgid "Error" msgstr "錯誤" @@ -718,7 +682,7 @@ msgid "Image %1" msgstr "å½±åƒ %1" 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\" è³‡æ–™å¤¾ă€‚" +msgstr "86Box 找ä¸åˆ°ä»»ä½•å¯ç”¨ç„ ROM å½±åƒă€‚\n\n請下載 ROM 套件並將其解壓到 \"roms\" è³‡æ–™å¤¾ă€‚" msgid "(empty)" msgstr "(空)" @@ -736,13 +700,13 @@ msgid "Off" msgstr "é—œ" msgid "All images" -msgstr "所有映åƒ" +msgstr "所有影åƒ" msgid "Basic sector images" -msgstr "基本ç£å€æ˜ åƒ" +msgstr "基本ç£å€å½±åƒ" msgid "Surface images" -msgstr "è¡¨é¢æ˜ åƒ" +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\" ä¸å¯ç”¨ă€‚將切æ›åˆ°å…¶ä»–å¯ç”¨æ©Ÿå‹ă€‚" @@ -751,10 +715,10 @@ msgid "Video card \"%hs\" is not available due to missing ROMs in the roms/video msgstr "由於 roms/video 資料夾中缺少åˆé©ç„ ROMï¼Œé¡¯ç¤ºå¡ \"%hs\" ä¸å¯ç”¨ă€‚將切æ›åˆ°å…¶ä»–å¯ç”¨é¡¯ç¤ºå¡ă€‚" msgid "Video card #2 \"%hs\" is not available due to missing ROMs in the roms/video directory. Disabling the second video card." -msgstr "由於 roms/video 資料夾中缺少åˆé©ç„ ROMï¼Œé¡¯ç¤ºå¡ 2 \"%hs\" ä¸å¯ç”¨ă€‚ç¦ç”¨ç¬¬äºŒå—显å¡ă€‚" +msgstr "由於 roms/video 資料夾中缺少åˆé©ç„ ROMï¼Œé¡¯ç¤ºå¡ 2 \"%hs\" ä¸å¯ç”¨ă€‚ç¦ç”¨ç¬¬äºŒå¼µé¡¯ç¤ºå¡ă€‚" msgid "Device \"%hs\" is not available due to missing ROMs. Ignoring the device." -msgstr "由於缺少åˆé©ç„ ROM,è£ç½® \"%hs\" ä¸å¯ç”¨ă€‚å¿½ç•¥è®¾å¤‡ă€‚" +msgstr "由於缺少åˆé©ç„ ROM,è£ç½® \"%hs\" ä¸å¯ç”¨ă€‚忽略è£ç½®ă€‚" msgid "Machine" msgstr "機å‹" @@ -852,9 +816,18 @@ msgstr "未找到 PCap è£ç½®" msgid "Invalid PCap device" msgstr "無效 PCap è£ç½®" +msgid "Generic paddle controller(s)" +msgstr "é€ç”¨æ—‹éˆ•æ§åˆ¶å™¨" + +msgid "2-axis, 1-button joystick(s)" +msgstr "2 軸, 1 鵿–æ¡¿" + msgid "2-axis, 2-button joystick(s)" msgstr "2 軸, 2 鵿–æ¡¿" +msgid "2-axis, 3-button joystick" +msgstr "2 軸, 3 鵿–æ¡¿" + msgid "2-axis, 4-button joystick" msgstr "2 軸, 4 鵿–æ¡¿" @@ -867,35 +840,41 @@ msgstr "2 軸, 8 鵿–æ¡¿" msgid "3-axis, 2-button joystick" msgstr "3 軸, 2 鵿–æ¡¿" +msgid "3-axis, 3-button joystick" +msgstr "3 軸, 3 鵿–æ¡¿" + msgid "3-axis, 4-button joystick" msgstr "3 軸, 4 鵿–æ¡¿" +msgid "4-axis, 2-button joystick" +msgstr "4 軸, 2 鵿–æ¡¿" + +msgid "4-axis, 3-button joystick" +msgstr "4 軸, 3 鵿–æ¡¿" + msgid "4-axis, 4-button joystick" msgstr "4 軸, 4 鵿–æ¡¿" -msgid "CH Flightstick Pro" -msgstr "CH Flightstick Pro" - -msgid "CH Flightstick Pro + CH Pedals" -msgstr "CH Flightstick Pro + CH Pedals" +msgid "2-button gamepad(s)" +msgstr "2 éµé戲手柄" -msgid "Microsoft SideWinder Pad" -msgstr "Microsoft SideWinder Pad" +msgid "3-button gamepad" +msgstr "3 éµé戲手柄" -msgid "Thrustmaster Flight Control System" -msgstr "Thrustmaster Flight Control System" +msgid "4-button gamepad" +msgstr "4 éµé戲手柄" -msgid "Thrustmaster FCS + Rudder Control System" -msgstr "Thrustmaster FCS + Rudder Control System" +msgid "6-button gamepad" +msgstr "6 éµé戲手柄" -msgid "2-button gamepad(s)" -msgstr "2 éµé戲手柄" +msgid "Gravis PC GamePad" +msgstr "Gravis PC GamePad" msgid "2-button flight yoke" msgstr "2 æŒ‰éˆ•é£›è¡Œæ–æ¡¿" -msgid "4-button gamepad" -msgstr "4 éµé戲手柄" +msgid "3-button flight yoke" +msgstr "3 æŒ‰éˆ•é£›è¡Œæ–æ¡¿" msgid "4-button flight yoke" msgstr "4 æŒ‰éˆ•é£›è¡Œæ–æ¡¿" @@ -903,11 +882,71 @@ msgstr "4 æŒ‰éˆ•é£›è¡Œæ–æ¡¿" msgid "2-button flight yoke with throttle" msgstr "2 æŒ‰éˆ•å¸¶æ²¹é–€é£›è¡Œæ–æ¡¿" +msgid "3-button flight yoke with throttle" +msgstr "3 æŒ‰éˆ•å¸¶æ²¹é–€é£›è¡Œæ–æ¡¿" + msgid "4-button flight yoke with throttle" msgstr "4 æŒ‰éˆ•å¸¶æ²¹é–€é£›è¡Œæ–æ¡¿" -msgid "Win95 Steering Wheel (3-axis, 4-button)" -msgstr "Win95 æ–¹å‘盤 (3 軸, 4 鵿–æ¡¿)" +msgid "Steering wheel (3-axis, 2-button)" +msgstr "æ–¹å‘盤 (3 軸, 2 鵿–æ¡¿)" + +msgid "Steering wheel (3-axis, 3-button)" +msgstr "æ–¹å‘盤 (3 軸, 3 鵿–æ¡¿)" + +msgid "Steering wheel (3-axis, 4-button)" +msgstr "æ–¹å‘盤 (3 軸, 4 鵿–æ¡¿)" + +msgid "CH Flightstick" +msgstr "CH Flightstick" + +msgid "CH Flightstick + CH Pedals" +msgstr "CH Flightstick + CH Pedals" + +msgid "CH Flightstick + CH Pedals Pro" +msgstr "CH Flightstick + CH Pedals Pro" + +msgid "CH Flightstick Pro" +msgstr "CH Flightstick Pro" + +msgid "CH Flightstick Pro + CH Pedals" +msgstr "CH Flightstick Pro + CH Pedals" + +msgid "CH Flightstick Pro + CH Pedals Pro" +msgstr "CH Flightstick Pro + CH Pedals Pro" + +msgid "CH Virtual Pilot" +msgstr "CH Virtual Pilot" + +msgid "CH Virtual Pilot + CH Pedals" +msgstr "CH Virtual Pilot + CH Pedals" + +msgid "CH Virtual Pilot + CH Pedals Pro" +msgstr "CH Virtual Pilot + CH Pedals Pro" + +msgid "CH Virtual Pilot Pro" +msgstr "CH Virtual Pilot Pro" + +msgid "CH Virtual Pilot Pro + CH Pedals" +msgstr "CH Virtual Pilot Pro + CH Pedals" + +msgid "CH Virtual Pilot Pro + CH Pedals Pro" +msgstr "CH Virtual Pilot Pro + CH Pedals Pro" + +msgid "Microsoft SideWinder Pad" +msgstr "Microsoft SideWinder Pad" + +msgid "Thrustmaster Flight Control System" +msgstr "Thrustmaster Flight Control System" + +msgid "Thrustmaster FCS + Rudder Control System" +msgstr "Thrustmaster FCS + Rudder Control System" + +msgid "Thrustmaster Formula T1/T2 with adapter" +msgstr "附轉æ¥å™¨ Thrustmaster Formula T1/T2" + +msgid "Thrustmaster Formula T1/T2 without adapter" +msgstr "ä¸é™„轉æ¥å™¨ Thrustmaster Formula T1/T2" msgid "None" msgstr "ç„¡" @@ -922,10 +961,10 @@ msgid "&Floppy %1 (%2): %3" msgstr "軟碟 %1 (%2): %3(&F)" msgid "Advanced sector images" -msgstr "進éç£å€æ˜ åƒ" +msgstr "進éç£å€å½±åƒ" msgid "Flux images" -msgstr "Flux 映åƒ" +msgstr "Flux å½±åƒ" msgid "Are you sure you want to hard reset the emulated machine?" msgstr "確å®è¦ç¡¬é‡è¨­æ¨¡æ“¬å™¨å—?" @@ -946,7 +985,7 @@ msgid "&MO %1 (%2): %3" msgstr "ç£å…‰ç¢Ÿ %1 (%2): %3(&M)" msgid "MO images" -msgstr "ç£å…‰ç¢Ÿæ˜ åƒ" +msgstr "ç£å…‰ç¢Ÿå½±åƒ" msgid "Welcome to 86Box!" msgstr "æ­¡è¿ä½¿ç”¨ 86Boxï¼" @@ -978,14 +1017,11 @@ msgstr "æ­¤æ“作將硬é‡è¨­æ¨¡æ“¬å™¨ă€‚" msgid "Save" msgstr "儲存" -msgid "About 86Box" -msgstr "關於 86Box" - -msgid "86Box v" -msgstr "86Box v" +msgid "About %1" +msgstr "關於 %1" msgid "An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, 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作者: Miran GrÄa (OBattler)ă€RichardG867ă€Jasmine Iwanekă€TC1995ă€coldbrewedă€Teemu Korhonen (Manaatti)ă€Joakim L. Giljeă€Adrien Moulin (elyosh)ă€Daniel Balsom (gloriouscow)ă€Cacodemon345ă€Fred N. van Kempen (waltje)ă€Tiseno100ă€reenigne ç­‰äººă€‚\n\n之å‰ç„核心貢ç»ä¾†è‡ª Sarah Walkeră€leileiă€JohnElliottă€greatpsycho ç­‰äººă€‚\n\næœ¬è»Ÿé«”ä¾æ“ GNU é€ç”¨å…¬å…±æˆæ¬ç¬¬äºŒç‰ˆæˆ–æ›´æ–°ç‰ˆæœ¬ç™¼å¸ƒă€‚è©³æƒ…è¦‹ LICENSE æª”æ¡ˆă€‚" +msgstr "一個èˆå¼é›»è…¦æ¨¡æ“¬å™¨\n\n作者: Miran GrÄa (OBattler)ă€RichardG867ă€Jasmine Iwanekă€TC1995ă€coldbrewedă€Teemu Korhonen (Manaatti)ă€Joakim L. Giljeă€Adrien Moulin (elyosh)ă€Daniel Balsom (gloriouscow)ă€Cacodemon345ă€Fred N. van Kempen (waltje)ă€Tiseno100ă€reenigne ç­‰äººă€‚\n\n之å‰ç„核心貢ç»ä¾†è‡ª Sarah Walkeră€leileiă€JohnElliottă€greatpsycho ç­‰äººă€‚\n\næœ¬è»Ÿé«”ä¾æ“ GNU é€ç”¨å…¬å…±æˆæ¬ç¬¬äºŒç‰ˆæˆ–æ›´æ–°ç‰ˆæœ¬ç™¼ä½ˆă€‚è©³æƒ…è¦‹ LICENSE æª”æ¡ˆă€‚" msgid "Hardware not available" msgstr "硬體ä¸å¯ç”¨" @@ -997,10 +1033,10 @@ msgid "Invalid configuration" msgstr "無效設å®" msgid "%1 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 "%1 是將 PostScript 檔案轉æ›ç‚º PDF 所需è¦ç„åº«ă€‚\n\n使用é€ç”¨ PostScript å°è¡¨æ©Ÿåˆ—å°ç„文件將被儲存為 PostScript (.ps) æª”æ¡ˆă€‚" +msgstr "自動將 PostScript 檔案轉æ›ç‚º PDF éœ€è¦ %1。\n\n使用é€ç”¨ PostScript å°è¡¨æ©Ÿåˆ—å°ç„文件將被儲存為 PostScript (.ps) æª”æ¡ˆă€‚" msgid "%1 is required for automatic conversion of PCL files to PDF.\n\nAny documents sent to the generic PCL printer will be saved as Printer Command Language (.pcl) files." -msgstr "%1 是將 PCL 檔案轉æ›ç‚º PDF 所需è¦ç„åº«ă€‚\n\n使用é€ç”¨ PCL å°è¡¨æ©Ÿåˆ—å°ç„文件將被儲存為 Printer Command Language (.pcl) æª”æ¡ˆă€‚" +msgstr "自動將 PCL 檔案轉æ›ç‚º PDF éœ€è¦ %1。\n\n使用é€ç”¨ PCL å°è¡¨æ©Ÿåˆ—å°ç„文件將被儲存為 Printer Command Language (.pcl) æª”æ¡ˆă€‚" msgid "Don't show this message again" msgstr "ä¸è¦å†é¡¯ç¤ºæ­¤æ¶ˆæ¯" @@ -1015,13 +1051,13 @@ msgid "Don't reset" msgstr "ä¸é‡è¨­" msgid "CD-ROM images" -msgstr "光碟映åƒ" +msgstr "光碟影åƒ" msgid "%1 Device Configuration" msgstr "%1 è£ç½®è¨­å®" msgid "Monitor in sleep mode" -msgstr "顯示器處在ç¡çœ ç‹€æ…‹" +msgstr "監視器處在ç¡çœ ç‹€æ…‹" msgid "GLSL shaders" msgstr "GLSL 著色器" @@ -1030,7 +1066,7 @@ 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啟用此設å®ä¸å—官方支æ´ï¼Œä¸¦ä¸”æäº¤ç„任何錯誤報å‘å¯èƒ½æœƒè¦–ç‚ºç„¡æ•ˆè€Œé—œé–‰ă€‚" +msgstr "此模擬電腦åœç”¨äº†åŸºæ–¼é¸å®é›»è…¦ç„ CPU é¡å‹éæ¿¾ă€‚\n\n能夠é¸ä¸­èˆ‡æ‰€é¸æ©Ÿå™¨æœ¬ä¸ç›¸å®¹ç„ CPU,但是å¯èƒ½æœƒé‡åˆ°èˆ‡æ©Ÿå™¨ BIOS 或其他軟體ä¸ç›¸å®¹ç„å•é¡Œă€‚\n\n啟用此設å®ä¸å—官方支æ´ï¼Œä¸¦ä¸”æäº¤ç„任何錯誤報å‘å¯èƒ½æœƒè¦–ç‚ºç„¡æ•ˆè€Œçµæ¡ˆă€‚" msgid "Continue" msgstr "繼續" @@ -1042,7 +1078,7 @@ msgid "C&assette: %1" msgstr "ç£å¸¶: %1(&A)" msgid "Cassette images" -msgstr "ç£å¸¶æ˜ åƒ" +msgstr "ç£å¸¶å½±åƒ" msgid "Cartridge %1: %2" msgstr "å¡å¸¶ %1: %2" @@ -1051,7 +1087,7 @@ msgid "Car&tridge %1: %2" msgstr "å¡å¸¶ %1: %2(&A)" msgid "Cartridge images" -msgstr "å¡å¸¶æ˜ åƒ" +msgstr "å¡å¸¶å½±åƒ" msgid "Resume execution" msgstr "æ¢å¾©åŸ·è¡Œ" @@ -1087,25 +1123,25 @@ msgid "Not running" msgstr "未執行" msgid "Running" -msgstr "é‹è¡Œ" +msgstr "執行中" msgid "Paused" msgstr "å·²æ«åœ" msgid "Waiting" -msgstr "等待" +msgstr "等待中" msgid "Powered Off" msgstr "é›»æºé—œé–‰" msgid "%n running" -msgstr "%n é‹è¡Œ" +msgstr "%n 執行中" msgid "%n paused" msgstr "%n å·²æ«åœ" msgid "%n waiting" -msgstr "%n 等待" +msgstr "%n 等待中" msgid "%1 total" msgstr "%1 總計" @@ -1132,7 +1168,7 @@ msgid "Unable to open the selected configuration file for reading: %1" msgstr "無法開啟é¸å–ç„è¨­å®æª”進行讀å–: %1" msgid "Use regular expressions in search box" -msgstr "在æœå°‹æ–¹å¡ä¸­ä½¿ç”¨æ­£å‰‡è¡¨é”å¼" +msgstr "在æœå°‹æ–¹å¡ä¸­ä½¿ç”¨æ­£è¦è¡¨ç¤ºå¼" msgid "%1 machine(s) are currently active. Are you sure you want to exit the VM manager anyway?" msgstr "%1 å°æ©Ÿå™¨ç›®å‰è™•æ–¼æ´»å‹•ç‹€æ…‹ă€‚æ‚¨ç¢ºå®è¦é€€å‡ºè™›æ“¬æ©Ÿå™¨ç®¡ç†å“¡å—?" @@ -1213,7 +1249,7 @@ msgid "Set display name" msgstr "設å®é¡¯ç¤ºå稱" msgid "Enter the new display name (blank to reset)" -msgstr "輸入新ç„顯示å稱 (空白表示é‡è¨­)" +msgstr "輸入新ç„顯示å稱 (留空以é‡è¨­)" msgid "Change &display name..." msgstr "è®æ›´é¡¯ç¤ºå稱(&D)..." @@ -1234,7 +1270,7 @@ msgid "Select an icon" msgstr "鏿“‡åœ–示" msgid "C&lone..." -msgstr "å…‹é†(&L)..." +msgstr "複製(&L)..." msgid "Virtual machine \"%1\" (%2) will be cloned into:" msgstr "虛擬機器 \"%1\" (%2) 將被複製到:" @@ -1246,7 +1282,7 @@ msgid "You cannot use the following characters in the name: %1" msgstr "您ä¸èƒ½åœ¨å稱中使用下列字元ï¼%1" msgid "Clone" -msgstr "å…‹é†" +msgstr "複製" msgid "Failed to create directory for cloned VM" msgstr "為複製ç„虛擬機器建立目錄失敗" @@ -1273,7 +1309,7 @@ msgid "Unable to open the configuration file at %1 for writing" msgstr "無法開啟 %1 ç„è¨­å®æª”進行寫入" msgid "Error adding system" -msgstr "錯誤新å¢ç³»çµ±" +msgstr "æ–°å¢ç³»çµ±éŒ¯èª¤" msgid "Remove directory failed" msgstr "移除目錄失敗" @@ -1315,7 +1351,7 @@ msgid "Show &config file" msgstr "é¡¯ç¤ºè¨­å®æª”(&C)" msgid "No screenshot" -msgstr "沒有截圖" +msgstr "沒有擷圖" msgid "Search" msgstr "æœå°‹" @@ -1332,8 +1368,8 @@ msgstr "系統" msgid "Storage" msgstr "儲存" -msgid "Disk %1: " -msgstr "ç£ç¢Ÿ %1: " +msgid "Disk %1:" +msgstr "ç£ç¢Ÿ %1:" msgid "No disks" msgstr "ç„¡ç£ç¢Ÿ" @@ -1354,7 +1390,7 @@ msgid "Hard disk (%1)" msgstr "硬碟 (%1)" msgid "MFM/RLL or ESDI CD-ROM drives never existed" -msgstr "ä¸å­˜åœ¨ MFM/RLL 或 ESDI CD-ROM 光碟機" +msgstr "MFM/RLL 或 ESDI CD-ROM å…‰ç¢Ÿæ©Ÿå¾æœªå­˜åœ¨" msgid "Custom..." msgstr "自訂..." @@ -1369,13 +1405,13 @@ msgid "Add Existing Hard Disk" msgstr "å¢å å·²å­˜åœ¨ç„硬碟" msgid "HDI disk images cannot be larger than 4 GB." -msgstr "HDI ç£ç¢Ÿæ˜ åƒä¸èƒ½è¶…é 4 GB。" +msgstr "HDI ç£ç¢Ÿå½±åƒä¸èƒ½è¶…é 4 GB。" msgid "Disk images cannot be larger than 127 GB." -msgstr "ç£ç¢Ÿæ˜ åƒä¸èƒ½è¶…é 127 GB。" +msgstr "ç£ç¢Ÿå½±åƒä¸èƒ½è¶…é 127 GB。" msgid "Hard disk images" -msgstr "硬碟映åƒ" +msgstr "硬碟影åƒ" msgid "Unable to read file" msgstr "ç„¡æ³•è®€å–æª”案" @@ -1384,16 +1420,16 @@ 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 映åƒă€‚" +msgstr "䏿”¯æ´é 512 ä½å…ƒçµ„ç£å€å¤§å°ç„ HDI 或 HDX å½±åƒă€‚" msgid "Disk image file already exists" -msgstr "ç£ç¢Ÿæ˜ åƒæª”案已存在" +msgstr "ç£ç¢Ÿå½±åƒæª”案已存在" msgid "Please specify a valid file name." msgstr "è«‹æŒ‡å®æœ‰æ•ˆç„檔案å。" msgid "Disk image created" -msgstr "已創建ç£ç¢Ÿæ˜ åƒ" +msgstr "已創建ç£ç¢Ÿå½±åƒ" msgid "Make sure the file exists and is readable." msgstr "è«‹ç¢ºå®æ­¤æª”案已存在並å¯è®€å–。" @@ -1402,16 +1438,16 @@ msgid "Make sure the file is being saved to a writable directory." msgstr "è«‹ç¢ºå®æ­¤æª”案儲存在å¯å¯«ç›®éŒ„中。" msgid "Disk image too large" -msgstr "ç£ç¢Ÿæ˜ åƒå¤ªå¤§" +msgstr "ç£ç¢Ÿå½±åƒå¤ªå¤§" msgid "Remember to partition and format the newly-created drive." -msgstr "è«‹è¨˜å¾—ç‚ºæ–°å‰µå»ºç„æ˜ åƒåˆ†å€ä¸¦æ ¼å¼åŒ–。" +msgstr "請記得為新創建ç„å½±åƒåˆ†å€ä¸¦æ ¼å¼åŒ–。" msgid "The selected file will be overwritten. Are you sure you want to use it?" msgstr "é¸å®ç„æª”æ¡ˆå°‡è¢«è¦†è“‹ă€‚ç¢ºå®ç¹¼çºŒä½¿ç”¨æ­¤æª”案å—?" msgid "Unsupported disk image" -msgstr "䏿”¯æ´ç„ç£ç¢Ÿæ˜ åƒ" +msgstr "䏿”¯æ´ç„ç£ç¢Ÿå½±åƒ" msgid "Overwrite" msgstr "覆蓋" @@ -1420,13 +1456,13 @@ msgid "Don't overwrite" msgstr "ä¸è¦†è“‹" msgid "Raw image" -msgstr "åŸå§‹æ˜ åƒ" +msgstr "åŸå§‹å½±åƒ" msgid "HDI image" -msgstr "HDI 映åƒ" +msgstr "HDI å½±åƒ" msgid "HDX image" -msgstr "HDX 映åƒ" +msgstr "HDX å½±åƒ" msgid "Fixed-size VHD" msgstr "固å®å¤§å° VHD" @@ -1441,13 +1477,13 @@ msgid "(N/A)" msgstr "(ä¸é©ç”¨)" msgid "Raw image (.img)" -msgstr "åŸå§‹æ˜ åƒ (.img)" +msgstr "åŸå§‹å½±åƒ (.img)" msgid "HDI image (.hdi)" -msgstr "HDI æ˜ åƒ (.hdi)" +msgstr "HDI å½±åƒ (.hdi)" msgid "HDX image (.hdx)" -msgstr "HDX æ˜ åƒ (.hdx)" +msgstr "HDX å½±åƒ (.hdx)" msgid "Fixed-size VHD (.vhd)" msgstr "固å®å¤§å° VHD (.vhd)" @@ -1471,7 +1507,7 @@ 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是å¦éœ€è¦ä¿®å¾©æ™‚間戳?" +msgstr "父影åƒå¯èƒ½åœ¨å‰µå»ºå·®ç•°å½±åƒå¾Œè¢«ä¿®æ”¹ă€‚\n\n如æœå½±åƒæª”案被移動或複製,或創建此ç£ç¢Ÿç„程å¼ä¸­å­˜åœ¨éŒ¯èª¤ï¼Œä¹Ÿå¯èƒ½ç™¼ç”Ÿé€™ç¨®æƒ…æ³ă€‚\n\n是å¦éœ€è¦ä¿®å¾©æ™‚間戳?" msgid "Parent and child disk timestamps do not match" msgstr "父碟與å­ç¢Ÿç„時間戳ä¸åŒ¹é…" @@ -1528,10 +1564,10 @@ msgid "1.44 MB" msgstr "1.44 MB" msgid "DMF (cluster 1024)" -msgstr "DMF (1024 ç°‡)" +msgstr "DMF (1024 ä½å…ƒçµ„å¢é›†)" msgid "DMF (cluster 2048)" -msgstr "DMF (2048 ç°‡)" +msgstr "DMF (2048 ä½å…ƒçµ„å¢é›†)" msgid "2.88 MB" msgstr "2.88 MB" @@ -1594,7 +1630,7 @@ msgid "Mouse sensitivity:" msgstr "æ»‘é¼ éˆæ•度:" msgid "Select media images from program working directory" -msgstr "å¾ç¨‹å¼å·¥ä½œç›®éŒ„䏭鏿“‡ä»‹è³ªæ˜ åƒ" +msgstr "å¾ç¨‹å¼å·¥ä½œç›®éŒ„䏭鏿“‡åª’體影åƒ" msgid "PIT mode:" msgstr "PIT 模å¼:" @@ -1612,10 +1648,10 @@ msgid "&Auto-pause on focus loss" msgstr "失å»ç„¦é»æ™‚自動æ«åœ(&A)" msgid "WinBox is no longer supported" -msgstr "WinBox is no longer supported" +msgstr "ä¸å†æ”¯æ´ WinBox" msgid "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." -msgstr "Development of the WinBox manager stopped in 2022 due to a lack of maintainers. As we direct our efforts towards making 86Box even better, we have made the decision to no longer support WinBox as a manager.\n\nNo further updates will be provided through WinBox, and you may encounter incorrect behavior should you continue using it with newer versions of 86Box. Any bug reports related to WinBox behavior will be closed as invalid.\n\nGo to 86box.net for a list of other managers you can use." +msgstr "WinBox æ–¼ 2022 年因缺ä¹ç¶­è­·è€…è€Œåœæ­¢ç™¼å±•ă€‚ç”±æ–¼æˆ‘å€‘å‚¾æ³¨å…¨å›æ–¼å°‡ 86Box åç„æ›´å¥½ï¼Œæˆ‘們決å®ä¸å†æ”¯æ´å°‡ WinBox å為管ç†å“¡ă€‚\n\n在 WinBox 未æä¾›æ›´æ–°å‰ï¼Œæ­é…æ–°ç‰ˆæœ¬ç„ 86Box 使用將å°è‡´ä¸æ­£ç¢ºç„è¡Œç‚ºă€‚ä»»ä½•ç”± WinBox 引起ç„錯誤å›å ±å°‡ä»¥ç„¡æ•ˆçµæ¡ˆă€‚\n\n請造訪 86box.net 網站以å–å¾—å…¶ä»–å¯ç”¨ç„管ç†å“¡åˆ—è¡¨ă€‚" msgid "Generate" msgstr "產生" @@ -1648,16 +1684,16 @@ msgid "&MCA devices..." msgstr "&MCA è£ç½®..." msgid "Show non-&primary monitors" -msgstr "顯示é主è¦é¡¯ç¤ºå™¨(&P)" +msgstr "顯示é主è¦ç›£è¦–器(&P)" msgid "Open screenshots &folder..." -msgstr "開啟è¢å¹•截圖資料夾...(&F)" +msgstr "開啟è¢å¹•擷圖資料夾(&F)..." msgid "Appl&y fullscreen stretch mode when maximized" -msgstr "最大化時套用全è¢å¹•拉伸模å¼(&Y)" +msgstr "最大化時套用全è¢å¹•延展模å¼(&Y)" msgid "&Cursor/Puck" -msgstr "游標/çƒæ£’(&C)" +msgstr "æ•¸ä½æ¿æ¨™å®å™¨(&C)" msgid "&Pen" msgstr "ç­†(&P)" @@ -1666,10 +1702,10 @@ msgid "&Host CD/DVD Drive (%1:)" msgstr "主機 CD/DVD 光碟機 (%1:) (&H)" msgid "&Connected" -msgstr "已連ç·" +msgstr "已連ç·(&C)" msgid "Clear image &history" -msgstr "æ¸…é™¤æ˜ åƒæ­·å²è¨˜éŒ„(&H)" +msgstr "æ¸…é™¤å½±åƒæ­·å²è¨˜éŒ„(&H)" msgid "Create..." msgstr "建立..." @@ -1684,7 +1720,7 @@ msgid "Null Driver" msgstr "空驅動程å¼" msgid "NIC:" -msgstr "NIC:" +msgstr "網路å¡ï¼" msgid "NIC %1 (%2) %3" msgstr "ç¶²è·¯å¡ %1 (%2) %3" @@ -1699,10 +1735,10 @@ msgid "Use target framerate:" msgstr "使用目標影格速ç‡ï¼" msgid " fps" -msgstr "fps" +msgstr " fps" msgid "VSync" -msgstr "VSync" +msgstr "å‚ç›´åŒæ­¥" msgid "Synchronize with video" msgstr "與視è¨åŒæ­¥" @@ -1717,10 +1753,10 @@ msgid "Browse..." msgstr "ç€è¦½..." msgid "Couldn't create OpenGL context." -msgstr "無法建立 OpenGL ä¸ä¸‹æ–‡ă€‚" +msgstr "無法建立 OpenGL å…§å®¹ă€‚" msgid "Couldn't switch to OpenGL context." -msgstr "無法切æ›è‡³ OpenGL ä¸ä¸‹æ–‡ă€‚" +msgstr "無法切æ›è‡³ OpenGL å…§å®¹ă€‚" msgid "OpenGL version 3.0 or greater is required. Current version is %1.%2" msgstr "éœ€è¦ OpenGL 版本 3.0 æˆ–æ›´é«˜ă€‚ç›®å‰ç‰ˆæœ¬ç‚º %1.%2" @@ -1732,7 +1768,7 @@ msgid "\nFalling back to software rendering." msgstr "\nå›é€€åˆ°è»Ÿé«”æ¸²æŸ“ă€‚" msgid "

When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.

" -msgstr "

ç•¶é¸æ“‡åª’é«”æ˜ åƒ (CD-ROMă€è»Ÿç¢Ÿç­‰) 時,開啟å°è©±æ–¹å¡æœƒåœ¨èˆ‡ 86Box è¨­å®æª”相åŒç„ç›®éŒ„ä¸­é–‹å§‹ă€‚æ­¤è¨­å®å¯èƒ½åªæœƒåœ¨ macOS 䏿œ‰æ‰€å½±éŸ¿ă€‚

" +msgstr "

ç•¶é¸æ“‡åª’é«”å½±åƒ (CD-ROMă€è»Ÿç¢Ÿç­‰) 時,開啟å°è©±æ–¹å¡æœƒåœ¨èˆ‡ 86Box è¨­å®æª”相åŒç„ç›®éŒ„ä¸­é–‹å§‹ă€‚æ­¤è¨­å®å¯èƒ½åªæœƒåœ¨ macOS 䏿œ‰æ‰€å½±éŸ¿ă€‚

" msgid "This machine might have been moved or copied." msgstr "這尿©Ÿå™¨å¯èƒ½å·²è¢«ç§»å‹•æˆ–è¤‡è£½ă€‚" @@ -1746,8 +1782,8 @@ msgstr "æˆ‘å·²ç§»å‹•é€™å°æ©Ÿå™¨" msgid "I Copied It" msgstr "æˆ‘å·²è¤‡è£½é€™å°æ©Ÿå™¨" -msgid "86Box Monitor #" -msgstr "86Box Monitor " +msgid "86Box Monitor #%1" +msgstr "86Box 監視器 #%1" msgid "No MCA devices." msgstr "沒有 MCA è£ç½®ă€‚" @@ -1782,6 +1818,9 @@ msgstr "é…æ¥å™¨:" msgid "VDE Socket:" msgstr "VDE æ’座:" +msgid "TAP Bridge Device:" +msgstr "TAP æ©‹æ¥è£ç½®:" + msgid "86Box Unit Tester" msgstr "86Box 單元測試器" @@ -1801,7 +1840,7 @@ msgid "Serial port passthrough 4" msgstr "åºåˆ—埠ç„ç›´é€ 4" msgid "Renderer &options..." -msgstr "渲染器é¸é …...(&O)" +msgstr "渲染器é¸é …(&O)..." msgid "PC/XT Keyboard" msgstr "PC/XT éµç›¤" @@ -1852,22 +1891,22 @@ msgid "3M MicroTouch (Serial)" msgstr "3M MicroTouch (åºåˆ—埠)" msgid "Default Baud rate" -msgstr "é è¨­æ³¢ç‰¹ç‡" +msgstr "é è¨­é®‘ç‡" msgid "[COM] Standard Hayes-compliant Modem" msgstr "[COM] 標準 Hayes ç›¸å®¹ç„æ•¸æ“機" msgid "Roland MT-32 Emulation" -msgstr "羅蘭 MT-32 模擬" +msgstr "Roland MT-32 模擬" msgid "Roland MT-32 (New) Emulation" -msgstr "羅蘭 MT-32(新)模擬" +msgstr "Roland MT-32(新)模擬" msgid "Roland CM-32L Emulation" -msgstr "羅蘭 CM-32L 模擬" +msgstr "Roland CM-32L 模擬" msgid "Roland CM-32LN Emulation" -msgstr "羅蘭 CM-32LN 模擬" +msgstr "Roland CM-32LN 模擬" msgid "OPL4-ML Daughterboard" msgstr "OPL4-ML å­æ¿" @@ -1924,7 +1963,7 @@ msgid "Enable BIOS extension ROM Writes (ROM #4)" msgstr "啟用 BIOS æ“´å…… ROM 寫入 (ROM 4)" msgid "Linear framebuffer base" -msgstr "ç·æ€§åœ–框緩è¡è¨˜æ†¶é«”ç„底座" +msgstr "ç·æ€§åœ–框緩è¡è¨˜æ†¶é«”ç„èµ·å§‹ä½å€" msgid "Address" msgstr "ä½å€" @@ -1939,7 +1978,7 @@ msgid "Parallel port IRQ" msgstr "ä¸¦åˆ—åŸ ç„ IRQ" msgid "BIOS Revision" -msgstr "BIOS 版本" +msgstr "BIOS 修訂版號" msgid "BIOS Version" msgstr "BIOS 版本" @@ -1948,7 +1987,7 @@ msgid "BIOS Language" msgstr "BIOS èªè¨€" msgid "IBM 5161 Expansion Unit" -msgstr "IBM 5161 æ“´å……è£ç½®" +msgstr "IBM 5161 擴充單元" msgid "IBM Cassette Basic" msgstr "IBM ç£å¸¶å¼ BASIC" @@ -2050,13 +2089,13 @@ msgid "Reverb Width" msgstr "混響寬度" msgid "Reverb Level" -msgstr "混響電平" +msgstr "æ··éŸ¿ä½æº–" msgid "Interpolation Method" msgstr "æ’值方法" msgid "Dynamic Sample Loading" -msgstr "樣å“ç„動態載入" +msgstr "å‹•æ…‹å–æ¨£è¼‰å…¥" msgid "Reverb Output Gain" msgstr "迴響輸出å¢ç›" @@ -2065,7 +2104,7 @@ msgid "Reversed stereo" msgstr "åå‘ç«‹é«”è²" msgid "Nice ramp" -msgstr "æ¼‚äº®ç„æ–œå¡" +msgstr "å¹³æ»‘æ¼¸è®æ›²ç·" msgid "Hz" msgstr "赫茲" @@ -2080,7 +2119,7 @@ msgid "RTS toggle" msgstr "RTS 切æ›" msgid "Revision" -msgstr "修訂" +msgstr "修訂版號" msgid "Controller" msgstr "æ§åˆ¶å™¨" @@ -2157,12 +2196,6 @@ msgstr "SID éæ¿¾å¼·åº¦" msgid "Surround module" msgstr "ç’°ç¹è²æ¨¡çµ„" -msgid "CODEC" -msgstr "CODEC" - -msgid "Raise CODEC interrupt on CODEC setup (needed by some drivers)" -msgstr "在 CODEC è¨­å®æ™‚啟動 CODEC 中斷 (æŸäº›é©…動程å¼éœ€è¦)" - msgid "SB Address" msgstr "SB ä½å€" @@ -2178,6 +2211,18 @@ msgstr "WSS IRQ" msgid "WSS DMA" msgstr "WSS DMA" +msgid "RTC IRQ" +msgstr "å¯¦æ™‚æ™‚é˜ IRQ" + +msgid "RTC Port Address" +msgstr "實時時é˜åŸ ä½å€" + +msgid "Onboard RTC" +msgstr "內建實時時é˜" + +msgid "Not installed" +msgstr "未安è£" + msgid "Enable OPL" msgstr "啟用 OPL" @@ -2236,7 +2281,7 @@ msgid "Snow emulation" msgstr "é›ªè±æ¨¡æ“¬" msgid "Monitor type" -msgstr "顯示器é¡å‹" +msgstr "監視器é¡å‹" msgid "Character set" msgstr "字元集" @@ -2377,7 +2422,7 @@ msgid "Non-timed (original)" msgstr "é宿™‚ (åŸå§‹)" msgid "45 Hz (JMP2 not populated)" -msgstr "45 Hz (JMP2 未填充)" +msgstr "45 Hz (JMP2 未安æ’)" msgid "Two" msgstr "二éµ" @@ -2448,9 +2493,6 @@ msgstr "24 MB" msgid "SigmaTel STAC9721T (stereo)" msgstr "SigmaTel STAC9721T (ç«‹é«”è²)" -msgid "Classic" -msgstr "ç¶“å…¸" - msgid "256 KB" msgstr "256 KB" @@ -2485,7 +2527,7 @@ msgid "Color (IBM 5153)" msgstr "彩色(IBM 5153)" msgid "Simple doubling" -msgstr "ç°¡å–®å å€" +msgstr "ç°¡å–®å€å¢" msgid "sRGB interpolation" msgstr "sRGB æ’值" @@ -2545,7 +2587,7 @@ msgid "U.S. English" msgstr "ç¾åœ‹è‹±èª" msgid "Scandinavian" -msgstr "斯堪ç„ç´ç¶­äºèª" +msgstr "斯堪地那維äºèª" msgid "Other languages" msgstr "å…¶ä»–èªè¨€" @@ -2554,16 +2596,16 @@ msgid "Bochs latest" msgstr "Bochs 最新" msgid "Apply overscan deltas" -msgstr "å¥—ç”¨éæƒæä¸‰è§’å€" +msgstr "å¥—ç”¨éæƒæå·®å€¼" msgid "Mono Interlaced" -msgstr "單色é”行扫æ" +msgstr "單色é”è¡Œæƒæ" msgid "Mono Non-Interlaced" msgstr "單色éé”è¡Œæƒæ" msgid "Color Interlaced" -msgstr "彩色é”行扫æ" +msgstr "彩色é”è¡Œæƒæ" msgid "Color Non-Interlaced" msgstr "彩色éé”è¡Œæƒæ" @@ -2617,7 +2659,7 @@ msgid "Parallel Line Internet Protocol" msgstr "Parallel Line Internet Protocol" msgid "Protection Dongle for Savage Quest" -msgstr "用於 Savage Quest ç„ä¿è­·å å¯†ç‹—" +msgstr "用於 Savage Quest ç„防拷ä¿è­·é–" msgid "Serial Passthrough Device" msgstr "åºåˆ—埠直é€è£ç½®" @@ -2656,7 +2698,7 @@ msgid "&Unmute" msgstr "解除éœéŸ³(&U)" msgid "Softfloat FPU" -msgstr "Softfloat FPU" +msgstr "Softfloat æµ®é»é‹ç®—器模擬" msgid "High performance impact" msgstr "å°æ•ˆèƒ½å½±éŸ¿å¤§" @@ -2686,7 +2728,7 @@ msgid "[Generic] 2000 (7200 RPM)" msgstr "[é€ç”¨] 2000 (7200 轉速)" msgid "IBM 8514/A clone (ISA)" -msgstr "IBM 8514/A å…‹é† (ISA)" +msgstr "IBM 8514/A ç›¸å®¹å“ (ISA)" msgid "Vendor" msgstr "製造商" @@ -2739,9 +2781,6 @@ msgstr "GLSL 錯誤" msgid "Could not load shader: %1" msgstr "無法載入著色器: %1" -msgid "OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2" -msgstr "éœ€è¦ OpenGL 版本 3.0 æˆ–æ›´é«˜ă€‚ç›®å‰ç„ GLSL 版本為 %1.%2" - msgid "Could not load texture: %1" msgstr "無法載入æè³ª: %1" @@ -2779,7 +2818,7 @@ msgid "Keybind" msgstr "éµç›¤ç¶å®" msgid "Clear binding" -msgstr "逿˜è£è¨‚" +msgstr "解除ç¶å®" msgid "Bind" msgstr "ç¶å®" @@ -2805,8 +2844,11 @@ msgstr "å‚³é€ Control+Alt+Escape" msgid "Toggle fullscreen" msgstr "切æ›å…¨è¢å¹•" +msgid "Toggle UI in fullscreen" +msgstr "切æ›ä½¿ç”¨è€…介é¢è‡³å…¨è¢å¹•" + msgid "Screenshot" -msgstr "è¢å¹•截圖" +msgstr "è¢å¹•擷圖" msgid "Release mouse pointer" msgstr "放開滑鼠游標" @@ -2830,7 +2872,7 @@ msgid "Local Switch" msgstr "本地交æ›å™¨" msgid "Remote Switch" -msgstr "陿§äº¤æ›å™¨" +msgstr "é ç«¯äº¤æ›å™¨" msgid "Switch:" msgstr "交æ›å™¨:" @@ -2851,7 +2893,7 @@ msgid "&Wipe NVRAM" msgstr "清除(&W) NVRAM" msgid "This will delete all NVRAM (and related) files of the virtual machine located in the \"nvr\" subdirectory. You'll have to reconfigure the BIOS (and possibly other devices inside the VM) settings again if applicable.\n\nAre you sure you want to wipe all NVRAM contents of the virtual machine \"%1\"?" -msgstr "é€™å°‡åˆªé™¤ä½æ–¼ (\"nvr\" å­ç›®éŒ„中ç„) è™›æ“¬æ©Ÿå™¨ç„æ‰€æœ‰ NVRAM (和相關) æª”æ¡ˆă€‚å¦‚æœé©ç”¨ç„è©±ï¼Œæ‚¨å¿…é ˆé‡æ–°è¨­å® BIOS (å¯èƒ½é‚„有虛擬機器內ç„å…¶ä»–è£ç½®) 設å®ă€‚\n\n您確å®è¦æ¸…除虛擬機 \"%1\" ç„æ‰€æœ‰ NVRAM 內容å—?" +msgstr "é€™å°‡åˆªé™¤ä½æ–¼ (\"nvr\" å­ç›®éŒ„中ç„) è™›æ“¬æ©Ÿå™¨ç„æ‰€æœ‰ NVRAM (和相關) æª”æ¡ˆă€‚å¦‚æœå¥—用ç„è©±ï¼Œæ‚¨å¿…é ˆé‡æ–°è¨­å® BIOS (å¯èƒ½é‚„有虛擬機器內ç„å…¶ä»–è£ç½®) 設å®ă€‚\n\n您確å®è¦æ¸…除虛擬機 \"%1\" ç„æ‰€æœ‰ NVRAM 內容å—?" msgid "Success" msgstr "æˆåŸ" @@ -2878,16 +2920,16 @@ msgid "Check for updates on startup" msgstr "啟動時檢查更新" msgid "Unable to determine release information" -msgstr "無法確å®é‡‹æ”¾è³‡è¨" +msgstr "無法確å®ç‰ˆæœ¬ç™¼ä½ˆè³‡è¨" msgid "There was an error checking for updates:\n\n%1\n\nPlease try again later." -msgstr "檢查更新時出錯:\n'\n%1\n\nè«‹ç¨å¾Œå†è©¦ă€‚" +msgstr "檢查更新時出錯:\n\n%1\n\nè«‹ç¨å¾Œå†è©¦ă€‚" msgid "Update check complete" msgstr "更新檢查完æˆ" msgid "stable" -msgstr "ç©©å®" +msgstr "ç©©å®ç‰ˆ" msgid "beta" msgstr "測試版" @@ -2929,7 +2971,7 @@ msgid "86Box Update" msgstr "86Box æ›´æ–°" msgid "Release notes:" -msgstr "發佈說æ˜:" +msgstr "版本發佈說æ˜:" msgid "%1 Hz" msgstr "%1 Hz" @@ -2962,10 +3004,10 @@ msgid "Sharpness" msgstr "é³åˆ©åº¦" msgid "&CGA composite settings..." -msgstr "CGA è¤‡åˆæ¨¡å¼ç„設å®...(&C)" +msgstr "CGA 複åˆè¦–è¨ç„設å®(&C)..." msgid "CGA composite settings" -msgstr "CGA è¤‡åˆæ¨¡å¼ç„設å®" +msgstr "CGA 複åˆè¦–è¨ç„設å®" msgid "Monitor EDID" msgstr "ç›£è¦–å™¨ç„ EDID" @@ -2983,7 +3025,7 @@ msgid "OpenGL input scale" msgstr "OpenGL ç„輸入比例" msgid "OpenGL input stretch mode" -msgstr "OpenGL ç„輸入拉伸模å¼" +msgstr "OpenGL ç„輸入延展模å¼" msgid "Color scheme" msgstr "é…色方案" diff --git a/src/qt/qt_about.cpp b/src/qt/qt_about.cpp index a85ab54d52d..f3628279744 100644 --- a/src/qt/qt_about.cpp +++ b/src/qt/qt_about.cpp @@ -48,9 +48,9 @@ About::About(QWidget *parent) # define DYNAREC_STR "no dynarec" #endif versioninfo.append(QString(" [%1, %2]").arg(QSysInfo::buildCpuArchitecture(), tr(DYNAREC_STR))); - setText(QString("%3%1%2").arg(EMU_VERSION_FULL, versioninfo, tr("86Box v"))); + setText(QString("%1 v%2%3").arg(EMU_NAME, EMU_VERSION_FULL, versioninfo)); setInformativeText(tr("An emulator of old computers\n\nAuthors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), Tiseno100, reenigne, and others.\n\nWith previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2 or later. See LICENSE for more information.").replace("\n", "
")); - setWindowTitle(tr("About 86Box")); + setWindowTitle(tr("About %1").arg(EMU_NAME)); const auto closeButton = addButton("OK", QMessageBox::ButtonRole::AcceptRole); setEscapeButton(closeButton); const auto webSiteButton = addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); diff --git a/src/qt/qt_cgasettingsdialog.cpp b/src/qt/qt_cgasettingsdialog.cpp index ee9aa86b68d..5357c905ab5 100644 --- a/src/qt/qt_cgasettingsdialog.cpp +++ b/src/qt/qt_cgasettingsdialog.cpp @@ -3,8 +3,7 @@ #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/vid_cga_comp.h> @@ -16,11 +15,11 @@ CGASettingsDialog::CGASettingsDialog(QWidget *parent) { ui->setupUi(this); - cga_hue = vid_cga_comp_hue; + cga_hue = vid_cga_comp_hue; cga_saturation = vid_cga_comp_saturation; cga_brightness = vid_cga_comp_brightness; - cga_contrast = vid_cga_comp_contrast; - cga_sharpness = vid_cga_comp_sharpness; + cga_contrast = vid_cga_comp_contrast; + cga_sharpness = vid_cga_comp_sharpness; ui->horizontalSliderHue->setValue(vid_cga_comp_hue); ui->horizontalSliderSaturation->setValue(vid_cga_comp_saturation); @@ -29,8 +28,7 @@ CGASettingsDialog::CGASettingsDialog(QWidget *parent) ui->horizontalSliderSharpness->setValue(vid_cga_comp_sharpness); connect(ui->buttonBox->button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &CGASettingsDialog::applySettings); - connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QPushButton::clicked, this, [this] - { + connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QPushButton::clicked, this, [this] { ui->horizontalSliderHue->setValue(0); ui->horizontalSliderSaturation->setValue(100); ui->horizontalSliderBrightness->setValue(0); @@ -38,11 +36,11 @@ CGASettingsDialog::CGASettingsDialog(QWidget *parent) ui->horizontalSliderSharpness->setValue(0); }); - connect(ui->horizontalSliderHue, &QSlider::valueChanged, this, [this] { updateDisplay(); } ); - connect(ui->horizontalSliderSaturation, &QSlider::valueChanged, this, [this] { updateDisplay(); } ); - connect(ui->horizontalSliderBrightness, &QSlider::valueChanged, this, [this] { updateDisplay(); } ); - connect(ui->horizontalSliderContrast, &QSlider::valueChanged, this, [this] { updateDisplay(); } ); - connect(ui->horizontalSliderSharpness, &QSlider::valueChanged, this, [this] { updateDisplay(); } ); + connect(ui->horizontalSliderHue, &QSlider::valueChanged, this, [this] { updateDisplay(); }); + connect(ui->horizontalSliderSaturation, &QSlider::valueChanged, this, [this] { updateDisplay(); }); + connect(ui->horizontalSliderBrightness, &QSlider::valueChanged, this, [this] { updateDisplay(); }); + connect(ui->horizontalSliderContrast, &QSlider::valueChanged, this, [this] { updateDisplay(); }); + connect(ui->horizontalSliderSharpness, &QSlider::valueChanged, this, [this] { updateDisplay(); }); } CGASettingsDialog::~CGASettingsDialog() @@ -50,7 +48,8 @@ CGASettingsDialog::~CGASettingsDialog() delete ui; } -void CGASettingsDialog::updateDisplay() +void +CGASettingsDialog::updateDisplay() { auto temp_cga_comp_hue = ui->horizontalSliderHue->value(); auto temp_cga_comp_saturation = ui->horizontalSliderSaturation->value(); @@ -60,7 +59,8 @@ void CGASettingsDialog::updateDisplay() cga_comp_reload(temp_cga_comp_brightness, temp_cga_comp_saturation, temp_cga_comp_sharpness, temp_cga_comp_hue, temp_cga_comp_contrast); } -void CGASettingsDialog::applySettings() +void +CGASettingsDialog::applySettings() { vid_cga_comp_hue = ui->horizontalSliderHue->value(); vid_cga_comp_saturation = ui->horizontalSliderSaturation->value(); @@ -69,26 +69,27 @@ void CGASettingsDialog::applySettings() vid_cga_comp_sharpness = ui->horizontalSliderSharpness->value(); cga_comp_reload(vid_cga_comp_brightness, vid_cga_comp_saturation, vid_cga_comp_sharpness, vid_cga_comp_hue, vid_cga_comp_contrast); - cga_hue = vid_cga_comp_hue; + cga_hue = vid_cga_comp_hue; cga_saturation = vid_cga_comp_saturation; cga_brightness = vid_cga_comp_brightness; - cga_contrast = vid_cga_comp_contrast; - cga_sharpness = vid_cga_comp_sharpness; + cga_contrast = vid_cga_comp_contrast; + cga_sharpness = vid_cga_comp_sharpness; } -void CGASettingsDialog::on_buttonBox_accepted() +void +CGASettingsDialog::on_buttonBox_accepted() { applySettings(); } -void CGASettingsDialog::on_buttonBox_rejected() +void +CGASettingsDialog::on_buttonBox_rejected() { - vid_cga_comp_hue = cga_hue; + vid_cga_comp_hue = cga_hue; vid_cga_comp_saturation = cga_saturation; vid_cga_comp_brightness = cga_brightness; - vid_cga_comp_contrast = cga_contrast; - vid_cga_comp_sharpness = cga_sharpness; + vid_cga_comp_contrast = cga_contrast; + vid_cga_comp_sharpness = cga_sharpness; cga_comp_reload(vid_cga_comp_brightness, vid_cga_comp_saturation, vid_cga_comp_sharpness, vid_cga_comp_hue, vid_cga_comp_contrast); } - diff --git a/src/qt/qt_cgasettingsdialog.ui b/src/qt/qt_cgasettingsdialog.ui index 7367b2099f0..dc5acb0fca5 100644 --- a/src/qt/qt_cgasettingsdialog.ui +++ b/src/qt/qt_cgasettingsdialog.ui @@ -15,18 +15,32 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize - - + + + + Hue + + + + + - -100 + -360 - 100 + 360 - Qt::Orientation::Horizontal + Qt::Horizontal + + + + + + + Saturation @@ -39,37 +53,34 @@ 100 - Qt::Orientation::Horizontal + Qt::Horizontal - - + + - Hue + Brightness - - + + - -50 + -100 - 50 + 100 - Qt::Orientation::Horizontal + Qt::Horizontal - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok|QDialogButtonBox::StandardButton::Reset + + + + Contrast @@ -82,48 +93,37 @@ 100 - Qt::Orientation::Horizontal + Qt::Horizontal - - + + - Contrast + Sharpness - - + + - -360 + -50 - 360 + 50 - Qt::Orientation::Horizontal + Qt::Horizontal - - - - Sharpness - - - - - - - Saturation + + + + Qt::Horizontal - - - - - - Brightness + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Reset diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 880539fe451..7cc39898873 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -50,7 +50,7 @@ extern "C" { # include #endif #ifdef Q_OS_WINDOWS -#include +# include #endif DeviceConfig::DeviceConfig(QWidget *parent) @@ -87,15 +87,16 @@ EnumerateSerialDevices() for (int i = 1; i < 256; i++) { devstr[0] = 0; snprintf(devstr.data(), 1024, R"(\\.\COM%d)", i); - const auto handle = CreateFileA(devstr.data(), - GENERIC_READ | GENERIC_WRITE, 0, - nullptr, OPEN_EXISTING, - 0, nullptr); + const auto handle = CreateFileA(devstr.data(), + GENERIC_READ | GENERIC_WRITE, 0, + nullptr, OPEN_EXISTING, + 0, nullptr); const auto dwError = GetLastError(); if ((handle != INVALID_HANDLE_VALUE) || (dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT)) { - if (handle != INVALID_HANDLE_VALUE) CloseHandle(handle); + if (handle != INVALID_HANDLE_VALUE) + CloseHandle(handle); serialDevices.push_back(QString(devstr)); } } @@ -114,8 +115,8 @@ EnumerateSerialDevices() void DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) { - auto * device_context = static_cast(dc); - const auto * config = static_cast(c); + auto *device_context = static_cast(dc); + const auto *config = static_cast(c); const QString blank = ""; int p; int q; @@ -136,7 +137,7 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) const int config_major_type = (config_type >> CONFIG_SHIFT) << CONFIG_SHIFT; - int value = 0; + int value = 0; auto selected = blank; switch (config_major_type) { @@ -164,210 +165,211 @@ DeviceConfig::ProcessConfig(void *dc, const void *c, const bool is_dep) default: break; case CONFIG_BINARY: - { - auto *cbox = new QCheckBox(); - cbox->setObjectName(config->name); - cbox->setChecked(value > 0); - this->ui->formLayout->addRow(tr(config->description), cbox); - break; - } + { + auto *cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + this->ui->formLayout->addRow(tr(config->description), cbox); + break; + } #ifdef USE_RTMIDI case CONFIG_MIDI_OUT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_out_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_out_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (i == value) - currentIndex = i; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; + } + this->ui->formLayout->addRow(tr(config->description), cbox); + cbox->setCurrentIndex(currentIndex); + break; } - this->ui->formLayout->addRow(tr(config->description), cbox); - cbox->setCurrentIndex(currentIndex); - break; - } case CONFIG_MIDI_IN: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; - for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_in_get_dev_name(i, midiName); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; + 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 (i == value) - currentIndex = i; + Models::AddEntry(model, midiName, i); + if (i == value) + currentIndex = i; + } + this->ui->formLayout->addRow(tr(config->description), cbox); + cbox->setCurrentIndex(currentIndex); + break; } - this->ui->formLayout->addRow(tr(config->description), cbox); - cbox->setCurrentIndex(currentIndex); - break; - } #endif case CONFIG_INT: case CONFIG_SELECTION: case CONFIG_HEX16: case CONFIG_HEX20: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && - (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, tr(sel->description), sel->value); + for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && + (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, tr(sel->description), sel->value); - if (sel->value == value) - currentIndex = row; + if (sel->value == value) + currentIndex = row; + } + this->ui->formLayout->addRow(tr(config->description), cbox); + cbox->setCurrentIndex(currentIndex); + break; } - this->ui->formLayout->addRow(tr(config->description), cbox); - cbox->setCurrentIndex(currentIndex); - break; - } case CONFIG_BIOS: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = -1; + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = -1; - q = 0; - for (auto *bios = config->bios; (bios != nullptr) && - (bios->name != nullptr) && - (bios->internal_name != nullptr) && - (strlen(bios->name) > 0) && - (strlen(bios->internal_name) > 0) && - (bios->files_no > 0); ++bios) { - p = 0; - for (int d = 0; d < bios->files_no; d++) - p += !!rom_present(const_cast(bios->files[d])); - if (p == bios->files_no) { - const int row = Models::AddEntry(model, tr(bios->name), q); - if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) - currentIndex = row; + q = 0; + for (auto *bios = config->bios; (bios != nullptr) && + (bios->name != nullptr) && + (bios->internal_name != nullptr) && + (strlen(bios->name) > 0) && + (strlen(bios->internal_name) > 0) && + (bios->files_no > 0); ++bios) { + p = 0; + for (int d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + const int row = Models::AddEntry(model, tr(bios->name), q); + if (!strcmp(selected.toUtf8().constData(), bios->internal_name)) + currentIndex = row; + } + q++; } - q++; + this->ui->formLayout->addRow(tr(config->description), cbox); + cbox->setCurrentIndex(currentIndex); + break; } - this->ui->formLayout->addRow(tr(config->description), cbox); - cbox->setCurrentIndex(currentIndex); - break; - } case CONFIG_SPINNER: - { - 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); - this->ui->formLayout->addRow(tr(config->description), spinBox); - break; - } + { + 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); + this->ui->formLayout->addRow(tr(config->description), spinBox); + break; + } case CONFIG_FNAME: - { - auto *fileField = new FileField(this); - fileField->setObjectName(config->name); - fileField->setFileName(selected); - /* Get the actually used part of the filter */ + { + auto *fileField = new FileField(this); + fileField->setObjectName(config->name); + fileField->setFileName(selected); + /* Get the actually used part of the filter */ #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) - QString filter = QString(config->file_filter).left(static_cast(strcspn(config->file_filter, "|"))); + QString filter = QString(config->file_filter).left(static_cast(strcspn(config->file_filter, "|"))); #else - QString filter = QString(config->file_filter).split("|").at(0); + QString filter = QString(config->file_filter).split("|").at(0); #endif - /* Extract the description and the extension list */ - QRegularExpressionMatch match = QRegularExpression("(.+) \\((.+)\\)$").match(filter); - QString description = match.captured(1); - QString extensions = match.captured(2); - /* Split the extension list up and strip the filename globs */ - QRegularExpression re("\\*\\.(.*)"); + /* Extract the description and the extension list */ + QRegularExpressionMatch match = QRegularExpression("(.+) \\((.+)\\)$").match(filter); + QString description = match.captured(1); + QString extensions = match.captured(2); + /* Split the extension list up and strip the filename globs */ + QRegularExpression re("\\*\\.(.*)"); #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) - QStringList extensionList; - int i = 0; - while (extensions.section(' ', i, i) != "") { - QString extension = re.match(extensions.section(' ', i, i)).captured(1); - extensionList.append(extension); - i++; - } + QStringList extensionList; + int i = 0; + while (extensions.section(' ', i, i) != "") { + QString extension = re.match(extensions.section(' ', i, i)).captured(1); + extensionList.append(extension); + i++; + } #else - QStringList extensionList = extensions.split(" "); - for (int i = 0; i < extensionList.count(); i++) - extensionList[i] = re.match(extensionList[i]).captured(1); + QStringList extensionList = extensions.split(" "); + for (int i = 0; i < extensionList.count(); i++) + extensionList[i] = re.match(extensionList[i]).captured(1); #endif - fileField->setFilter(tr(description.toUtf8().constData()) % util::DlgFilter(extensionList) % tr("All files") % util::DlgFilter({ "*" }, true)); - this->ui->formLayout->addRow(tr(config->description), fileField); - break; - } + fileField->setFilter(tr(description.toUtf8().constData()) % util::DlgFilter(extensionList) % tr("All files") % util::DlgFilter({ "*" }, true)); + this->ui->formLayout->addRow(tr(config->description), fileField); + break; + } case CONFIG_STRING: - { - const auto lineEdit = new QLineEdit; - lineEdit->setObjectName(config->name); - lineEdit->setCursor(Qt::IBeamCursor); - lineEdit->setText(selected); - this->ui->formLayout->addRow(tr(config->description), lineEdit); - break; - } + { + const auto lineEdit = new QLineEdit; + lineEdit->setObjectName(config->name); + lineEdit->setCursor(Qt::IBeamCursor); + lineEdit->setText(selected); + this->ui->formLayout->addRow(tr(config->description), lineEdit); + break; + } case CONFIG_SERPORT: - { - auto *cbox = new QComboBox(); - cbox->setObjectName(config->name); - cbox->setMaxVisibleItems(30); - auto *model = cbox->model(); - int currentIndex = 0; - auto serialDevices = EnumerateSerialDevices(); + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + cbox->setMaxVisibleItems(30); + auto *model = cbox->model(); + int currentIndex = 0; + auto serialDevices = EnumerateSerialDevices(); - Models::AddEntry(model, tr("None"), -1); - for (int i = 0; i < serialDevices.size(); i++) { - const int row = Models::AddEntry(model, serialDevices[i], i); - if (selected == serialDevices[i]) - currentIndex = row; - } + Models::AddEntry(model, tr("None"), -1); + for (int i = 0; i < serialDevices.size(); i++) { + const int row = Models::AddEntry(model, serialDevices[i], i); + if (selected == serialDevices[i]) + currentIndex = row; + } - this->ui->formLayout->addRow(tr(config->description), cbox); - cbox->setCurrentIndex(currentIndex); - break; - } + this->ui->formLayout->addRow(tr(config->description), cbox); + cbox->setCurrentIndex(currentIndex); + break; + } case CONFIG_MAC: - { - // QHBoxLayout for the line edit widget and the generate button - const auto hboxLayout = new QHBoxLayout(); - const auto generateButton = new QPushButton(tr("Generate")); - const auto lineEdit = new QLineEdit; - // Allow the line edit to expand and fill available space - lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred); - lineEdit->setInputMask("HH:HH:HH;0"); - lineEdit->setObjectName(config->name); - // Display the current or generated MAC in uppercase - // When stored it will be converted to lowercase - if (config_get_mac(device_context->name, config->name, - config->default_int) & 0xFF000000) { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), - random_generate(), random_generate())); - } else { - auto current_mac = QString(config_get_string(device_context->name, config->name, - const_cast(config->default_string))); - lineEdit->setText(current_mac.toUpper()); + { + // QHBoxLayout for the line edit widget and the generate button + const auto hboxLayout = new QHBoxLayout(); + const auto generateButton = new QPushButton(tr("Generate")); + const auto lineEdit = new QLineEdit; + // Allow the line edit to expand and fill available space + lineEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); + lineEdit->setInputMask("HH:HH:HH;0"); + lineEdit->setObjectName(config->name); + // Display the current or generated MAC in uppercase + // When stored it will be converted to lowercase + if (config_get_mac(device_context->name, config->name, + config->default_int) + & 0xFF000000) { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); + } else { + auto current_mac = QString(config_get_string(device_context->name, config->name, + const_cast(config->default_string))); + lineEdit->setText(current_mac.toUpper()); + } + // Action for the generate button + connect(generateButton, &QPushButton::clicked, [lineEdit] { + lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), + random_generate(), random_generate())); + }); + hboxLayout->addWidget(lineEdit); + hboxLayout->addWidget(generateButton); + this->ui->formLayout->addRow(tr(config->description), hboxLayout); + break; } - // Action for the generate button - connect(generateButton, &QPushButton::clicked, [lineEdit] { - lineEdit->setText(QString::asprintf("%02X:%02X:%02X", random_generate(), - random_generate(), random_generate())); - }); - hboxLayout->addWidget(lineEdit); - hboxLayout->addWidget(generateButton); - this->ui->formLayout->addRow(tr(config->description), hboxLayout); - break; - } } ++config; } diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp index a5214111f49..2e92416233b 100644 --- a/src/qt/qt_deviceconfig.hpp +++ b/src/qt/qt_deviceconfig.hpp @@ -28,7 +28,7 @@ class DeviceConfig : public QDialog { private: Ui::DeviceConfig *ui; - void ProcessConfig(void *dc, const void *c, bool is_dep); + void ProcessConfig(void *dc, const void *c, bool is_dep); }; #endif // QT_DEVICECONFIG_HPP diff --git a/src/qt/qt_downloader.cpp b/src/qt/qt_downloader.cpp index d88eca57ae6..f6366e8ce10 100644 --- a/src/qt/qt_downloader.cpp +++ b/src/qt/qt_downloader.cpp @@ -23,8 +23,7 @@ extern "C" { #include <86box/plat.h> } -Downloader:: -Downloader(const DownloadLocation downloadLocation, QObject *parent) +Downloader::Downloader(const DownloadLocation downloadLocation, QObject *parent) : QObject(parent) , file(nullptr) , reply(nullptr) @@ -51,7 +50,9 @@ Downloader(const DownloadLocation downloadLocation, QObject *parent) Downloader::~Downloader() { delete file; } -void Downloader::download(const QUrl &url, const QString &filepath, const QVariant &varData) { +void +Downloader::download(const QUrl &url, const QString &filepath, const QVariant &varData) +{ variantData = varData; // temporary until I get the plat stuff fixed @@ -62,7 +63,7 @@ void Downloader::download(const QUrl &url, const QString &filepath, const QVaria const auto final_path = downloadDirectory.filePath(filepath); file = new QFile(final_path); - if(!file->open(QIODevice::WriteOnly)) { + if (!file->open(QIODevice::WriteOnly)) { qWarning() << "Unable to open file " << final_path; return; } @@ -70,7 +71,7 @@ void Downloader::download(const QUrl &url, const QString &filepath, const QVaria const auto nam = new QNetworkAccessManager(this); // Create the network request and execute const auto request = QNetworkRequest(url); - reply = nam->get(request); + reply = nam->get(request); // Connect to the finished signal connect(reply, &QNetworkReply::finished, this, &Downloader::onResult); } @@ -93,4 +94,3 @@ Downloader::onResult() qDebug() << Q_FUNC_INFO << "Downloaded complete: file written to " << file->fileName(); emit downloadCompleted(file->fileName(), variantData); } - diff --git a/src/qt/qt_downloader.hpp b/src/qt/qt_downloader.hpp index 942da3c49dd..82b4229d70b 100644 --- a/src/qt/qt_downloader.hpp +++ b/src/qt/qt_downloader.hpp @@ -20,7 +20,6 @@ #include #include - class Downloader final : public QObject { Q_OBJECT public: @@ -38,17 +37,17 @@ class Downloader final : public QObject { // Signal emitted when the download is successful void downloadCompleted(QString filename, QVariant varData); // Signal emitted when an error occurs - void errorOccurred(const QString&); + void errorOccurred(const QString &); private slots: void onResult(); private: - QFile *file; + QFile *file; QNetworkAccessManager nam; - QNetworkReply *reply; - QVariant variantData; - QDir downloadDirectory; + QNetworkReply *reply; + QVariant variantData; + QDir downloadDirectory; }; #endif diff --git a/src/qt/qt_filefield.ui b/src/qt/qt_filefield.ui index 3a1e3e75374..91000af50d1 100644 --- a/src/qt/qt_filefield.ui +++ b/src/qt/qt_filefield.ui @@ -51,7 +51,7 @@ - &Specify... + Browse... diff --git a/src/qt/qt_glsl_parser.cpp b/src/qt/qt_glsl_parser.cpp index 0bd35ca258d..4dbddd1c088 100644 --- a/src/qt/qt_glsl_parser.cpp +++ b/src/qt/qt_glsl_parser.cpp @@ -3,15 +3,14 @@ #include #include -extern MainWindow* main_window; +extern MainWindow *main_window; #include #include #include #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/ini.h> #include <86box/config.h> @@ -19,25 +18,32 @@ extern "C" #include <86box/path.h> #include <86box/plat.h> -extern void startblit(); -extern void endblit(); +extern void startblit(); +extern void endblit(); extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); -extern char* trim(char* str); +extern char *trim(char *str); } -#define safe_strncpy(a, b, n) \ - do { \ - strncpy((a), (b), (n)-1); \ - (a)[(n)-1] = 0; \ - } while (0) - +#define safe_strncpy(a, b, n) \ + do { \ + strncpy((a), (b), (n) - 1); \ + (a)[(n) - 1] = 0; \ + } while (0) +static inline void * +wx_config_load(const char *path) +{ + ini_t ini = ini_read(path); + if (ini) + ini_strip_quotes(ini); + return (void *) ini; +} -static inline void *wx_config_load(const char *path) { ini_t ini = ini_read(path); if (ini) ini_strip_quotes(ini); return (void*)ini; } - -static inline int wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal) { - int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); - char* str = ini_get_string((ini_t)config, "", name, (char*)defVal); +static inline int +wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal) +{ + int res = ini_has_entry(ini_find_or_create_section((ini_t) config, ""), name); + char *str = ini_get_string((ini_t) config, "", name, (char *) defVal); if (size == 0) return res; if (str != NULL) @@ -47,40 +53,56 @@ static inline int wx_config_get_string(void *config, const char *name, char *dst return res; } -static inline int wx_config_get_int(void *config, const char *name, int *dst, int defVal) { - int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); - *dst = ini_get_int((ini_t)config, "", name, defVal); +static inline int +wx_config_get_int(void *config, const char *name, int *dst, int defVal) +{ + int res = ini_has_entry(ini_find_or_create_section((ini_t) config, ""), name); + *dst = ini_get_int((ini_t) config, "", name, defVal); return res; } -static inline int wx_config_get_float(void *config, const char *name, float *dst, float defVal) { - int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); - *dst = (float)ini_get_double((ini_t)config, "", name, defVal); +static inline int +wx_config_get_float(void *config, const char *name, float *dst, float defVal) +{ + int res = ini_has_entry(ini_find_or_create_section((ini_t) config, ""), name); + *dst = (float) ini_get_double((ini_t) config, "", name, defVal); return res; } -static inline int wx_config_get_bool(void *config, const char *name, int *dst, int defVal) { - int res = ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); - *dst = !!ini_get_int((ini_t)config, "", name, defVal); +static inline int +wx_config_get_bool(void *config, const char *name, int *dst, int defVal) +{ + int res = ini_has_entry(ini_find_or_create_section((ini_t) config, ""), name); + *dst = !!ini_get_int((ini_t) config, "", name, defVal); return res; } -static inline int wx_config_has_entry(void *config, const char *name) { return ini_has_entry(ini_find_or_create_section((ini_t)config, ""), name); } -static inline void wx_config_free(void *config) { ini_close(config); }; - -static int endswith(const char *str, const char *ext) { - const char *p; - int elen = strlen(ext); - int slen = strlen(str); - if (slen >= elen) { - p = &str[slen - elen]; - for (int i = 0; i < elen; ++i) { - if (tolower(p[i]) != tolower(ext[i])) - return 0; - } - return 1; +static inline int +wx_config_has_entry(void *config, const char *name) +{ + return ini_has_entry(ini_find_or_create_section((ini_t) config, ""), name); +} +static inline void +wx_config_free(void *config) +{ + ini_close(config); +}; + +static int +endswith(const char *str, const char *ext) +{ + const char *p; + int elen = strlen(ext); + int slen = strlen(str); + if (slen >= elen) { + p = &str[slen - elen]; + for (int i = 0; i < elen; ++i) { + if (tolower(p[i]) != tolower(ext[i])) + return 0; } - return 0; + return 1; + } + return 0; } static int @@ -101,326 +123,355 @@ glsl_detect_bom(const char *fn) return 0; } -static char *load_file(const char *fn) { - int bom = glsl_detect_bom(fn); - FILE *fp = plat_fopen(fn, "rb"); - if (!fp) - return 0; - fseek(fp, 0, SEEK_END); - long fsize = ftell(fp); - fseek(fp, 0, SEEK_SET); +static char * +load_file(const char *fn) +{ + int bom = glsl_detect_bom(fn); + FILE *fp = plat_fopen(fn, "rb"); + if (!fp) + return 0; + fseek(fp, 0, SEEK_END); + long fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); - if (bom) { - fsize -= 3; - fseek(fp, 3, SEEK_SET); - } + if (bom) { + fsize -= 3; + fseek(fp, 3, SEEK_SET); + } - char *data = (char*)malloc(fsize + 1); + char *data = (char *) malloc(fsize + 1); - size_t read_bytes = fread(data, fsize, 1, fp); - if (read_bytes != 1) { - fclose(fp); - free(data); - return nullptr; - } else { - fclose(fp); + size_t read_bytes = fread(data, fsize, 1, fp); + if (read_bytes != 1) { + fclose(fp); + free(data); + return nullptr; + } else { + fclose(fp); - data[fsize] = 0; + data[fsize] = 0; - return data; - } + return data; + } } -static void strip_lines(const char *program, const char *starts_with) { - /* strip parameters */ - char *ptr = (char *) strstr(program, starts_with); - while (ptr != nullptr) { - while (*ptr != '\n' && *ptr != '\0') - *ptr++ = ' '; - ptr = (char *) strstr(program, starts_with); - } +static void +strip_lines(const char *program, const char *starts_with) +{ + /* strip parameters */ + char *ptr = (char *) strstr(program, starts_with); + while (ptr != nullptr) { + while (*ptr != '\n' && *ptr != '\0') + *ptr++ = ' '; + ptr = (char *) strstr(program, starts_with); + } } -static void strip_parameters(const char *program) { - /* strip parameters */ - strip_lines(program, "#pragma parameter"); +static void +strip_parameters(const char *program) +{ + /* strip parameters */ + strip_lines(program, "#pragma parameter"); } -static void strip_defines(const char *program) { - /* strip texture define */ - strip_lines(program, "#define texture"); +static void +strip_defines(const char *program) +{ + /* strip texture define */ + strip_lines(program, "#define texture"); } -static int has_parameter(glslp_t *glsl, char *id) { - for (int i = 0; i < glsl->num_parameters; ++i) - if (!strcmp(glsl->parameters[i].id, id)) - return 1; - return 0; +static int +has_parameter(glslp_t *glsl, char *id) +{ + for (int i = 0; i < glsl->num_parameters; ++i) + if (!strcmp(glsl->parameters[i].id, id)) + return 1; + return 0; } -static int get_parameters(glslp_t *glsl) { - struct parameter p; - for (int i = 0; i < glsl->num_shaders; ++i) { - size_t size = 0; - char* line = NULL; - struct shader *shader = &glsl->shaders[i]; - int bom = glsl_detect_bom(shader->shader_fn); - FILE *f = plat_fopen(shader->shader_fn, "rb"); - if (!f) - return 0; - if (bom) { - fseek(f, 3, SEEK_SET); - } - while (local_getline(&line, &size, f) != -1 && glsl->num_parameters < MAX_PARAMETERS) { - line[strcspn(line, "\r\n")] = '\0'; - trim(line); - int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, - &p.default_value, &p.min, &p.max, &p.step); - if (num < 5) - continue; - p.id[63] = 0; - p.description[63] = 0; - - if (num == 5) - p.step = 0.1f * (p.max - p.min); - - p.value = p.default_value; - - if (!has_parameter(glsl, p.id)) { - memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); - pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, - p.max, p.step); - } - } - - fclose(f); +static int +get_parameters(glslp_t *glsl) +{ + struct parameter p; + for (int i = 0; i < glsl->num_shaders; ++i) { + size_t size = 0; + char *line = NULL; + struct shader *shader = &glsl->shaders[i]; + int bom = glsl_detect_bom(shader->shader_fn); + FILE *f = plat_fopen(shader->shader_fn, "rb"); + if (!f) + return 0; + if (bom) { + fseek(f, 3, SEEK_SET); + } + while (local_getline(&line, &size, f) != -1 && glsl->num_parameters < MAX_PARAMETERS) { + line[strcspn(line, "\r\n")] = '\0'; + trim(line); + int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, + &p.default_value, &p.min, &p.max, &p.step); + if (num < 5) + continue; + p.id[63] = 0; + p.description[63] = 0; + + if (num == 5) + p.step = 0.1f * (p.max - p.min); + + p.value = p.default_value; + + if (!has_parameter(glsl, p.id)) { + memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); + pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, + p.max, p.step); + } } - return 1; + fclose(f); + } + + return 1; } -static struct parameter *get_parameter(glslp_t *glslp, const char *id) { - for (int i = 0; i < glslp->num_parameters; ++i) { - if (!strcmp(glslp->parameters[i].id, id)) { - return &glslp->parameters[i]; - } +static struct parameter * +get_parameter(glslp_t *glslp, const char *id) +{ + for (int i = 0; i < glslp->num_parameters; ++i) { + if (!strcmp(glslp->parameters[i].id, id)) { + return &glslp->parameters[i]; } + } + return 0; +} + +static glslp_t * +glsl_parse(const char *f) +{ + glslp_t *glslp = (glslp_t *) calloc(1, sizeof(glslp_t)); + glslp->num_shaders = 1; + struct shader *shader = &glslp->shaders[0]; + strcpy(shader->shader_fn, f); + shader->shader_program = load_file(f); + if (!shader->shader_program) { + QMessageBox::critical((QWidget *) qApp->findChild(), QObject::tr("GLSL error"), QObject::tr("Could not load shader: %1").arg(shader->shader_fn)); + // wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + shader->scale_x = shader->scale_y = 1.0f; + strcpy(shader->scale_type_x, "source"); + strcpy(shader->scale_type_y, "source"); + get_parameters(glslp); + return glslp; +} + +extern "C" { + +void +get_glslp_name(const char *f, char *s, int size) +{ + safe_strncpy(s, path_get_filename((char *) f), size); } -static glslp_t *glsl_parse(const char *f) { - glslp_t *glslp = (glslp_t*) calloc(1, sizeof(glslp_t)); - glslp->num_shaders = 1; - struct shader *shader = &glslp->shaders[0]; - strcpy(shader->shader_fn, f); - shader->shader_program = load_file(f); +glslp_t * +glslp_parse(const char *f) +{ + int j; + int len; + int sublen; + char s[2049], t[2049], z[2076]; + + memset(s, 0, sizeof(s)); + if (endswith(f, ".glsl")) + return glsl_parse(f); + + void *cfg = wx_config_load(f); + + if (!cfg) { + fprintf(stderr, "GLSLP Error: Could not load GLSLP-file %s\n", f); + return 0; + } + + glslp_t *glslp = (glslp_t *) calloc(1, sizeof(glslp_t)); + + get_glslp_name(f, glslp->name, sizeof(glslp->name)); + + wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); + + wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); + + for (int i = 0; i < glslp->num_shaders; ++i) { + struct shader *shader = &glslp->shaders[i]; + + snprintf(s, sizeof(s) - 1, "shader%d", i); + if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) { + /* shader doesn't exist, lets break here */ + glslp->num_shaders = i; + break; + } + strcpy(s, f); + *path_get_filename(s) = 0; + + size_t max_len = sizeof(shader->shader_fn); + size_t s_len = strlen(s); + + if (s_len >= max_len) { + // s alone fills or overflows the buffer, truncate and null-terminate + size_t copy_len = max_len - 1 < s_len ? max_len - 1 : s_len; + memcpy(shader->shader_fn, s, copy_len); + shader->shader_fn[copy_len] = '\0'; + } else { + // Copy s fully + memcpy(shader->shader_fn, s, s_len); + // Copy as much of t as fits after s + size_t avail = max_len - 1 - s_len; // space left for t + null terminator + // Copy as much of t as fits into the remaining space + memcpy(shader->shader_fn + s_len, t, avail); + // Null-terminate + shader->shader_fn[s_len + avail] = '\0'; + } + + shader->shader_program = load_file(shader->shader_fn); if (!shader->shader_program) { - QMessageBox::critical((QWidget *) qApp->findChild(), QObject::tr("GLSL error"), QObject::tr("Could not load shader: %1").arg(shader->shader_fn)); - //wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; + fprintf(stderr, "GLSLP Error: Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; } strip_parameters(shader->shader_program); strip_defines(shader->shader_program); - shader->scale_x = shader->scale_y = 1.0f; - strcpy(shader->scale_type_x, "source"); - strcpy(shader->scale_type_y, "source"); - get_parameters(glslp); - return glslp; -} -extern "C" { + snprintf(s, sizeof(s) - 1, "alias%d", i); + wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); -void get_glslp_name(const char *f, char *s, int size) { safe_strncpy(s, path_get_filename((char *)f), size); } + snprintf(s, sizeof(s) - 1, "filter_linear%d", i + 1); + wx_config_get_bool(cfg, s, &shader->filter_linear, 0); -glslp_t *glslp_parse(const char *f) { - int j; - int len; - int sublen; - char s[2049], t[2049], z[2076]; + snprintf(s, sizeof(s) - 1, "wrap_mode%d", i); + wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); - memset(s, 0, sizeof(s)); - if (endswith(f, ".glsl")) - return glsl_parse(f); + snprintf(s, sizeof(s) - 1, "float_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); + snprintf(s, sizeof(s) - 1, "srgb_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); - void *cfg = wx_config_load(f); + snprintf(s, sizeof(s) - 1, "mipmap_input%d", i); + wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); - if (!cfg) { - fprintf(stderr, "GLSLP Error: Could not load GLSLP-file %s\n", f); - return 0; + strcpy(shader->scale_type_x, "source"); + snprintf(s, sizeof(s) - 1, "scale_type_x%d", i); + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + strcpy(shader->scale_type_y, "source"); + snprintf(s, sizeof(s) - 1, "scale_type_y%d", i); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + snprintf(s, sizeof(s) - 1, "scale_type%d", i); + if (wx_config_has_entry(cfg, s)) { + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); } - glslp_t *glslp = (glslp_t*) calloc(1, sizeof(glslp_t)); - - get_glslp_name(f, glslp->name, sizeof(glslp->name)); - - wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); - - wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); - - for (int i = 0; i < glslp->num_shaders; ++i) { - struct shader *shader = &glslp->shaders[i]; - - snprintf(s, sizeof(s) - 1, "shader%d", i); - if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) { - /* shader doesn't exist, lets break here */ - glslp->num_shaders = i; - break; - } - strcpy(s, f); - *path_get_filename(s) = 0; - - size_t max_len = sizeof(shader->shader_fn); - size_t s_len = strlen(s); - - if (s_len >= max_len) { - // s alone fills or overflows the buffer, truncate and null-terminate - size_t copy_len = max_len - 1 < s_len ? max_len - 1 : s_len; - memcpy(shader->shader_fn, s, copy_len); - shader->shader_fn[copy_len] = '\0'; - } else { - // Copy s fully - memcpy(shader->shader_fn, s, s_len); - // Copy as much of t as fits after s - size_t avail = max_len - 1 - s_len; // space left for t + null terminator - // Copy as much of t as fits into the remaining space - memcpy(shader->shader_fn + s_len, t, avail); - // Null-terminate - shader->shader_fn[s_len + avail] = '\0'; - } - - shader->shader_program = load_file(shader->shader_fn); - if (!shader->shader_program) { - fprintf(stderr, "GLSLP Error: Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; - } - strip_parameters(shader->shader_program); - strip_defines(shader->shader_program); - - snprintf(s, sizeof(s) - 1, "alias%d", i); - wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); - - snprintf(s, sizeof(s) - 1, "filter_linear%d", i + 1); - wx_config_get_bool(cfg, s, &shader->filter_linear, 0); - - snprintf(s, sizeof(s) - 1, "wrap_mode%d", i); - wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); - - snprintf(s, sizeof(s) - 1, "float_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); - snprintf(s, sizeof(s) - 1, "srgb_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); - - snprintf(s, sizeof(s) - 1, "mipmap_input%d", i); - wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); - - strcpy(shader->scale_type_x, "source"); - snprintf(s, sizeof(s) - 1, "scale_type_x%d", i); - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - strcpy(shader->scale_type_y, "source"); - snprintf(s, sizeof(s) - 1, "scale_type_y%d", i); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - snprintf(s, sizeof(s) - 1, "scale_type%d", i); - if (wx_config_has_entry(cfg, s)) { - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - } - - snprintf(s, sizeof(s) - 1, "scale_x%d", i); - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - snprintf(s, sizeof(s) - 1, "scale_y%d", i); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - snprintf(s, sizeof(s) - 1, "scale%d", i); - if (wx_config_has_entry(cfg, s)) { - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - } - - snprintf(s, sizeof(s) - 1, "frame_count_mod%d", i); - wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); + snprintf(s, sizeof(s) - 1, "scale_x%d", i); + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + snprintf(s, sizeof(s) - 1, "scale_y%d", i); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + snprintf(s, sizeof(s) - 1, "scale%d", i); + if (wx_config_has_entry(cfg, s)) { + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); } - /* textures */ - glslp->num_textures = 0; - wx_config_get_string(cfg, "textures", t, sizeof(t), 0); + snprintf(s, sizeof(s) - 1, "frame_count_mod%d", i); + wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); + } + + /* textures */ + glslp->num_textures = 0; + wx_config_get_string(cfg, "textures", t, sizeof(t), 0); - len = strlen(t); - j = 0; - sublen = 0; - for (int i = 0; i < len; ++i) { - if (t[i] == ';' || i == len - 1) { - sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; - safe_strncpy(s, t + j, sublen); - s[511 < sublen ? 511 : sublen] = 0; + len = strlen(t); + j = 0; + sublen = 0; + for (int i = 0; i < len; ++i) { + if (t[i] == ';' || i == len - 1) { + sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; + safe_strncpy(s, t + j, sublen); + s[511 < sublen ? 511 : sublen] = 0; - if (s[strlen(s) - 1] == ';') s[strlen(s) - 1] = 0; + if (s[strlen(s) - 1] == ';') + s[strlen(s) - 1] = 0; - struct texture *tex = &glslp->textures[glslp->num_textures++]; + struct texture *tex = &glslp->textures[glslp->num_textures++]; - strcpy(tex->name, s); - wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); + strcpy(tex->name, s); + wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); - snprintf(z, sizeof(z) - 1, "%s_linear", s); - wx_config_get_bool(cfg, z, &tex->linear, 0); + snprintf(z, sizeof(z) - 1, "%s_linear", s); + wx_config_get_bool(cfg, z, &tex->linear, 0); - snprintf(z, sizeof(z) - 1, "%s_mipmap", s); - wx_config_get_bool(cfg, z, &tex->mipmap, 0); + snprintf(z, sizeof(z) - 1, "%s_mipmap", s); + wx_config_get_bool(cfg, z, &tex->mipmap, 0); - snprintf(z, sizeof(z) - 1, "%s_wrap_mode", s); - wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); + snprintf(z, sizeof(z) - 1, "%s_wrap_mode", s); + wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); - j = i + 1; - } + j = i + 1; } + } - /* parameters */ - get_parameters(glslp); + /* parameters */ + get_parameters(glslp); - wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); + wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); - len = strlen(t); - j = 0; - sublen = 0; - for (int i = 0; i < len; ++i) { - if (t[i] == ';' || i == len - 1) { - sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; - safe_strncpy(s, t + j, sublen); - s[511 < sublen ? 511 : sublen] = 0; + len = strlen(t); + j = 0; + sublen = 0; + for (int i = 0; i < len; ++i) { + if (t[i] == ';' || i == len - 1) { + sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; + safe_strncpy(s, t + j, sublen); + s[511 < sublen ? 511 : sublen] = 0; - struct parameter *p = get_parameter(glslp, s); + struct parameter *p = get_parameter(glslp, s); - if (p) - wx_config_get_float(cfg, s, &p->default_value, 0); + if (p) + wx_config_get_float(cfg, s, &p->default_value, 0); - j = i + 1; - } + j = i + 1; } + } - wx_config_free(cfg); + wx_config_free(cfg); - return glslp; + return glslp; } -void glslp_free(glslp_t *p) { - for (int i = 0; i < p->num_shaders; ++i) - if (p->shaders[i].shader_program) - free(p->shaders[i].shader_program); - free(p); +void +glslp_free(glslp_t *p) +{ + for (int i = 0; i < p->num_shaders; ++i) + if (p->shaders[i].shader_program) + free(p->shaders[i].shader_program); + free(p); } -void glslp_read_shader_config(glslp_t *shader) { - char s[512]; +void +glslp_read_shader_config(glslp_t *shader) +{ + char s[512]; char *name = shader->name; - snprintf(s, sizeof(s) -1, "GL3 Shaders - %s", name); + snprintf(s, sizeof(s) - 1, "GL3 Shaders - %s", name); for (int i = 0; i < shader->num_parameters; ++i) { struct parameter *param = &shader->parameters[i]; - param->value = config_get_double(s, param->id, param->default_value); + param->value = config_get_double(s, param->id, param->default_value); } } -void glslp_write_shader_config(glslp_t *shader) { - char s[512]; +void +glslp_write_shader_config(glslp_t *shader) +{ + char s[512]; char *name = shader->name; startblit(); @@ -431,5 +482,4 @@ void glslp_write_shader_config(glslp_t *shader) { } endblit(); } - } diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index 66ab3e59b97..fbb6a476897 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -19,7 +19,7 @@ extern "C" { #ifdef __unix__ -#include +# include #endif #include <86box/86box.h> #include <86box/hdd.h> @@ -75,7 +75,7 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) 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 = tr("%1 MB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); + QString text = tr("%1 MB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); Models::AddEntry(model, text, i); } Models::AddEntry(model, tr("Custom..."), 127); @@ -85,11 +85,11 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); filters = QStringList({ tr("Raw image") % util::DlgFilter({ "img" }, true), - tr("HDI image") % util::DlgFilter({ "hdi" }, true), - tr("HDX image") % util::DlgFilter({ "hdx" }, true), - tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true), - tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true), - tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) }); + tr("HDI image") % util::DlgFilter({ "hdi" }, true), + tr("HDX image") % util::DlgFilter({ "hdx" }, true), + tr("Fixed-size VHD") % util::DlgFilter({ "vhd" }, true), + tr("Dynamic-size VHD") % util::DlgFilter({ "vhd" }, true), + tr("Differencing VHD") % util::DlgFilter({ "vhd" }, true) }); if (existing) { ui->fileField->setFilter(tr("Hard disk images") % util::DlgFilter({ "hd?", "im?", "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true)); @@ -317,7 +317,6 @@ create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, in _86box_geometry.spt = vhd_geometry.spt; } - mvhd_close(vhd); } @@ -414,7 +413,7 @@ HarddiskDialog::onCreateNewFile() file.close(); _86BoxGeom _86box_geometry {}; - int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { case IMG_FMT_VHD_FIXED: { @@ -568,7 +567,7 @@ HarddiskDialog::onExistingFileSelected(const QString &fileName, bool precheck) if (!file.open(QIODevice::ReadOnly)) { // No message box during precheck (performed when the file input loses focus and this function is called) // If precheck is false, the file has been chosen from a file dialog and the alert should display. - if(!precheck) { + if (!precheck) { QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); } return; diff --git a/src/qt/qt_harddiskdialog.ui b/src/qt/qt_harddiskdialog.ui index e2dea022093..6de39375f0a 100644 --- a/src/qt/qt_harddiskdialog.ui +++ b/src/qt/qt_harddiskdialog.ui @@ -33,7 +33,7 @@ - + File name: @@ -43,7 +43,7 @@ - + Cylinders: @@ -66,7 +66,7 @@ - + Heads: @@ -92,7 +92,7 @@ - + Sectors: @@ -118,7 +118,7 @@ - + Size (MB): @@ -141,7 +141,7 @@ - + Type: @@ -155,7 +155,7 @@ - + Bus: @@ -169,7 +169,7 @@ - + Channel: @@ -183,7 +183,7 @@ - + Model: diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 9e48a627e6a..1c07e5f3ff5 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -123,10 +123,10 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT { model->removeRows(0, model->rowCount()); - int busRows = 0; - int shifter = 1; - int orer = 1; - int subChannelWidth = 1; + int busRows = 0; + int shifter = 1; + int orer = 1; + int subChannelWidth = 1; QList busesToCheck; QList channelsInUse; switch (bus) { @@ -160,15 +160,15 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT busesToCheck.append(HDD_BUS_SCSI); break; case CDROM_BUS_MKE: - shifter = 2; - orer = 3; - busRows = 4; + shifter = 2; + orer = 3; + busRows = 4; busesToCheck.append(CDROM_BUS_MKE); break; default: break; } - if(sbt != nullptr && !busesToCheck.empty()) { + if (sbt != nullptr && !busesToCheck.empty()) { for (auto const &checkBus : busesToCheck) { channelsInUse.append(sbt->busChannelsInUse(checkBus)); } @@ -179,9 +179,9 @@ Harddrives::populateBusChannels(QAbstractItemModel *model, int bus, SettingsBusT 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); - const auto *channelModel = qobject_cast(model); - auto *channelItem = channelModel->item(i); - if(channelItem) { + const auto *channelModel = qobject_cast(model); + auto *channelItem = channelModel->item(i); + if (channelItem) { channelItem->setEnabled(!channelsInUse.contains(i)); } } diff --git a/src/qt/qt_iconindicators.cpp b/src/qt/qt_iconindicators.cpp index 169910b217e..b93c375b741 100644 --- a/src/qt/qt_iconindicators.cpp +++ b/src/qt/qt_iconindicators.cpp @@ -35,7 +35,7 @@ getIconWithIndicator(const QIcon &icon, const QSize &size, QIcon::Mode iconMode, if (indicator == None) return iconPixmap; - auto painter = QPainter(&iconPixmap); + auto painter = QPainter(&iconPixmap); auto indicatorPixmap = getIndicatorIcon((indicator == ReadWriteActive || indicator == WriteProtectedActive) ? Active : indicator).pixmap(size); if (indicator == WriteProtectedBrowse) diff --git a/src/qt/qt_iconindicators.hpp b/src/qt/qt_iconindicators.hpp index c3c8946ad3d..24ce80ad370 100644 --- a/src/qt/qt_iconindicators.hpp +++ b/src/qt/qt_iconindicators.hpp @@ -1,5 +1,5 @@ #ifndef QT_ICONINDICATORS_HPP -# define QT_ICONINDICATORS_HPP +#define QT_ICONINDICATORS_HPP #include #include diff --git a/src/qt/qt_joystickconfiguration.ui b/src/qt/qt_joystickconfiguration.ui index 139b99ca521..f5f2773b39f 100644 --- a/src/qt/qt_joystickconfiguration.ui +++ b/src/qt/qt_joystickconfiguration.ui @@ -32,7 +32,7 @@ - + Device diff --git a/src/qt/qt_keybind.cpp b/src/qt/qt_keybind.cpp index 1862f4aa89a..78845a733ed 100644 --- a/src/qt/qt_keybind.cpp +++ b/src/qt/qt_keybind.cpp @@ -52,7 +52,7 @@ extern "C" { # include #endif #ifdef Q_OS_WINDOWS -#include +# include #endif KeyBinder::KeyBinder(QWidget *parent) @@ -60,10 +60,10 @@ KeyBinder::KeyBinder(QWidget *parent) , ui(new Ui::KeyBinder) { ui->setupUi(this); - singleKeySequenceEdit *seq = new singleKeySequenceEdit(); - ui->formLayout->addRow(seq); - seq->setObjectName("keySequence"); - this->setTabOrder(seq, ui->buttonBox); + singleKeySequenceEdit *seq = new singleKeySequenceEdit(); + ui->formLayout->addRow(seq); + seq->setObjectName("keySequence"); + this->setTabOrder(seq, ui->buttonBox); } KeyBinder::~KeyBinder() @@ -72,29 +72,31 @@ KeyBinder::~KeyBinder() } void -KeyBinder::showEvent( QShowEvent* event ) { - QWidget::showEvent( event ); - this->findChild()->setFocus(); -} +KeyBinder::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + this->findChild()->setFocus(); +} -bool KeyBinder::eventFilter(QObject *obj, QEvent *event) +bool +KeyBinder::eventFilter(QObject *obj, QEvent *event) { - return QObject::eventFilter(obj, event); + return QObject::eventFilter(obj, event); } QKeySequence -KeyBinder::BindKey(QWidget* widget, QString CurValue) +KeyBinder::BindKey(QWidget *widget, QString CurValue) { - KeyBinder kb(widget); - kb.setWindowTitle(tr("Bind Key")); + KeyBinder kb(widget); + kb.setWindowTitle(tr("Bind Key")); kb.setFixedSize(kb.minimumSizeHint()); - kb.findChild()->setKeySequence(QKeySequence::fromString(CurValue, QKeySequence::NativeText)); - kb.setEnabled(true); - + kb.findChild()->setKeySequence(QKeySequence::fromString(CurValue, QKeySequence::NativeText)); + kb.setEnabled(true); + if (kb.exec() == QDialog::Accepted) { - QKeySequenceEdit *seq = kb.findChild(); - return (seq->keySequence()); + QKeySequenceEdit *seq = kb.findChild(); + return (seq->keySequence()); } else { - return (false); - } + return (false); + } } \ No newline at end of file diff --git a/src/qt/qt_keybind.hpp b/src/qt/qt_keybind.hpp index 25f4a916856..055dacce475 100644 --- a/src/qt/qt_keybind.hpp +++ b/src/qt/qt_keybind.hpp @@ -22,12 +22,12 @@ class KeyBinder : public QDialog { explicit KeyBinder(QWidget *parent = nullptr); ~KeyBinder() override; - static QKeySequence BindKey(QWidget* widget, QString CurValue); + static QKeySequence BindKey(QWidget *widget, QString CurValue); private: Ui::KeyBinder *ui; - bool eventFilter(QObject *obj, QEvent *event) override; - void showEvent( QShowEvent* event ) override; + bool eventFilter(QObject *obj, QEvent *event) override; + void showEvent(QShowEvent *event) override; }; #endif // QT_KeyBinder_HPP diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index b9d4c438539..2e6203f24d8 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -109,9 +109,9 @@ struct Pixmaps { struct StateActive { std::unique_ptr label; - PixmapSetActive *pixmaps = nullptr; - bool active = false; - bool write_active = false; + PixmapSetActive *pixmaps = nullptr; + bool active = false; + bool write_active = false; void setActive(bool b) { @@ -164,11 +164,11 @@ struct StateEmpty { }; struct StateEmptyActive { std::unique_ptr label; - PixmapSetEmptyActive *pixmaps = nullptr; - bool empty = false; - bool active = false; - bool write_active = false; - bool wp = false; + PixmapSetEmptyActive *pixmaps = nullptr; + bool empty = false; + bool active = false; + bool write_active = false; + bool wp = false; void setActive(bool b) { @@ -222,7 +222,7 @@ struct StateEmptyActive { } }; -static QSize pixmap_size(16, 16); +static QSize pixmap_size(16, 16); void PixmapSetEmpty::load(const QIcon &icon) @@ -236,8 +236,8 @@ PixmapSetActive::load(const QIcon &icon) { normal = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, None); active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, Active); - - write_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, WriteActive); + + write_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, WriteActive); read_write_active = getIconWithIndicator(icon, pixmap_size, QIcon::Normal, ReadWriteActive); } @@ -326,7 +326,7 @@ MachineStatus::MachineStatus(QObject *parent) : QObject(parent) , refreshTimer(new QTimer(this)) { - d = std::make_unique(this); + d = std::make_unique(this); soundMenu = nullptr; connect(refreshTimer, &QTimer::timeout, this, &MachineStatus::refreshIcons); refreshTimer->start(75); @@ -335,7 +335,7 @@ MachineStatus::MachineStatus(QObject *parent) MachineStatus::~MachineStatus() = default; void -MachineStatus::setSoundMenu(QMenu* menu) +MachineStatus::setSoundMenu(QMenu *menu) { soundMenu = menu; } @@ -768,7 +768,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_MFM && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_MFM].label->setToolTip(tooltip); @@ -784,7 +784,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_ESDI && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_ESDI].label->setToolTip(tooltip); @@ -800,7 +800,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_XTA && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_XTA].label->setToolTip(tooltip); @@ -819,7 +819,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_IDE && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_IDE].label->setToolTip(tooltip); @@ -835,7 +835,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_ATAPI && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 1), QString::number(hdd[i].channel & 1), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_ATAPI].label->setToolTip(tooltip); @@ -855,7 +855,7 @@ MachineStatus::refresh(QStatusBar *sbar) tooltip.append("\n"); for (int i = 0; i < HDD_NUM; i++) { if (hdd[i].bus_type == HDD_BUS_SCSI && hdd[i].fn[0] != 0) { - tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 4), QString::asprintf("%02d", hdd[i].channel & 15), QString::number((((qulonglong)hdd[i].hpc * (qulonglong)hdd[i].spt * (qulonglong)hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); + tooltip.append(QString("\n%5:%6: %1 (C:H:S = %2:%3:%4, %7 %8)").arg(QString::fromUtf8(hdd[i].fn), QString::number(hdd[i].tracks), QString::number(hdd[i].hpc), QString::number(hdd[i].spt), QString::number(hdd[i].channel >> 4), QString::asprintf("%02d", hdd[i].channel & 15), QString::number((((qulonglong) hdd[i].hpc * (qulonglong) hdd[i].spt * (qulonglong) hdd[i].tracks) * 512ull) / 1048576ull), tr("MB"))); } } d->hdds[HDD_BUS_SCSI].label->setToolTip(tooltip); diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index bb505826558..2e270ec84b0 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -78,7 +78,7 @@ class MachineStatus : public QObject { QString getMessage(); void clearActivity(); - void setSoundMenu(QMenu* menu); + void setSoundMenu(QMenu *menu); public slots: void refresh(QStatusBar *sbar); void message(const QString &msg); diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 90b4b6e59f0..5526eee37c0 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -50,14 +50,14 @@ extern "C" { #include <86box/ui.h> #include <86box/video.h> #ifdef DISCORD -# include <86box/discord.h> +# include <86box/discord.h> #endif #include <86box/gdbstub.h> #include <86box/version.h> #include <86box/renderdefs.h> #ifdef Q_OS_LINUX -#define GAMEMODE_AUTO -#include "../unix/gamemode/gamemode_client.h" +# define GAMEMODE_AUTO +# include "../unix/gamemode/gamemode_client.h" #endif } @@ -96,7 +96,7 @@ extern "C" { #include "cpu.h" #include <86box/timer.h> #include <86box/nvr.h> -extern int qt_nvr_save(void); +extern int qt_nvr_save(void); extern void exit_pause(void); bool cpu_thread_running = false; @@ -210,19 +210,19 @@ win_keyboard_handle(uint32_t scancode, int up, int e0, int e1) static LRESULT CALLBACK emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { - LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; + LPKBDLLHOOKSTRUCT lpKdhs = (LPKBDLLHOOKSTRUCT) lParam; /* Checks if CTRL was pressed. */ - BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); - BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); - BOOL ret = TRUE; + BOOL bCtrlDown = GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); + BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); + BOOL ret = TRUE; - static int last = 0; + static int last = 0; - if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - const auto &secondaryRenderer = main_window->renderers[monitor_index]; - is_over_window = is_over_window || ((secondaryRenderer != nullptr) && - (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); - } + if (show_second_monitors) + for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { + const auto &secondaryRenderer = main_window->renderers[monitor_index]; + is_over_window = is_over_window || ((secondaryRenderer != nullptr) && (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); + } bool skip = ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window || (kbd_req_capture && !mouse_capture)); @@ -235,179 +235,173 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) Only a handful of keys can be handled via Virtual Key detection; rest can't be reliably detected. */ DWORD vkCode = lpKdhs->vkCode; - bool up = !!(lpKdhs->flags & LLKHF_UP); - - if (inhibit_multimedia_keys - && (lpKdhs->vkCode == VK_MEDIA_PLAY_PAUSE - || lpKdhs->vkCode == VK_MEDIA_NEXT_TRACK - || lpKdhs->vkCode == VK_MEDIA_PREV_TRACK - || lpKdhs->vkCode == VK_VOLUME_DOWN - || lpKdhs->vkCode == VK_VOLUME_UP - || lpKdhs->vkCode == VK_VOLUME_MUTE - || lpKdhs->vkCode == VK_MEDIA_STOP - || lpKdhs->vkCode == VK_LAUNCH_MEDIA_SELECT - || lpKdhs->vkCode == VK_LAUNCH_MAIL - || lpKdhs->vkCode == VK_LAUNCH_APP1 - || lpKdhs->vkCode == VK_LAUNCH_APP2 - || lpKdhs->vkCode == VK_HELP - || lpKdhs->vkCode == VK_BROWSER_BACK - || lpKdhs->vkCode == VK_BROWSER_FORWARD - || lpKdhs->vkCode == VK_BROWSER_FAVORITES - || lpKdhs->vkCode == VK_BROWSER_HOME - || lpKdhs->vkCode == VK_BROWSER_REFRESH - || lpKdhs->vkCode == VK_BROWSER_SEARCH - || lpKdhs->vkCode == VK_BROWSER_STOP)) + bool up = !!(lpKdhs->flags & LLKHF_UP); + + if (inhibit_multimedia_keys && + (lpKdhs->vkCode == VK_MEDIA_PLAY_PAUSE || + lpKdhs->vkCode == VK_MEDIA_NEXT_TRACK || + lpKdhs->vkCode == VK_MEDIA_PREV_TRACK || + lpKdhs->vkCode == VK_VOLUME_DOWN || + lpKdhs->vkCode == VK_VOLUME_UP || + lpKdhs->vkCode == VK_VOLUME_MUTE || + lpKdhs->vkCode == VK_MEDIA_STOP || + lpKdhs->vkCode == VK_LAUNCH_MEDIA_SELECT || + lpKdhs->vkCode == VK_LAUNCH_MAIL || + lpKdhs->vkCode == VK_LAUNCH_APP1 || + lpKdhs->vkCode == VK_LAUNCH_APP2 || + lpKdhs->vkCode == VK_HELP || + lpKdhs->vkCode == VK_BROWSER_BACK || + lpKdhs->vkCode == VK_BROWSER_FORWARD || + lpKdhs->vkCode == VK_BROWSER_FAVORITES || + lpKdhs->vkCode == VK_BROWSER_HOME || + lpKdhs->vkCode == VK_BROWSER_REFRESH || + lpKdhs->vkCode == VK_BROWSER_SEARCH || + lpKdhs->vkCode == VK_BROWSER_STOP)) ret = TRUE; else ret = CallNextHookEx(NULL, nCode, wParam, lParam); - switch (vkCode) - { + switch (vkCode) { case VK_MEDIA_PLAY_PAUSE: - { - win_keyboard_handle(0x22, up, 1, 0); - break; - } + { + win_keyboard_handle(0x22, up, 1, 0); + break; + } case VK_MEDIA_STOP: - { - win_keyboard_handle(0x24, up, 1, 0); - break; - } + { + win_keyboard_handle(0x24, up, 1, 0); + break; + } case VK_VOLUME_UP: - { - win_keyboard_handle(0x30, up, 1, 0); - break; - } + { + win_keyboard_handle(0x30, up, 1, 0); + break; + } case VK_VOLUME_DOWN: - { - win_keyboard_handle(0x2E, up, 1, 0); - break; - } + { + win_keyboard_handle(0x2E, up, 1, 0); + break; + } case VK_VOLUME_MUTE: - { - win_keyboard_handle(0x20, up, 1, 0); - break; - } + { + win_keyboard_handle(0x20, up, 1, 0); + break; + } case VK_MEDIA_NEXT_TRACK: - { - win_keyboard_handle(0x19, up, 1, 0); - break; - } + { + win_keyboard_handle(0x19, up, 1, 0); + break; + } case VK_MEDIA_PREV_TRACK: - { - win_keyboard_handle(0x10, up, 1, 0); - break; - } + { + win_keyboard_handle(0x10, up, 1, 0); + break; + } case VK_LAUNCH_MEDIA_SELECT: - { - win_keyboard_handle(0x6D, up, 1, 0); - break; - } + { + win_keyboard_handle(0x6D, up, 1, 0); + break; + } case VK_LAUNCH_MAIL: - { - win_keyboard_handle(0x6C, up, 1, 0); - break; - } + { + win_keyboard_handle(0x6C, up, 1, 0); + break; + } case VK_LAUNCH_APP1: - { - win_keyboard_handle(0x6B, up, 1, 0); - break; - } + { + win_keyboard_handle(0x6B, up, 1, 0); + break; + } case VK_LAUNCH_APP2: - { - win_keyboard_handle(0x21, up, 1, 0); - break; - } + { + win_keyboard_handle(0x21, up, 1, 0); + break; + } case VK_BROWSER_BACK: - { - win_keyboard_handle(0x6A, up, 1, 0); - break; - } + { + win_keyboard_handle(0x6A, up, 1, 0); + break; + } case VK_BROWSER_FORWARD: - { - win_keyboard_handle(0x69, up, 1, 0); - break; - } + { + win_keyboard_handle(0x69, up, 1, 0); + break; + } case VK_BROWSER_STOP: - { - win_keyboard_handle(0x68, up, 1, 0); - break; - } + { + win_keyboard_handle(0x68, up, 1, 0); + break; + } case VK_BROWSER_HOME: - { - win_keyboard_handle(0x32, up, 1, 0); - break; - } + { + win_keyboard_handle(0x32, up, 1, 0); + break; + } case VK_BROWSER_SEARCH: - { - win_keyboard_handle(0x65, up, 1, 0); - break; - } + { + win_keyboard_handle(0x65, up, 1, 0); + break; + } case VK_BROWSER_REFRESH: - { - win_keyboard_handle(0x67, up, 1, 0); - break; - } + { + win_keyboard_handle(0x67, up, 1, 0); + break; + } case VK_BROWSER_FAVORITES: - { - win_keyboard_handle(0x66, up, 1, 0); - break; - } + { + win_keyboard_handle(0x66, up, 1, 0); + break; + } case VK_HELP: - { - win_keyboard_handle(0x3b, up, 1, 0); - break; - } + { + win_keyboard_handle(0x3b, up, 1, 0); + break; + } } return ret; - } - else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + } else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; - else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; - else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; - else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && - !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) + else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) ret = TRUE; else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) ret = TRUE; - else if (inhibit_multimedia_keys - && (lpKdhs->vkCode == VK_MEDIA_PLAY_PAUSE - || lpKdhs->vkCode == VK_MEDIA_NEXT_TRACK - || lpKdhs->vkCode == VK_MEDIA_PREV_TRACK - || lpKdhs->vkCode == VK_VOLUME_DOWN - || lpKdhs->vkCode == VK_VOLUME_UP - || lpKdhs->vkCode == VK_VOLUME_MUTE - || lpKdhs->vkCode == VK_MEDIA_STOP - || lpKdhs->vkCode == VK_LAUNCH_MEDIA_SELECT - || lpKdhs->vkCode == VK_LAUNCH_MAIL - || lpKdhs->vkCode == VK_LAUNCH_APP1 - || lpKdhs->vkCode == VK_LAUNCH_APP2 - || lpKdhs->vkCode == VK_HELP - || lpKdhs->vkCode == VK_BROWSER_BACK - || lpKdhs->vkCode == VK_BROWSER_FORWARD - || lpKdhs->vkCode == VK_BROWSER_FAVORITES - || lpKdhs->vkCode == VK_BROWSER_HOME - || lpKdhs->vkCode == VK_BROWSER_REFRESH - || lpKdhs->vkCode == VK_BROWSER_SEARCH - || lpKdhs->vkCode == VK_BROWSER_STOP)) + else if (inhibit_multimedia_keys && + (lpKdhs->vkCode == VK_MEDIA_PLAY_PAUSE || + lpKdhs->vkCode == VK_MEDIA_NEXT_TRACK || + lpKdhs->vkCode == VK_MEDIA_PREV_TRACK || + lpKdhs->vkCode == VK_VOLUME_DOWN || + lpKdhs->vkCode == VK_VOLUME_UP || + lpKdhs->vkCode == VK_VOLUME_MUTE || + lpKdhs->vkCode == VK_MEDIA_STOP || + lpKdhs->vkCode == VK_LAUNCH_MEDIA_SELECT || + lpKdhs->vkCode == VK_LAUNCH_MAIL || + lpKdhs->vkCode == VK_LAUNCH_APP1 || + lpKdhs->vkCode == VK_LAUNCH_APP2 || + lpKdhs->vkCode == VK_HELP || + lpKdhs->vkCode == VK_BROWSER_BACK || + lpKdhs->vkCode == VK_BROWSER_FORWARD || + lpKdhs->vkCode == VK_BROWSER_FAVORITES || + lpKdhs->vkCode == VK_BROWSER_HOME || + lpKdhs->vkCode == VK_BROWSER_REFRESH || + lpKdhs->vkCode == VK_BROWSER_SEARCH || + lpKdhs->vkCode == VK_BROWSER_STOP)) ret = TRUE; else ret = CallNextHookEx(NULL, nCode, wParam, lParam); if (lpKdhs->scanCode == 0x00000045) { if ((lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000090)) { - /* NumLock. */ - lpKdhs->flags &= ~LLKHF_EXTENDED; + /* NumLock. */ + lpKdhs->flags &= ~LLKHF_EXTENDED; } else if (!(lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000013)) { /* Pause - send E1 1D. */ win_keyboard_handle(0xe1, 0, 0, 0); @@ -433,21 +427,21 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) #endif #ifdef Q_OS_WINDOWS -static HHOOK llhook = NULL; +static HHOOK llhook = NULL; #endif void main_thread_fn() { - int frames; + int frames; QThread::currentThread()->setPriority(QThread::HighestPriority); plat_set_thread_name(nullptr, "main_thread"); framecountx = 0; // title_update = 1; uint64_t old_time = elapsed_timer.elapsed(); - int drawits = frames = 0; - is_cpu_thread = 1; + int drawits = frames = 0; + is_cpu_thread = 1; while (!is_quit && cpu_thread_run) { /* See if it is time to run a frame of code. */ const uint64_t new_time = elapsed_timer.elapsed(); @@ -505,8 +499,8 @@ main_thread_fn() } cpu_thread_running = false; - is_quit = 1; - for (uint8_t i = 1; i < GFXCARD_MAX; i ++) { + is_quit = 1; + for (uint8_t i = 1; i < GFXCARD_MAX; i++) { if (gfxcard[i]) { ui_deinit_monitor(i); plat_delay_ms(500); @@ -520,7 +514,7 @@ static std::thread *main_thread; QTimer discordupdate; #ifdef Q_OS_WINDOWS -WindowsDarkModeFilter* vmm_dark_mode_filter = nullptr; +WindowsDarkModeFilter *vmm_dark_mode_filter = nullptr; #endif int @@ -530,9 +524,9 @@ main(int argc, char *argv[]) bool wasDarkTheme = false; /* Check if Windows supports UTF-8 */ if (GetACP() == CP_UTF8) - acp_utf8 = 1; + acp_utf8 = 1; else - acp_utf8 = 0; + acp_utf8 = 0; #endif #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); @@ -568,9 +562,9 @@ main(int argc, char *argv[]) if (!util::isWindowsLightTheme()) { QFile f(":qdarkstyle/dark/darkstyle.qss"); - if (!f.exists()) { + if (!f.exists()) { printf("Unable to set stylesheet, file not found\n"); - } else { + } else { f.open(QFile::ReadOnly | QFile::Text); QTextStream ts(&f); qApp->setStyleSheet(ts.readAll()); @@ -685,7 +679,7 @@ main(int argc, char *argv[]) pc_init_modules(); // UUID / copy / move detection - if(!util::compareUuid()) { + if (!util::compareUuid()) { QMessageBox movewarnbox; movewarnbox.setIcon(QMessageBox::Icon::Warning); movewarnbox.setText(QObject::tr("This machine might have been moved or copied.")); @@ -721,7 +715,7 @@ main(int argc, char *argv[]) warningbox.addButton(QObject::tr("Exit"), QMessageBox::RejectRole); warningbox.exec(); if (warningbox.result() == QDialog::Accepted) - return 0; + return 0; } #endif @@ -748,7 +742,7 @@ main(int argc, char *argv[]) warningbox.addButton(QObject::tr("Exit"), QMessageBox::RejectRole); warningbox.exec(); if (warningbox.result() == QDialog::Accepted) - return 0; + return 0; } #ifdef DISCORD @@ -760,7 +754,7 @@ main(int argc, char *argv[]) // https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod exit_pause(); timeBeginPeriod(1); - atexit([] () -> void { timeEndPeriod(1); }); + atexit([]() -> void { timeEndPeriod(1); }); #endif main_window = new MainWindow(); @@ -772,13 +766,12 @@ main(int argc, char *argv[]) #ifdef WAYLAND if (QApplication::platformName().contains("wayland")) { /* Force a sync. */ - (void)main_window->winId(); + (void) main_window->winId(); QApplication::sync(); - extern void wl_keyboard_grab(QWindow *window); + extern void wl_keyboard_grab(QWindow * window); wl_keyboard_grab(main_window->windowHandle()); } #endif - app.installEventFilter(main_window); @@ -826,7 +819,7 @@ main(int argc, char *argv[]) if (hook_enabled) { /* Yes, low-level hooks *DO* work with raw input, at least global ones. */ llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); - atexit([] () -> void { + atexit([]() -> void { if (llhook) UnhookWindowsHookEx(llhook); }); @@ -920,10 +913,10 @@ main(int argc, char *argv[]) plat_pause(0); cpu_thread_running = true; - main_thread = new std::thread(main_thread_fn); + main_thread = new std::thread(main_thread_fn); }); - const auto ret = app.exec(); + const auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index e41f36c57d3..083f0761aa1 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -40,7 +40,7 @@ extern "C" { #include <86box/plat.h> #include <86box/ui.h> #ifdef DISCORD -# include <86box/discord.h> +# include <86box/discord.h> #endif #include <86box/device.h> #include <86box/video.h> @@ -124,8 +124,8 @@ void qt_set_sequence_auto_mnemonic(bool b); #endif #if defined Q_OS_UNIX && !defined Q_OS_HAIKU && !defined Q_OS_MACOS -#include -#include "x11_util.h" +# include +# include "x11_util.h" #endif #ifdef Q_OS_MACOS @@ -143,7 +143,7 @@ namespace IOKit { # include "be_keyboard.hpp" extern MainWindow *main_window; -QShortcut *windowedShortcut; +QShortcut *windowedShortcut; filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) @@ -191,8 +191,8 @@ MainWindow::MainWindow(QWidget *parent) ui->stackedWidget->setMouseTracking(true); statusBar()->setVisible(!hide_status_bar); - auto hertz_label = new QLabel; - QTimer* frameRateTimer = new QTimer(this); + auto hertz_label = new QLabel; + QTimer *frameRateTimer = new QTimer(this); frameRateTimer->setInterval(1000); frameRateTimer->setSingleShot(false); connect(frameRateTimer, &QTimer::timeout, [hertz_label] { @@ -205,14 +205,14 @@ MainWindow::MainWindow(QWidget *parent) statusBar()->addPermanentWidget(hertz_label); frameRateTimer->start(1000); - num_icon = QIcon(":/settings/qt/icons/num_lock_on.ico"); - num_icon_off = QIcon(":/settings/qt/icons/num_lock_off.ico"); - scroll_icon = QIcon(":/settings/qt/icons/scroll_lock_on.ico"); + num_icon = QIcon(":/settings/qt/icons/num_lock_on.ico"); + num_icon_off = QIcon(":/settings/qt/icons/num_lock_off.ico"); + scroll_icon = QIcon(":/settings/qt/icons/scroll_lock_on.ico"); scroll_icon_off = QIcon(":/settings/qt/icons/scroll_lock_off.ico"); - caps_icon = QIcon(":/settings/qt/icons/caps_lock_on.ico"); - caps_icon_off = QIcon(":/settings/qt/icons/caps_lock_off.ico"); - kana_icon = QIcon(":/settings/qt/icons/kana_lock_on.ico"); - kana_icon_off = QIcon(":/settings/qt/icons/kana_lock_off.ico"); + caps_icon = QIcon(":/settings/qt/icons/caps_lock_on.ico"); + caps_icon_off = QIcon(":/settings/qt/icons/caps_lock_off.ico"); + kana_icon = QIcon(":/settings/qt/icons/kana_lock_on.ico"); + kana_icon_off = QIcon(":/settings/qt/icons/kana_lock_off.ico"); num_label = new QLabel; num_label->setPixmap(num_icon_off.pixmap(QSize(16, 16))); @@ -234,10 +234,10 @@ MainWindow::MainWindow(QWidget *parent) kana_label->setToolTip(QShortcut::tr("Kana Lock")); statusBar()->addPermanentWidget(kana_label); - QTimer* ledKeyboardTimer = new QTimer(this); + QTimer *ledKeyboardTimer = new QTimer(this); ledKeyboardTimer->setTimerType(Qt::CoarseTimer); ledKeyboardTimer->setInterval(1); - connect(ledKeyboardTimer, &QTimer::timeout, this, [this] () { + connect(ledKeyboardTimer, &QTimer::timeout, this, [this]() { uint8_t caps, num, scroll, kana; keyboard_get_states(&caps, &num, &scroll, &kana); @@ -246,12 +246,10 @@ MainWindow::MainWindow(QWidget *parent) if (caps_label->isVisible()) caps_label->setPixmap(caps ? this->caps_icon.pixmap(QSize(16, 16)) : this->caps_icon_off.pixmap(QSize(16, 16))); if (scroll_label->isVisible()) - scroll_label->setPixmap(scroll ? this->scroll_icon.pixmap(QSize(16, 16)) : - this->scroll_icon_off.pixmap(QSize(16, 16))); + scroll_label->setPixmap(scroll ? this->scroll_icon.pixmap(QSize(16, 16)) : this->scroll_icon_off.pixmap(QSize(16, 16))); if (kana_label->isVisible()) - kana_label->setPixmap(kana ? this->kana_icon.pixmap(QSize(16, 16)) : - this->kana_icon_off.pixmap(QSize(16, 16))); + kana_label->setPixmap(kana ? this->kana_icon.pixmap(QSize(16, 16)) : this->kana_icon_off.pixmap(QSize(16, 16))); }); ledKeyboardTimer->start(); @@ -285,10 +283,8 @@ MainWindow::MainWindow(QWidget *parent) num_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); scroll_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); - int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && - (keyboard_type == KEYBOARD_TYPE_AX); - int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && - !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); + int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && (keyboard_type == KEYBOARD_TYPE_AX); + int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); kana_label->setVisible(ext_ax_kbd || int_ax_kbd); while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); @@ -300,7 +296,10 @@ MainWindow::MainWindow(QWidget *parent) bool enable_comp_option = false; for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].mon_composite) { enable_comp_option = true; break; } + if (monitors[i].mon_composite) { + enable_comp_option = true; + break; + } } ui->actionCGA_composite_settings->setEnabled(enable_comp_option); @@ -314,20 +313,7 @@ MainWindow::MainWindow(QWidget *parent) return; } 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 }); connect(this, &MainWindow::getTitleForNonQtThread, this, &MainWindow::getTitle_, Qt::BlockingQueuedConnection); @@ -398,8 +384,7 @@ MainWindow::MainWindow(QWidget *parent) if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { w = static_cast(w / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)); - const int modifiedHeight = - static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + const int modifiedHeight = static_cast(h / (!dpi_scale ? util::screenOfWidget(this)->devicePixelRatio() : 1.)) + menuBar()->height() + (statusBar()->height() * !hide_status_bar) + (ui->toolBar->height() * !hide_tool_bar); @@ -576,17 +561,27 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->action_6x_2); actGroup->addAction(ui->action_7x_2); actGroup->addAction(ui->action_8x_2); - connect(actGroup, &QActionGroup::triggered, this, [this](QAction* action) { - if (action == ui->action_0_5x_2) video_gl_input_scale = 0.5; - if (action == ui->action_1x_2) video_gl_input_scale = 1; - if (action == ui->action1_5x_2) video_gl_input_scale = 1.5; - if (action == ui->action_2x_2) video_gl_input_scale = 2; - if (action == ui->action_3x_2) video_gl_input_scale = 3; - if (action == ui->action_4x_2) video_gl_input_scale = 4; - if (action == ui->action_5x_2) video_gl_input_scale = 5; - if (action == ui->action_6x_2) video_gl_input_scale = 6; - if (action == ui->action_7x_2) video_gl_input_scale = 7; - if (action == ui->action_8x_2) video_gl_input_scale = 8; + connect(actGroup, &QActionGroup::triggered, this, [this](QAction *action) { + if (action == ui->action_0_5x_2) + video_gl_input_scale = 0.5; + if (action == ui->action_1x_2) + video_gl_input_scale = 1; + if (action == ui->action1_5x_2) + video_gl_input_scale = 1.5; + if (action == ui->action_2x_2) + video_gl_input_scale = 2; + if (action == ui->action_3x_2) + video_gl_input_scale = 3; + if (action == ui->action_4x_2) + video_gl_input_scale = 4; + if (action == ui->action_5x_2) + video_gl_input_scale = 5; + if (action == ui->action_6x_2) + video_gl_input_scale = 6; + if (action == ui->action_7x_2) + video_gl_input_scale = 7; + if (action == ui->action_8x_2) + video_gl_input_scale = 8; }); switch (scale) { @@ -697,12 +692,17 @@ MainWindow::MainWindow(QWidget *parent) actGroup->addAction(ui->action_Square_pixels_keep_ratio_gl); actGroup->addAction(ui->action_Integer_scale_gl); actGroup->addAction(ui->action4_3_Integer_scale_gl); - connect(actGroup, &QActionGroup::triggered, this, [this](QAction* action) { - if (action == ui->action_Full_screen_stretch_gl) video_gl_input_scale_mode = FULLSCR_SCALE_FULL; - if (action == ui->action_4_3_gl) video_gl_input_scale_mode = FULLSCR_SCALE_43; - if (action == ui->action_Square_pixels_keep_ratio_gl) video_gl_input_scale_mode = FULLSCR_SCALE_KEEPRATIO; - if (action == ui->action_Integer_scale_gl) video_gl_input_scale_mode = FULLSCR_SCALE_INT; - if (action == ui->action4_3_Integer_scale_gl) video_gl_input_scale_mode = FULLSCR_SCALE_INT43; + connect(actGroup, &QActionGroup::triggered, this, [this](QAction *action) { + if (action == ui->action_Full_screen_stretch_gl) + video_gl_input_scale_mode = FULLSCR_SCALE_FULL; + if (action == ui->action_4_3_gl) + video_gl_input_scale_mode = FULLSCR_SCALE_43; + if (action == ui->action_Square_pixels_keep_ratio_gl) + video_gl_input_scale_mode = FULLSCR_SCALE_KEEPRATIO; + if (action == ui->action_Integer_scale_gl) + video_gl_input_scale_mode = FULLSCR_SCALE_INT; + if (action == ui->action4_3_Integer_scale_gl) + video_gl_input_scale_mode = FULLSCR_SCALE_INT43; }); switch (video_grayscale) { default: @@ -770,7 +770,7 @@ MainWindow::MainWindow(QWidget *parent) video_setblit(qt_blit); if (start_in_fullscreen) { - connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this] () { + connect(ui->stackedWidget, &RendererStack::blitToRenderer, this, [this]() { if (start_in_fullscreen) { QTimer::singleShot(100, ui->actionFullscreen, &QAction::trigger); start_in_fullscreen = 0; @@ -820,9 +820,9 @@ MainWindow::MainWindow(QWidget *parent) setContextMenuPolicy(Qt::PreventContextMenu); /* Remove default Shift+F10 handler, which unfocuses keyboard input even with no context menu. */ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - connect(new QShortcut(QKeySequence(Qt::SHIFT | Qt::Key_F10), this), &QShortcut::activated, this, [](){}); + connect(new QShortcut(QKeySequence(Qt::SHIFT | Qt::Key_F10), this), &QShortcut::activated, this, []() {}); #else - connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, [](){}); + connect(new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F10), this), &QShortcut::activated, this, []() {}); #endif connect(this, &MainWindow::initRendererMonitor, this, &MainWindow::initRendererMonitorSlot); @@ -880,18 +880,19 @@ MainWindow::MainWindow(QWidget *parent) else # endif # ifdef WAYLAND - if (QApplication::platformName().contains("wayland")) + if (QApplication::platformName().contains("wayland")) xkbcommon_wl_init(); else # endif - {} + { + } #endif #if defined Q_OS_UNIX && !defined Q_OS_MACOS && !defined Q_OS_HAIKU if (QApplication::platformName().contains("xcb")) { QTimer::singleShot(0, this, [this] { auto whandle = windowHandle(); - if (! whandle) { + if (!whandle) { qWarning() << "No window handle"; } else { QPlatformWindow *window = whandle->handle(); @@ -901,7 +902,7 @@ MainWindow::MainWindow(QWidget *parent) } #endif - updateShortcuts(); + updateShortcuts(); } void @@ -914,7 +915,7 @@ MainWindow::closeEvent(QCloseEvent *event) if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); - auto chkbox = new QCheckBox(tr("Don't show this message again")); + auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); @@ -967,57 +968,57 @@ MainWindow::closeEvent(QCloseEvent *event) event->accept(); } +void +MainWindow::updateShortcuts() +{ + /* + Update menu shortcuts from accelerator table + + Note that these only work in windowed mode. If you add any new shortcuts, + you have to go duplicate them in MainWindow::eventFilter() + */ + + // First we need to wipe all existing accelerators, otherwise Qt will + // run into conflicts with old ones. + ui->actionTake_screenshot->setShortcut(QKeySequence()); + ui->actionCtrl_Alt_Del->setShortcut(QKeySequence()); + ui->actionCtrl_Alt_Esc->setShortcut(QKeySequence()); + ui->actionHard_Reset->setShortcut(QKeySequence()); + ui->actionPause->setShortcut(QKeySequence()); + ui->actionMute_Unmute->setShortcut(QKeySequence()); + + int accID; + QKeySequence seq; + + accID = FindAccelerator("screenshot"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionTake_screenshot->setShortcut(seq); + + accID = FindAccelerator("send_ctrl_alt_del"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionCtrl_Alt_Del->setShortcut(seq); + + accID = FindAccelerator("send_ctrl_alt_esc"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionCtrl_Alt_Esc->setShortcut(seq); + + accID = FindAccelerator("hard_reset"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionHard_Reset->setShortcut(seq); + + accID = FindAccelerator("fullscreen"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionFullscreen->setShortcut(seq); + + accID = FindAccelerator("pause"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionPause->setShortcut(seq); + + accID = FindAccelerator("mute"); + seq = QKeySequence::fromString(acc_keys[accID].seq); + ui->actionMute_Unmute->setShortcut(seq); +} -void MainWindow::updateShortcuts() -{ - /* - Update menu shortcuts from accelerator table - - Note that these only work in windowed mode. If you add any new shortcuts, - you have to go duplicate them in MainWindow::eventFilter() - */ - - // First we need to wipe all existing accelerators, otherwise Qt will - // run into conflicts with old ones. - ui->actionTake_screenshot->setShortcut(QKeySequence()); - ui->actionCtrl_Alt_Del->setShortcut(QKeySequence()); - ui->actionCtrl_Alt_Esc->setShortcut(QKeySequence()); - ui->actionHard_Reset->setShortcut(QKeySequence()); - ui->actionPause->setShortcut(QKeySequence()); - ui->actionMute_Unmute->setShortcut(QKeySequence()); - - int accID; - QKeySequence seq; - - accID = FindAccelerator("screenshot"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionTake_screenshot->setShortcut(seq); - - accID = FindAccelerator("send_ctrl_alt_del"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionCtrl_Alt_Del->setShortcut(seq); - - accID = FindAccelerator("send_ctrl_alt_esc"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionCtrl_Alt_Esc->setShortcut(seq); - - accID = FindAccelerator("hard_reset"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionHard_Reset->setShortcut(seq); - - accID = FindAccelerator("fullscreen"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionFullscreen->setShortcut(seq); - - accID = FindAccelerator("pause"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionPause->setShortcut(seq); - - accID = FindAccelerator("mute"); - seq = QKeySequence::fromString(acc_keys[accID].seq); - ui->actionMute_Unmute->setShortcut(seq); -} - void MainWindow::resizeEvent(QResizeEvent *event) { @@ -1031,30 +1032,32 @@ MainWindow::resizeEvent(QResizeEvent *event) int newY = pos().y(); if (((frameGeometry().x() + event->size().width() + 1) > util::screenOfWidget(this)->availableGeometry().right())) { - //move(util::screenOfWidget(this)->availableGeometry().right() - size().width() - 1, pos().y()); + // move(util::screenOfWidget(this)->availableGeometry().right() - size().width() - 1, pos().y()); newX = util::screenOfWidget(this)->availableGeometry().right() - frameGeometry().width() - 1; - if (newX < 1) newX = 1; + if (newX < 1) + newX = 1; } if (((frameGeometry().y() + event->size().height() + 1) > util::screenOfWidget(this)->availableGeometry().bottom())) { newY = util::screenOfWidget(this)->availableGeometry().bottom() - frameGeometry().height() - 1; - if (newY < 1) newY = 1; + if (newY < 1) + newY = 1; } move(newX, newY); -#endif +#endif /*MOVE_WINDOW*/ } void MainWindow::initRendererMonitorSlot(int monitor_index) { auto &secondaryRenderer = this->renderers[monitor_index]; - secondaryRenderer = std::make_unique(nullptr, monitor_index); + secondaryRenderer = std::make_unique(nullptr, monitor_index); if (secondaryRenderer) { connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] { this->renderers[monitor_index]->show(); }); secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); - secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(monitor_index + 1)); + secondaryRenderer->setWindowTitle(QObject::tr("86Box Monitor #%1").arg(monitor_index + 1)); secondaryRenderer->setContextMenuPolicy(Qt::PreventContextMenu); for (int i = 0; i < this->actions().size(); i++) { @@ -1083,7 +1086,7 @@ MainWindow::initRendererMonitorSlot(int monitor_index) if (monitor_settings[monitor_index].mon_window_maximized) { if (renderers[monitor_index]) renderers[monitor_index]->onResize(renderers[monitor_index]->width(), - renderers[monitor_index]->height()); + renderers[monitor_index]->height()); device_force_redraw(); } @@ -1258,7 +1261,7 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) # ifdef EVDEV_KEYBOARD_HPP keycode = evdev_translate(keycode - 8); # else - keycode = 0; + keycode = 0; # endif #endif @@ -1277,11 +1280,11 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) } break; - case 0x80 ... 0xff: /* regular break codes */ - case 0x10b: /* Microsoft scroll up normal */ + case 0x80 ... 0xff: /* regular break codes */ + case 0x10b: /* Microsoft scroll up normal */ case 0x180 ... 0x1ff: /* E0 break codes (including Microsoft scroll down normal) */ /* This key uses a break code as make. Send it manually, only on press. */ - if (down && (mouse_capture || !kbd_req_capture || video_fullscreen)) { + if (down && (mouse_capture || !kbd_req_capture || (video_fullscreen && !fullscreen_ui_visible))) { if (keycode & 0x100) keyboard_send(0xe0); keyboard_send(keycode & 0xff); @@ -1293,7 +1296,7 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) keycode = 0x38; /* map to Left Alt */ break; - case 0x137: /* Print Screen */ + case 0x137: /* Print Screen */ if (keyboard_recv_ui(0x38) || keyboard_recv_ui(0x138)) { /* Alt+ */ keycode = 0x54; } else if (down) { @@ -1304,7 +1307,7 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) } break; - case 0x145: /* Pause */ + case 0x145: /* Pause */ if (keyboard_recv_ui(0x1d) || keyboard_recv_ui(0x11d)) { /* Ctrl+ */ keycode = 0x146; } else { @@ -1322,15 +1325,15 @@ MainWindow::processKeyboardInput(bool down, uint32_t keycode) // that's followed up with "(really?)". It's the only way to distinguish // left and right modifiers with Qt 6 on macOS, so let's just roll with it. static std::unordered_map mac_modifiers_to_xt = { - {NX_DEVICELCTLKEYMASK, 0x1D }, - { NX_DEVICELSHIFTKEYMASK, 0x2A }, - { NX_DEVICERSHIFTKEYMASK, 0x36 }, - { NX_DEVICELCMDKEYMASK, 0x15B}, - { NX_DEVICERCMDKEYMASK, 0x15C}, - { NX_DEVICELALTKEYMASK, 0x38 }, - { NX_DEVICERALTKEYMASK, 0x138}, - { NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A }, - { NX_DEVICERCTLKEYMASK, 0x11D}, + { NX_DEVICELCTLKEYMASK, 0x1D }, + { NX_DEVICELSHIFTKEYMASK, 0x2A }, + { NX_DEVICERSHIFTKEYMASK, 0x36 }, + { NX_DEVICELCMDKEYMASK, 0x15B }, + { NX_DEVICERCMDKEYMASK, 0x15C }, + { NX_DEVICELALTKEYMASK, 0x38 }, + { NX_DEVICERALTKEYMASK, 0x138 }, + { NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A }, + { NX_DEVICERCTLKEYMASK, 0x11D }, }; static bool mac_iso_swap = false; @@ -1391,45 +1394,44 @@ MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) - Romanian third level ANSI_Grave is unknown - Russian clusters <>, plusminus and paragraph into a four-level ANSI_Grave, with the aforementioned `~ on ISO_Section */ auto key = event->key(); - if ((nvk == 0x32) && ( /* system reports ANSI_Grave for ISO_Section keys: */ - (key == Qt::Key_Less) || (key == Qt::Key_Greater) || /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */ - (key == Qt::Key_Ugrave) || /* French Canadian */ - (key == Qt::Key_Icircumflex) || /* Romanian */ - (key == Qt::Key_Iacute) || /* Hungarian */ - (key == Qt::Key_BracketLeft) || (key == Qt::Key_BracketRight) || /* Russian upper two levels */ - (key == Qt::Key_W) /* Turkish F */ - )) + if ((nvk == 0x32) && ( /* system reports ANSI_Grave for ISO_Section keys: */ + (key == Qt::Key_Less) || (key == Qt::Key_Greater) || /* Croatian, French, German, Icelandic, Italian, Norwegian, Portuguese, Spanish, Spanish Latin America, Turkish Q */ + (key == Qt::Key_Ugrave) || /* French Canadian */ + (key == Qt::Key_Icircumflex) || /* Romanian */ + (key == Qt::Key_Iacute) || /* Hungarian */ + (key == Qt::Key_BracketLeft) || (key == Qt::Key_BracketRight) || /* Russian upper two levels */ + (key == Qt::Key_W) /* Turkish F */ + )) mac_iso_swap = true; - else if ((nvk == 0x0a) && ( /* system reports ISO_Section for ANSI_Grave keys: */ - (key == Qt::Key_paragraph) || (key == Qt::Key_plusminus) || /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */ - (key == Qt::Key_At) || (key == Qt::Key_NumberSign) || /* Belgian, French */ - (key == Qt::Key_Apostrophe) || /* Brazilian unshifted */ - (key == Qt::Key_QuoteDbl) || /* Brazilian shifted, Turkish Q unshifted */ - (key == Qt::Key_QuoteLeft) || /* Croatian (right quote unknown) */ - (key == Qt::Key_Dollar) || /* Danish unshifted */ - (key == Qt::Key_AsciiCircum) || (key == 0x1ffffff) || /* German unshifted (0x1ffffff according to one tester), Polish unshifted */ - (key == Qt::Key_degree) || /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */ - (key == Qt::Key_0) || /* Hungarian unshifted */ - (key == Qt::Key_diaeresis) || /* Icelandic shifted */ - (key == Qt::Key_acute) || /* Norwegian unshifted */ - (key == Qt::Key_Asterisk) || /* Polish shifted */ - (key == Qt::Key_masculine) || (key == Qt::Key_ordfeminine) || /* Spanish (masculine unconfirmed) */ - (key == Qt::Key_Eacute) || /* Turkish Q shifted */ - (key == Qt::Key_Slash) /* French Canadian unshifted, Ukrainian shifted */ - )) + else if ((nvk == 0x0a) && ( /* system reports ISO_Section for ANSI_Grave keys: */ + (key == Qt::Key_paragraph) || (key == Qt::Key_plusminus) || /* Arabic, British, Bulgarian, Danish shifted, Dutch, Greek, Hebrew, Hungarian shifted, International English, Norwegian shifted, Portuguese, Russian lower two levels, Swiss unshifted, Swedish unshifted, Turkish F */ + (key == Qt::Key_At) || (key == Qt::Key_NumberSign) || /* Belgian, French */ + (key == Qt::Key_Apostrophe) || /* Brazilian unshifted */ + (key == Qt::Key_QuoteDbl) || /* Brazilian shifted, Turkish Q unshifted */ + (key == Qt::Key_QuoteLeft) || /* Croatian (right quote unknown) */ + (key == Qt::Key_Dollar) || /* Danish unshifted */ + (key == Qt::Key_AsciiCircum) || (key == 0x1ffffff) || /* German unshifted (0x1ffffff according to one tester), Polish unshifted */ + (key == Qt::Key_degree) || /* German shifted, Icelandic unshifted, Spanish Latin America shifted, Swiss shifted, Swedish shifted */ + (key == Qt::Key_0) || /* Hungarian unshifted */ + (key == Qt::Key_diaeresis) || /* Icelandic shifted */ + (key == Qt::Key_acute) || /* Norwegian unshifted */ + (key == Qt::Key_Asterisk) || /* Polish shifted */ + (key == Qt::Key_masculine) || (key == Qt::Key_ordfeminine) || /* Spanish (masculine unconfirmed) */ + (key == Qt::Key_Eacute) || /* Turkish Q shifted */ + (key == Qt::Key_Slash) /* French Canadian unshifted, Ukrainian shifted */ + )) mac_iso_swap = true; -#if 0 +# if 0 if (down) { QMessageBox questionbox(QMessageBox::Icon::Information, QString("Mac key swap test"), QString("nativeVirtualKey 0x%1\nnativeScanCode 0x%2\nkey 0x%3\nmac_iso_swap %4").arg(nvk, 0, 16).arg(event->nativeScanCode(), 0, 16).arg(key, 0, 16).arg(mac_iso_swap ? "yes" : "no"), QMessageBox::Ok, this); questionbox.exec(); } -#endif +# endif if (mac_iso_swap) nvk = (nvk == 0x0a) ? 0x32 : 0x0a; } // Special case for command + forward delete to send insert. - if ((event->nativeModifiers() & NSEventModifierFlagCommand) && - ((event->nativeVirtualKey() == nvk_Delete) || event->key() == Qt::Key_Delete)) { + if ((event->nativeModifiers() & NSEventModifierFlagCommand) && ((event->nativeVirtualKey() == nvk_Delete) || event->key() == Qt::Key_Delete)) { nvk = nvk_Insert; // Qt::Key_Help according to event->key() } @@ -1449,6 +1451,7 @@ MainWindow::on_actionFullscreen_triggered() if (!hide_tool_bar) ui->toolBar->show(); video_fullscreen = 0; + fullscreen_ui_visible = 0; if (vid_resize != 1) { emit resizeContents(vid_resize == 2 ? fixed_size_x : monitors[0].mon_scrnsz_x, vid_resize == 2 ? fixed_size_y : monitors[0].mon_scrnsz_y); } @@ -1461,7 +1464,7 @@ MainWindow::on_actionFullscreen_triggered() ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); } - fs_on_signal = false; + fs_on_signal = false; fs_off_signal = false; ui->stackedWidget->onResize(width(), height()); } @@ -1482,85 +1485,75 @@ MainWindow::getTitle(wchar_t *title) } } - // Helper to find an accelerator key and return it's sequence // TODO: Is there a more central place to put this? QKeySequence MainWindow::FindAcceleratorSeq(const char *name) { - int accID = FindAccelerator(name); - if(accID == -1) - return false; - - return(QKeySequence::fromString(acc_keys[accID].seq)); + int accID = FindAccelerator(name); + if (accID == -1) + return false; + + return (QKeySequence::fromString(acc_keys[accID].seq)); } bool MainWindow::eventFilter(QObject *receiver, QEvent *event) { - // Detect shortcuts when menubar is hidden - // TODO: Could this be simplified by proxying the event and manually - // shoving it into the menubar? - if (event->type() == QEvent::KeyPress) - { - this->keyPressEvent((QKeyEvent *) event); - - // We check for mouse release even if we aren't fullscreen, - // because it's not a menu accelerator. - if (event->type() == QEvent::KeyPress) - { - QKeyEvent *ke = (QKeyEvent *) event; - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("release_mouse") || - (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("release_mouse")) - { - plat_mouse_capture(0); - } - } - - if (event->type() == QEvent::KeyPress && video_fullscreen != 0) - { - QKeyEvent *ke = (QKeyEvent *) event; - - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("screenshot") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("screenshot")) - { - ui->actionTake_screenshot->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("fullscreen") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("fullscreen")) - { - ui->actionFullscreen->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("hard_reset") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("hard_reset")) - { - ui->actionHard_Reset->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("send_ctrl_alt_del") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("send_ctrl_alt_del")) - { - ui->actionCtrl_Alt_Del->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("send_ctrl_alt_esc") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("send_ctrl_alt_esc")) - { - ui->actionCtrl_Alt_Esc->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("pause") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("pause")) - { - ui->actionPause->trigger(); - } - if ((QKeySequence)(ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("mute") - || (QKeySequence)(ke->key() | ke->modifiers()) == FindAcceleratorSeq("mute")) - { - ui->actionMute_Unmute->trigger(); - } - - return true; - } - } - + // Detect shortcuts when menubar is hidden + // TODO: Could this be simplified by proxying the event and manually + // shoving it into the menubar? + if (event->type() == QEvent::KeyPress) { + this->keyPressEvent((QKeyEvent *) event); + + // We check for mouse release even if we aren't fullscreen, + // because it's not a menu accelerator. + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = (QKeyEvent *) event; + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("release_mouse") || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("release_mouse")) { + plat_mouse_capture(0); + } + } + + if (event->type() == QEvent::KeyPress && video_fullscreen != 0) { + QKeyEvent *ke = (QKeyEvent *) event; + + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("screenshot") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("screenshot")) { + ui->actionTake_screenshot->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("fullscreen") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("fullscreen")) { + ui->actionFullscreen->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("hard_reset") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("hard_reset")) { + ui->actionHard_Reset->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("send_ctrl_alt_del") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("send_ctrl_alt_del")) { + ui->actionCtrl_Alt_Del->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("send_ctrl_alt_esc") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("send_ctrl_alt_esc")) { + ui->actionCtrl_Alt_Esc->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("pause") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("pause")) { + ui->actionPause->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("mute") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("mute")) { + ui->actionMute_Unmute->trigger(); + } + if ((QKeySequence) (ke->key() | (ke->modifiers() & ~Qt::KeypadModifier)) == FindAcceleratorSeq("toggle_ui_fullscreen") + || (QKeySequence) (ke->key() | ke->modifiers()) == FindAcceleratorSeq("toggle_ui_fullscreen")) { + toggleFullscreenUI(); + } + + return true; + } + } if (!dopause && (!kbd_req_capture || mouse_capture)) { if (event->type() == QEvent::Shortcut) { @@ -1571,8 +1564,8 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event) } } if (event->type() == QEvent::KeyPress) { - event->accept(); - + event->accept(); + return true; } if (event->type() == QEvent::KeyRelease) { @@ -1586,7 +1579,7 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event) static auto curdopause = dopause; if (event->type() == QEvent::WindowBlocked) { window_blocked = true; - curdopause = dopause; + curdopause = dopause; plat_pause(isNonPause ? dopause : (isShowMessage ? 2 : 1)); emit setMouseCapture(false); releaseKeyboard(); @@ -1595,7 +1588,7 @@ MainWindow::eventFilter(QObject *receiver, QEvent *event) plat_pause(curdopause); } } - + return QMainWindow::eventFilter(receiver, event); } @@ -1615,15 +1608,16 @@ MainWindow::refreshMediaMenu() caps_label->setToolTip(QShortcut::tr("Caps Lock")); caps_label->setVisible(machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD)); kana_label->setToolTip(QShortcut::tr("Kana Lock")); - int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && - (keyboard_type == KEYBOARD_TYPE_AX); - int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && - !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); + int ext_ax_kbd = machine_has_bus(machine, MACHINE_BUS_PS2_PORTS | MACHINE_BUS_AT_KBD) && (keyboard_type == KEYBOARD_TYPE_AX); + int int_ax_kbd = machine_has_flags(machine, MACHINE_KEYBOARD_JIS) && !machine_has_bus(machine, MACHINE_BUS_PS2_PORTS); kana_label->setVisible(ext_ax_kbd || int_ax_kbd); bool enable_comp_option = false; for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].mon_composite) { enable_comp_option = true; break; } + if (monitors[i].mon_composite) { + enable_comp_option = true; + break; + } } ui->actionCGA_composite_settings->setEnabled(enable_comp_option); @@ -1635,12 +1629,11 @@ MainWindow::showMessage(int flags, const QString &header, const QString &message if (QThread::currentThread() == this->thread()) { if (!cpu_thread_running) { showMessageForNonQtThread(flags, header, message, richText, nullptr); - } - else + } else showMessage_(flags, header, message, richText); } else { std::atomic_bool done = false; - emit showMessageForNonQtThread(flags, header, message, richText, &done); + emit showMessageForNonQtThread(flags, header, message, richText, &done); while (!done) { QThread::msleep(1); } @@ -1681,7 +1674,7 @@ MainWindow::keyPressEvent(QKeyEvent *event) processKeyboardInput(true, event->nativeScanCode()); #endif } - + event->accept(); } @@ -1724,13 +1717,13 @@ MainWindow::getRenderWidgetSize() void MainWindow::focusInEvent(QFocusEvent *event) { - //this->grabKeyboard(); + // this->grabKeyboard(); } void MainWindow::focusOutEvent(QFocusEvent *event) { - //this->releaseKeyboard(); + // this->releaseKeyboard(); } void @@ -2205,11 +2198,37 @@ MainWindow::on_actionUpdate_status_bar_icons_triggered() status->clearActivity(); } +void +MainWindow::toggleFullscreenUI() +{ + if (video_fullscreen == 0) + return; + + fullscreen_ui_visible ^= 1; + + if (fullscreen_ui_visible) { + // UI is being shown - save mouse capture state and release if captured + mouse_was_captured = (mouse_capture != 0); + if (mouse_was_captured) { + plat_mouse_capture(0); + } + } else { + // UI is being hidden - restore previous mouse capture state + if (mouse_was_captured) { + plat_mouse_capture(1); + } + } + + ui->menubar->setVisible(fullscreen_ui_visible); + ui->statusbar->setVisible(fullscreen_ui_visible && !hide_status_bar); + ui->toolBar->setVisible(fullscreen_ui_visible && !hide_tool_bar); +} + void MainWindow::on_actionTake_screenshot_triggered() { startblit(); - for (auto & monitor : monitors) + for (auto &monitor : monitors) ++monitor.mon_screenshots; endblit(); device_force_redraw(); @@ -2240,16 +2259,13 @@ MainWindow::setSendKeyboardInput(bool enabled) void MainWindow::updateUiPauseState() { - const auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : - QIcon(":/menuicons/qt/icons/pause.ico"); - const auto tooltip_text = dopause ? QString(tr("Resume execution")) : - QString(tr("Pause execution")); - const auto menu_text = dopause ? QString(tr("Re&sume")) : - QString(tr("&Pause")); + const auto pause_icon = dopause ? QIcon(":/menuicons/qt/icons/run.ico") : QIcon(":/menuicons/qt/icons/pause.ico"); + const auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); + const auto menu_text = dopause ? QString(tr("Re&sume")) : QString(tr("&Pause")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); ui->actionPause->setText(menu_text); - emit vmmRunningStateChanged(static_cast(window_blocked ? (dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting) : (VMManagerProtocol::RunningState)dopause)); + emit vmmRunningStateChanged(static_cast(window_blocked ? (dopause ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting) : (VMManagerProtocol::RunningState) dopause)); } void @@ -2345,10 +2361,11 @@ MainWindow::on_actionRenderer_options_triggered() } } } - } else for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i] && renderers[i]->hasOptions()) - renderers[i]->reloadOptions(); - } + } else + for (int i = 1; i < MONITORS_NUM; i++) { + if (renderers[i] && renderers[i]->hasOptions()) + renderers[i]->reloadOptions(); + } } else if (reload_renderers && ui->stackedWidget->reloadRendererOption()) { reload_renderers = false; ui->stackedWidget->switchRenderer(static_cast(vid_api)); @@ -2437,24 +2454,28 @@ MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool config_save(); } -void MainWindow::on_actionCursor_Puck_triggered() +void +MainWindow::on_actionCursor_Puck_triggered() { tablet_tool_type = 0; config_save(); } -void MainWindow::on_actionPen_triggered() +void +MainWindow::on_actionPen_triggered() { tablet_tool_type = 1; config_save(); } -void MainWindow::on_actionACPI_Shutdown_triggered() +void +MainWindow::on_actionACPI_Shutdown_triggered() { acpi_pwrbut_pressed = 1; } -void MainWindow::on_actionCGA_composite_settings_triggered() +void +MainWindow::on_actionCGA_composite_settings_triggered() { isNonPause = true; CGASettingsDialog dialog; @@ -2463,4 +2484,3 @@ void MainWindow::on_actionCGA_composite_settings_triggered() isNonPause = false; config_save(); } - diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 26585ddaf94..1a1cf4f2037 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -33,16 +33,15 @@ class MainWindow : public QMainWindow { explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); - void showMessage(int flags, const QString &header, const QString &message, bool richText); - void getTitle(wchar_t *title); - void blitToWidget(int x, int y, int w, int h, int monitor_index); - QSize getRenderWidgetSize(); - void setSendKeyboardInput(bool enabled); - void reloadAllRenderers(); - QShortcut *windowedShortcut; - QKeySequence FindAcceleratorSeq(const char *name); - - + void showMessage(int flags, const QString &header, const QString &message, bool richText); + void getTitle(wchar_t *title); + void blitToWidget(int x, int y, int w, int h, int monitor_index); + QSize getRenderWidgetSize(); + void setSendKeyboardInput(bool enabled); + void reloadAllRenderers(); + QShortcut *windowedShortcut; + QKeySequence FindAcceleratorSeq(const char *name); + std::array, 8> renderers; signals: void paint(const QImage &image); @@ -65,7 +64,7 @@ class MainWindow : public QMainWindow { void setFullscreen(bool state); void setMouseCapture(bool state); - void showMessageForNonQtThread(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool* done); + void showMessageForNonQtThread(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool *done); void getTitleForNonQtThread(wchar_t *title); void vmmRunningStateChanged(VMManagerProtocol::RunningState state); @@ -131,6 +130,7 @@ private slots: void on_actionHide_tool_bar_triggered(); void on_actionUpdate_status_bar_icons_triggered(); void on_actionTake_screenshot_triggered(); + void toggleFullscreenUI(); void on_actionMute_Unmute_triggered(); void on_actionSound_gain_triggered(); void on_actionPreferences_triggered(); @@ -138,7 +138,7 @@ private slots: void on_actionRenderer_options_triggered(); void refreshMediaMenu(); - void showMessage_(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool* done = nullptr); + void showMessage_(int flags, const QString &header, const QString &message, bool richText, std::atomic_bool *done = nullptr); void getTitle_(wchar_t *title); void on_actionMCA_devices_triggered(); @@ -178,8 +178,8 @@ private slots: std::unique_ptr status; std::shared_ptr mm; - void updateShortcuts(); - void processKeyboardInput(bool down, uint32_t keycode); + void updateShortcuts(); + void processKeyboardInput(bool down, uint32_t keycode); #ifdef Q_OS_MACOS uint32_t last_modifiers = 0; void processMacKeyboardInput(bool down, const QKeyEvent *event); @@ -192,24 +192,27 @@ private slots: bool vnc_enabled = false; /* Full screen ON and OFF signals */ - bool fs_on_signal = false; - bool fs_off_signal = false; + bool fs_on_signal = false; + bool fs_off_signal = false; /* Reload the renderers after closing renderer options dialog. */ - bool reload_renderers = false; + bool reload_renderers = false; + + /* Mouse capture state before showing fullscreen UI */ + bool mouse_was_captured = false; friend class SpecifyDimensions; friend class ProgSettings; friend class RendererCommon; - friend class RendererStack; // For UI variable access by non-primary renderer windows. + friend class RendererStack; // For UI variable access by non-primary renderer windows. friend class WindowsRawInputFilter; // Needed to reload renderers on style sheet changes. QLabel *caps_label, *scroll_label, *num_label, *kana_label; - QIcon caps_icon, scroll_icon, num_icon, kana_icon; - QIcon caps_icon_off, scroll_icon_off, num_icon_off, kana_icon_off; + QIcon caps_icon, scroll_icon, num_icon, kana_icon; + QIcon caps_icon_off, scroll_icon_off, num_icon_off, kana_icon_off; - bool isShowMessage = false; - bool isNonPause = false; + bool isShowMessage = false; + bool isNonPause = false; bool window_blocked = false; }; diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 38aba061fba..45c4f70ae08 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -260,7 +260,7 @@ - Qt::ContextMenuPolicy::PreventContextMenu + Qt::PreventContextMenu toolBar @@ -272,7 +272,7 @@ false - Qt::ToolBarArea::TopToolBarArea + Qt::TopToolBarArea @@ -281,7 +281,7 @@ - Qt::ToolButtonStyle::ToolButtonIconOnly + Qt::ToolButtonIconOnly false @@ -396,7 +396,7 @@ E&xit - QAction::MenuRole::QuitRole + QAction::QuitRole @@ -408,7 +408,7 @@ &Settings... - QAction::MenuRole::NoRole + QAction::NoRole false @@ -710,7 +710,7 @@ false - QAction::MenuRole::AboutQtRole + QAction::AboutQtRole @@ -718,7 +718,7 @@ &About 86Box... - QAction::MenuRole::AboutRole + QAction::AboutRole @@ -771,7 +771,7 @@ &Preferences... - QAction::MenuRole::PreferencesRole + QAction::PreferencesRole @@ -844,7 +844,7 @@ Renderer &options... - QAction::MenuRole::NoRole + QAction::NoRole diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index a7892af312a..c75c05f9b74 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -19,7 +19,7 @@ #include #include "qt_mediahistorymanager.hpp" #ifdef Q_OS_WINDOWS -#include +# include #endif extern "C" { @@ -371,7 +371,7 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) path_normalize(temp); } - QString qstr = QString::fromUtf8(temp); + QString qstr = QString::fromUtf8(temp); QFileInfo new_fi(qstr); bool file_exists = new_fi.exists(); diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index e63327fd842..75b2e2b978a 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -28,10 +28,10 @@ extern "C" { #ifdef Q_OS_WINDOWS -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP +# define BITMAP WINDOWS_BITMAP +# include +# include +# undef BITMAP #endif #include #include @@ -70,7 +70,7 @@ extern "C" { std::shared_ptr MediaMenu::ptr; -static QSize pixmap_size(16, 16); +static QSize pixmap_size(16, 16); MediaMenu::MediaMenu(QWidget *parent) : QObject(parent) @@ -85,7 +85,7 @@ MediaMenu::refresh(QMenu *parentMenu) parentMenu->clear(); if (MachineStatus::hasCassette()) { - cassetteMenu = parentMenu->addMenu(""); + cassetteMenu = parentMenu->addMenu(""); QIcon img_icon = QIcon(":/settings/qt/icons/cassette_image.ico"); cassetteMenu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this]() { cassetteNewImage(); }); cassetteMenu->addSeparator(); @@ -114,7 +114,7 @@ MediaMenu::refresh(QMenu *parentMenu) cartridgeMenus.clear(); if (machine_has_cartridge(machine)) { for (int i = 0; i < 2; i++) { - auto *menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); QIcon img_icon = QIcon(":/settings/qt/icons/cartridge_image.ico"); menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); @@ -132,9 +132,8 @@ MediaMenu::refresh(QMenu *parentMenu) floppyMenus.clear(); MachineStatus::iterateFDD([this, parentMenu](int i) { - auto *menu = parentMenu->addMenu(""); - QIcon img_icon = fdd_is_525(i) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : - QIcon(":/settings/qt/icons/floppy_35_image.ico"); + auto *menu = parentMenu->addMenu(""); + QIcon img_icon = fdd_is_525(i) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : QIcon(":/settings/qt/icons/floppy_35_image.ico"); menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { floppyNewImage(i); }); menu->addSeparator(); menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, Browse), tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); @@ -186,7 +185,7 @@ MediaMenu::refresh(QMenu *parentMenu) rdiskMenus.clear(); MachineStatus::iterateRDisk([this, parentMenu](int i) { - auto *menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); QIcon img_icon = QIcon(":/settings/qt/icons/rdisk_image.ico"); menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { rdiskNewImage(i); }); menu->addSeparator(); @@ -206,7 +205,7 @@ MediaMenu::refresh(QMenu *parentMenu) moMenus.clear(); MachineStatus::iterateMO([this, parentMenu](int i) { - auto *menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); QIcon img_icon = QIcon(":/settings/qt/icons/mo_image.ico"); menu->addAction(getIconWithIndicator(img_icon, pixmap_size, QIcon::Normal, New), tr("&New image..."), [this, i]() { moNewImage(i); }); menu->addSeparator(); @@ -316,15 +315,15 @@ MediaMenu::cassetteEject() void MediaMenu::cassetteUpdateMenu() { - QString name = cassette_fname; - QFileInfo fi(cassette_fname); - const 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]); + QString name = cassette_fname; + QFileInfo fi(cassette_fname); + const 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()); @@ -400,9 +399,9 @@ MediaMenu::cartridgeUpdateMenu(int i) { const QString name = cart_fns[i]; QFileInfo fi(cart_fns[i]); - auto *menu = cartridgeMenus[i]; - auto childs = menu->children(); - auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); + auto *menu = cartridgeMenus[i]; + auto childs = menu->children(); + auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); menu->setTitle(tr("Car&tridge %1: %2").arg(QString::number(i + 1), name.isEmpty() ? tr("(empty)") : name)); @@ -447,7 +446,8 @@ MediaMenu::floppySelectImage(int i, bool wp) tr("All files") % util::DlgFilter({ "*" }, true)); - if (!filename.isEmpty()) floppyMount(i, filename, wp); + if (!filename.isEmpty()) + floppyMount(i, filename, wp); } void @@ -525,7 +525,6 @@ MediaMenu::floppyUpdateMenu(int i) 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]->setToolTip(tr("Floppy %1 (%2): %3").arg(QString::number(i + 1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); - } void @@ -597,7 +596,7 @@ MediaMenu::cdromMount(int i, int dir, const QString &arg) else { filename = QFileDialog::getOpenFileName(parentWidget, QString(), QString(), - tr("CD-ROM images") % util::DlgFilter({ "iso", "cue", "mds" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue", "mds" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } if (filename.isEmpty()) @@ -649,7 +648,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) QObjectList children; QFileInfo fi; QIcon menu_icon; - const auto fn = mhm.getImageForSlot(index, slot, type); + const auto fn = mhm.getImageForSlot(index, slot, type); QString menu_item_name; @@ -691,8 +690,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) menu = floppyMenus[index]; children = menu->children(); imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); - menu_icon = fdd_is_525(index) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : - QIcon(":/settings/qt/icons/floppy_35_image.ico"); + menu_icon = fdd_is_525(index) ? QIcon(":/settings/qt/icons/floppy_525_image.ico") : QIcon(":/settings/qt/icons/floppy_35_image.ico"); if (fn.left(5) == "wp://") fi.setFile(fn.right(fn.length() - 5)); else @@ -720,7 +718,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) #endif } else { fi.setFile(fn); - menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); + menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); menu_item_name = fn.isEmpty() ? tr("Reload previous image") : fn; } imageHistoryUpdatePos->setIcon(menu_icon); @@ -770,7 +768,7 @@ MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) imageHistoryUpdatePos->setText(menu_item_name.prepend("&%1 ").arg((slot == 9) ? 0 : (slot + 1))); else #endif - imageHistoryUpdatePos->setText(menu_item_name); + imageHistoryUpdatePos->setText(menu_item_name); if (fn.left(8) == "ioctl://") imageHistoryUpdatePos->setVisible(true); @@ -788,9 +786,9 @@ MediaMenu::clearImageHistory() void MediaMenu::cdromUpdateMenu(int i) { - QString name = cdrom[i].image_path; - QString name2; - QIcon menu_icon; + QString name = cdrom[i].image_path; + QString name2; + QIcon menu_icon; if (!cdromMenus.contains(i)) return; @@ -810,17 +808,17 @@ MediaMenu::cdromUpdateMenu(int i) #else menu_item_name = tr("Host CD/DVD Drive (%1)").arg(name.right(name.length() - 8)); #endif - name2 = menu_item_name; - menu_icon = QIcon(":/settings/qt/icons/cdrom_host.ico"); + name2 = menu_item_name; + menu_icon = QIcon(":/settings/qt/icons/cdrom_host.ico"); } else { QFileInfo fi(cdrom[i].image_path); menu_item_name = name.isEmpty() ? QString() : fi.fileName(); name2 = name; if (name.isEmpty()) - menu_icon = QIcon(":/settings/qt/icons/cdrom.ico"); + menu_icon = QIcon(":/settings/qt/icons/cdrom.ico"); else - menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); + menu_icon = fi.isDir() ? QIcon(":/settings/qt/icons/cdrom_folder.ico") : QIcon(":/settings/qt/icons/cdrom_image.ico"); } ejectMenu->setIcon(getIconWithIndicator(menu_icon, pixmap_size, QIcon::Normal, Eject)); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(menu_item_name)); @@ -846,8 +844,8 @@ MediaMenu::cdromUpdateMenu(int i) break; } - menu->setTitle(tr("&CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); - menu->setToolTip(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name2)); + menu->setTitle(tr("&CD-ROM %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name2)); + menu->setToolTip(tr("CD-ROM %1 (%2): %3").arg(QString::number(i + 1), busName, name.isEmpty() ? tr("(empty)") : name2)); } void @@ -970,7 +968,7 @@ MediaMenu::moUpdateMenu(int i) auto *menu = moMenus[i]; auto childs = menu->children(); - auto *ejectMenu = dynamic_cast(childs[moEjectPos]); + auto *ejectMenu = dynamic_cast(childs[moEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); @@ -1004,7 +1002,7 @@ MediaMenu::rdiskUpdateMenu(int i) auto *menu = rdiskMenus[i]; auto childs = menu->children(); - auto *ejectMenu = dynamic_cast(childs[rdiskEjectPos]); + auto *ejectMenu = dynamic_cast(childs[rdiskEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); ejectMenu->setText(name.isEmpty() ? tr("E&ject") : tr("E&ject %1").arg(fi.fileName())); diff --git a/src/qt/qt_midi.cpp b/src/qt/qt_midi.cpp index 40fbfb460f9..0d1b17066a7 100644 --- a/src/qt/qt_midi.cpp +++ b/src/qt/qt_midi.cpp @@ -69,5 +69,4 @@ plat_midi_in_get_dev_name(int num, char *s) s[0] = ' '; s[1] = 0; } - } diff --git a/src/qt/qt_models_common.hpp b/src/qt/qt_models_common.hpp index 7e116523f8c..98674a68ff7 100644 --- a/src/qt/qt_models_common.hpp +++ b/src/qt/qt_models_common.hpp @@ -3,5 +3,5 @@ class QString; class QAbstractItemModel; namespace Models { - int AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole); +int AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole); }; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 6712b22f393..98078004a40 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -83,7 +83,7 @@ static const disk_size_t disk_sizes[14] = { { 0, 8, 0, 0, 0, 963, 32, 2, 0, 0, 0, 0, 0 }, /* LS-120 */ { 0, 32, 0, 0, 0, 262, 56, 2, 0, 0, 0, 0, 0 } /* LS-240 */ #endif -// clang-format on + // clang-format on }; static const QStringList rpmModes = { @@ -198,7 +198,7 @@ NewFloppyDialog::onCreate() QFileInfo fi(filename); filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? (usr_path + fi.filePath()) : fi.filePath(); ui->fileField->setFileName(filename); - FileType fileType; + FileType fileType; QProgressDialog progress("Creating floppy image", QString(), 0, 100, this); connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue); @@ -646,8 +646,8 @@ NewFloppyDialog::createRDiskSectorImage(const QString &filename, const disk_size bool NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar) { - const mo_type_t *dp = &mo_types[disk_size]; - uint64_t total_size = 0; + const mo_type_t *dp = &mo_types[disk_size]; + uint64_t total_size = 0; uint64_t total_size2; uint32_t total_sectors = 0; uint32_t sector_bytes = 0; diff --git a/src/qt/qt_newfloppydialog.ui b/src/qt/qt_newfloppydialog.ui index c0437d81021..98bfd8be4bc 100644 --- a/src/qt/qt_newfloppydialog.ui +++ b/src/qt/qt_newfloppydialog.ui @@ -27,7 +27,7 @@ - + File name: @@ -44,7 +44,7 @@ - + Disk size: diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index c8c2e2fc624..8e01bfe6c1c 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -21,7 +21,7 @@ #include "qt_renderercommon.hpp" #include "qt_mainwindow.hpp" -extern MainWindow* main_window; +extern MainWindow *main_window; #include #include @@ -42,6 +42,8 @@ extern MainWindow* main_window; #include #include +#include +#define HAVE_STDARG_H #include "qt_openglrenderer.hpp" #include "qt_openglshadermanagerdialog.hpp" @@ -56,7 +58,7 @@ extern "C" { #include <86box/config.h> #include <86box/qt-glslp-parser.h> -char gl3_shader_file[MAX_USER_SHADERS][512]; +char gl3_shader_file[MAX_USER_SHADERS][512]; extern bool cpu_thread_running; } @@ -71,76 +73,76 @@ extern int video_vsync; extern int video_focus_dim; extern int video_refresh_rate; -const char* vertex_shader_default_tex_src = +const char *vertex_shader_default_tex_src = #ifdef __APPLE__ - "#version 150\n" + "#version 150\n" #else - "#version 130\n" + "#version 130\n" #endif - "\n" - "in vec4 VertexCoord;\n" - "in vec2 TexCoord;\n" - "\n" - "out vec2 texCoord;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " texCoord = TexCoord;\n" - "}\n"; - -const char* fragment_shader_default_tex_src = + "\n" + "in vec4 VertexCoord;\n" + "in vec2 TexCoord;\n" + "\n" + "out vec2 texCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " texCoord = TexCoord;\n" + "}\n"; + +const char *fragment_shader_default_tex_src = #ifdef __APPLE__ - "#version 150\n" + "#version 150\n" #else - "#version 130\n" + "#version 130\n" #endif - "\n" - "in vec2 texCoord;\n" - "uniform sampler2D Texture;\n" - "\n" - "out vec4 color;" - "\n" - "void main()\n" - "{\n" - " color = texture(Texture, texCoord);\n" - " color.a = 1.0;\n" - "}\n"; - -const char* vertex_shader_default_color_src = + "\n" + "in vec2 texCoord;\n" + "uniform sampler2D Texture;\n" + "\n" + "out vec4 color;" + "\n" + "void main()\n" + "{\n" + " color = texture(Texture, texCoord);\n" + " color.a = 1.0;\n" + "}\n"; + +const char *vertex_shader_default_color_src = #ifdef __APPLE__ - "#version 150\n" + "#version 150\n" #else - "#version 130\n" + "#version 130\n" #endif - "\n" - "in vec4 VertexCoord;\n" - "in vec4 Color;\n" - "\n" - "out vec4 color;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " color = Color;\n" - "}\n"; - -const char* fragment_shader_default_color_src = + "\n" + "in vec4 VertexCoord;\n" + "in vec4 Color;\n" + "\n" + "out vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " color = Color;\n" + "}\n"; + +const char *fragment_shader_default_color_src = #ifdef __APPLE__ - "#version 150\n" + "#version 150\n" #else - "#version 130\n" + "#version 130\n" #endif - "\n" - "in vec4 color;\n" - "\n" - "out vec4 outColor;" - "\n" - "void main()\n" - "{\n" - " outColor = color;\n" - " outColor.a = 1.0;\n" - "}\n"; + "\n" + "in vec4 color;\n" + "\n" + "out vec4 outColor;" + "\n" + "void main()\n" + "{\n" + " outColor = color;\n" + " outColor.a = 1.0;\n" + "}\n"; #ifdef ENABLE_OGL3_LOG int ogl3_do_log = ENABLE_OGL3_LOG; @@ -152,7 +154,7 @@ ogl3_log(const char *fmt, ...) if (ogl3_do_log) { va_start(ap, fmt); - ogl3_log_ex(fmt, ap); + pclog_ex(fmt, ap); va_end(ap); } } @@ -210,19 +212,16 @@ int OpenGLRenderer::compile_shader(GLenum shader_type, const char *prepend, const char *program, int *dst) { QRegularExpression versionRegex("^\\s*(#version\\s+\\w+)", QRegularExpression::MultilineOption); - QString progSource = QString(program); - QByteArray finalSource = nullptr; - const char *source[5]; - char version[50]; - char *version_loc = (char *) strstr(program, "#version"); + QString progSource = QString(program); + QByteArray finalSource = nullptr; + const char *source[5]; + char version[50]; + char *version_loc = (char *) strstr(program, "#version"); if (version_loc) { snprintf(version, 49, "%s\n", versionRegex.match(progSource).captured(1).toLatin1().data()); progSource.remove(versionRegex); } else { - version_loc = ((char *) this->glslVersion.toLatin1().data()) + 9; - char glsl_ver[4] = { 0 }; - memcpy(glsl_ver, version_loc, 3); - int ver = atoi((char *) glsl_ver); + int ver = gl_version[0] * 100 + gl_version[1] * 10; if (ver == 300) ver = 130; else if (ver == 310) @@ -231,7 +230,7 @@ OpenGLRenderer::compile_shader(GLenum shader_type, const char *prepend, const ch ver = 150; snprintf(version, 49, "#version %d\n", ver); } - + /* Remove parameter lines. */ progSource.remove(QRegularExpression("^\\s*#pragma parameter.*?\\n", QRegularExpression::MultilineOption)); @@ -310,27 +309,27 @@ OpenGLRenderer::find_uniforms(struct glsl_shader *glsl, int num_pass) u->orig.texture_size = get_uniform(p, "OrigTextureSize"); for (i = 0; i < glsl->num_passes; ++i) { - snprintf(s, sizeof(s) -1, "Pass%dTexture", (i + 1)); + snprintf(s, sizeof(s) - 1, "Pass%dTexture", (i + 1)); u->pass[i].texture = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "Pass%dInputSize", (i + 1)); + snprintf(s, sizeof(s) - 1, "Pass%dInputSize", (i + 1)); u->pass[i].input_size = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "Pass%dTextureSize", (i + 1)); + snprintf(s, sizeof(s) - 1, "Pass%dTextureSize", (i + 1)); u->pass[i].texture_size = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "PassPrev%dTexture", num_pass - i); + snprintf(s, sizeof(s) - 1, "PassPrev%dTexture", num_pass - i); u->prev_pass[i].texture = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "PassPrev%dInputSize", num_pass - i); + snprintf(s, sizeof(s) - 1, "PassPrev%dInputSize", num_pass - i); u->prev_pass[i].input_size = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "PassPrev%dTextureSize", num_pass - i); + snprintf(s, sizeof(s) - 1, "PassPrev%dTextureSize", num_pass - i); u->prev_pass[i].texture_size = get_uniform(p, s); } u->prev[0].texture = get_uniform(p, "PrevTexture"); u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); for (i = 1; i < MAX_PREV; ++i) { - snprintf(s, sizeof(s) -1, "Prev%dTexture", i); + snprintf(s, sizeof(s) - 1, "Prev%dTexture", i); u->prev[i].texture = get_uniform(p, s); - snprintf(s, sizeof(s) -1, "Prev%dTexCoord", i); + snprintf(s, sizeof(s) - 1, "Prev%dTexCoord", i); u->prev[i].tex_coord = get_attrib(p, s); } for (i = 0; i < MAX_PREV; ++i) @@ -654,7 +653,7 @@ OpenGLRenderer::load_glslp(glsl_t *glsl, int num_shader, const char *f) ogl3_log("Load texture %s...\n", file); if (!load_texture(file, &tex->texture)) { - //QMessageBox::critical(main_window, tr("GLSL Error"), tr("Could not load texture: %s").arg(file)); + // QMessageBox::critical(main_window, tr("GLSL Error"), tr("Could not load texture: %s").arg(file)); main_window->showMessage(MBX_ERROR | MBX_FATAL, tr("GLSL Error"), tr("Could not load texture: %1").arg(file), false); ogl3_log("Could not load texture %s!\n", file); failed = 1; @@ -806,7 +805,7 @@ OpenGLRenderer::read_shader_config() for (int i = 0; i < active_shader->num_shaders; ++i) { struct glsl_shader *shader = &active_shader->shaders[i]; char *name = shader->name; - snprintf(s, sizeof(s) -1, "GL3 Shaders - %s", name); + snprintf(s, sizeof(s) - 1, "GL3 Shaders - %s", name); // shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); for (int j = 0; j < shader->num_parameters; ++j) { struct shader_parameter *param = &shader->parameters[j]; @@ -819,7 +818,7 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent) : QWindow((QWindow*)nullptr) , renderTimer(new QTimer(this)) { - connect(renderTimer, &QTimer::timeout, this, [this]() { this->render(); } ); + connect(renderTimer, &QTimer::timeout, this, [this]() { this->render(); }); imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); @@ -847,8 +846,8 @@ OpenGLRenderer::OpenGLRenderer(QWidget *parent) source.setRect(0, 0, 100, 100); isInitialized = false; - isFinalized = false; - context = nullptr; + isFinalized = false; + context = nullptr; } OpenGLRenderer::~OpenGLRenderer() { finalize(); } @@ -874,12 +873,16 @@ OpenGLRenderer::initialize() glw.initializeOpenGLFunctions(); + glw.glClearColor(0, 0, 0, 1); + + glw.glClear(GL_COLOR_BUFFER_BIT); + ogl3_log("OpenGL information: [%s] %s (%s)\n", glw.glGetString(GL_VENDOR), glw.glGetString(GL_RENDERER), glw.glGetString(GL_VERSION)); - glsl_version[0] = glsl_version[1] = -1; - glw.glGetIntegerv(GL_MAJOR_VERSION, &glsl_version[0]); - glw.glGetIntegerv(GL_MINOR_VERSION, &glsl_version[1]); - if (glsl_version[0] < 3) { - throw opengl_init_error(tr("OpenGL version 3.0 or greater is required. Current GLSL version is %1.%2").arg(glsl_version[0]).arg(glsl_version[1])); + gl_version[0] = gl_version[1] = -1; + glw.glGetIntegerv(GL_MAJOR_VERSION, &gl_version[0]); + glw.glGetIntegerv(GL_MINOR_VERSION, &gl_version[1]); + if (gl_version[0] < 3) { + throw opengl_init_error(tr("OpenGL version 3.0 or greater is required. Current version is %1.%2").arg(gl_version[0]).arg(gl_version[1])); } ogl3_log("Using OpenGL %s\n", glw.glGetString(GL_VERSION)); ogl3_log("Using Shading Language %s\n", glw.glGetString(GL_SHADING_LANGUAGE_VERSION)); @@ -898,20 +901,20 @@ OpenGLRenderer::initialize() glw.glEnable(GL_TEXTURE_2D); - //renderTimer->start(75); + // renderTimer->start(75); if (video_framerate != -1) { - renderTimer->start(ceilf(1000.f / (float)video_framerate)); + renderTimer->start(ceilf(1000.f / (float) video_framerate)); } scene_texture.data = NULL; scene_texture.width = 2048; scene_texture.height = 2048; - scene_texture.internal_format = GL_RGB8; - scene_texture.format = GL_BGR; + scene_texture.internal_format = GL_RGBA8; + scene_texture.format = GL_RGBA; scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; scene_texture.min_filter = scene_texture.mag_filter = video_filter_method ? GL_LINEAR : GL_NEAREST; - scene_texture.mipmap = 0; + scene_texture.mipmap = 0; create_texture(&scene_texture); @@ -1105,10 +1108,6 @@ OpenGLRenderer::initialize() emit initialized(); - glw.glClearColor(0, 0, 0, 1); - - glw.glClear(GL_COLOR_BUFFER_BIT); - context->swapBuffers(this); } catch (const opengl_init_error &e) { /* Mark all buffers as in use */ @@ -1228,7 +1227,7 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) destination.y(), destination.width(), destination.height()); - + if (video_framerate == -1) render(); } @@ -1388,7 +1387,7 @@ OpenGLRenderer::event(QEvent *event) return res; } -QDialog* +QDialog * OpenGLRenderer::getOptions(QWidget *parent) { return new OpenGLShaderManagerDialog(parent); @@ -1427,7 +1426,7 @@ OpenGLRenderer::render() glw.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, video_filter_method ? GL_LINEAR : GL_NEAREST); glw.glBindTexture(GL_TEXTURE_2D, 0); - GLfloat orig_output_size[] = { (GLfloat)window_rect.w, (GLfloat)window_rect.h }; + GLfloat orig_output_size[] = { (GLfloat) window_rect.w, (GLfloat) window_rect.h }; if (active_shader->srgb) glw.glEnable(GL_FRAMEBUFFER_SRGB); @@ -1508,8 +1507,8 @@ OpenGLRenderer::render() /* loop through each pass */ for (int i = 0; i < shader->num_passes; ++i) { - bool resetFiltering = false; - struct shader_pass *pass = &shader->passes[i]; + bool resetFiltering = false; + struct shader_pass *pass = &shader->passes[i]; memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); @@ -1697,31 +1696,31 @@ OpenGLRenderer::render() } if (monitors[r_monitor_index].mon_screenshots) { - int width = destination.width(), height = destination.height(); + int width = destination.width(), height = destination.height(); char path[1024]; char fn[256]; - + memset(fn, 0, sizeof(fn)); memset(path, 0, sizeof(path)); - + path_append_filename(path, usr_path, SCREENSHOT_PATH); - + if (!plat_dir_check(path)) plat_dir_create(path); - + path_slash(path); strcat(path, "Monitor_"); snprintf(&path[strlen(path)], 42, "%d_", r_monitor_index + 1); - - plat_tempfile(fn, NULL, (char*)".png"); + + plat_tempfile(fn, NULL, (char *) ".png"); strcat(path, fn); - unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 3); - + unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 4); + glw.glFinish(); glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb); - QImage image(rgb, width, height, QImage::Format_RGB888); + QImage image((uchar*)rgb, width, height, width * 3, QImage::Format_RGB888); image.mirrored(false, true).save(path, "png"); monitors[r_monitor_index].mon_screenshots--; free(rgb); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index c2dc3291710..f99d7384ebf 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -39,8 +39,7 @@ #include "qt_renderercommon.hpp" -extern "C" -{ +extern "C" { #include <86box/qt-glslp-parser.h> } @@ -83,10 +82,9 @@ public slots: bool event(QEvent *event) override; private: - std::array, 2> imagebufs; - QTimer *renderTimer; + QTimer *renderTimer; QString glslVersion = ""; @@ -98,30 +96,30 @@ public slots: QOpenGLExtraFunctions glw; struct shader_texture scene_texture; - glsl_t *active_shader; + glsl_t *active_shader; void *unpackBuffer = nullptr; - int glsl_version[2] = { 0, 0 }; + int gl_version[2] = { 0, 0 }; void initialize(); void initializeExtensions(); void initializeBuffers(); void applyOptions(); - + void create_scene_shader(); void create_texture(struct shader_texture *tex); void create_fbo(struct shader_fbo *fbo); void recreate_fbo(struct shader_fbo *fbo, int width, int height); void setup_fbo(struct shader *shader, struct shader_fbo *fbo); - bool notReady() const { return !isInitialized || isFinalized; } - glsl_t* load_glslp(glsl_t *glsl, int num_shader, const char *f); - glsl_t* load_shaders(int num, char shaders[MAX_USER_SHADERS][512]); - int compile_shader(GLenum shader_type, const char *prepend, const char *program, int *dst); - int create_default_shader_tex(struct shader_pass *pass); - int create_default_shader_color(struct shader_pass *pass); - int create_program(struct shader_program *program); + bool notReady() const { return !isInitialized || isFinalized; } + glsl_t *load_glslp(glsl_t *glsl, int num_shader, const char *f); + glsl_t *load_shaders(int num, char shaders[MAX_USER_SHADERS][512]); + int compile_shader(GLenum shader_type, const char *prepend, const char *program, int *dst); + int create_default_shader_tex(struct shader_pass *pass); + int create_default_shader_color(struct shader_pass *pass); + int create_program(struct shader_program *program); GLuint get_uniform(GLuint program, const char *name); GLuint get_attrib(GLuint program, const char *name); diff --git a/src/qt/qt_openglshaderconfig.cpp b/src/qt/qt_openglshaderconfig.cpp index 1e8c2d54f9f..096f274070f 100644 --- a/src/qt/qt_openglshaderconfig.cpp +++ b/src/qt/qt_openglshaderconfig.cpp @@ -3,16 +3,15 @@ #include "qt_mainwindow.hpp" -extern MainWindow* main_window; +extern MainWindow *main_window; -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/config.h> } -OpenGLShaderConfig::OpenGLShaderConfig(QWidget *parent, glslp_t* shader) +OpenGLShaderConfig::OpenGLShaderConfig(QWidget *parent, glslp_t *shader) : QDialog(parent) , ui(new Ui::OpenGLShaderConfig) { @@ -27,11 +26,12 @@ OpenGLShaderConfig::OpenGLShaderConfig(QWidget *parent, glslp_t* shader) for (int i = 0; i < currentShader->num_parameters; i++) { auto spinBox = new QDoubleSpinBox; + spinBox->setDecimals(3); spinBox->setObjectName(currentShader->parameters[i].id); spinBox->setRange(currentShader->parameters[i].min, currentShader->parameters[i].max); spinBox->setValue(currentShader->parameters[i].value); spinBox->setSingleStep(currentShader->parameters[i].step); - QFormLayout* layout = (QFormLayout*)ui->scrollAreaWidgetContents->layout(); + QFormLayout *layout = (QFormLayout *) ui->scrollAreaWidgetContents->layout(); layout->addRow(currentShader->parameters[i].description, spinBox); } } @@ -41,11 +41,12 @@ OpenGLShaderConfig::~OpenGLShaderConfig() delete ui; } -void OpenGLShaderConfig::on_buttonBox_clicked(QAbstractButton *button) +void +OpenGLShaderConfig::on_buttonBox_clicked(QAbstractButton *button) { if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole) { for (int i = 0; i < currentShader->num_parameters; i++) { - QDoubleSpinBox* box = this->findChild(QString(currentShader->parameters[i].id)); + QDoubleSpinBox *box = this->findChild(QString(currentShader->parameters[i].id)); if (box) { box->setValue(currentShader->parameters[i].default_value); } @@ -53,9 +54,9 @@ void OpenGLShaderConfig::on_buttonBox_clicked(QAbstractButton *button) } else if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) { startblit(); for (int i = 0; i < currentShader->num_parameters; i++) { - QDoubleSpinBox* box = this->findChild(QString(currentShader->parameters[i].id)); + QDoubleSpinBox *box = this->findChild(QString(currentShader->parameters[i].id)); if (box) { - float val = (float)box->value(); + float val = (float) box->value(); currentShader->parameters[i].value = val; } } @@ -66,14 +67,14 @@ void OpenGLShaderConfig::on_buttonBox_clicked(QAbstractButton *button) } } - -void OpenGLShaderConfig::on_OpenGLShaderConfig_accepted() +void +OpenGLShaderConfig::on_OpenGLShaderConfig_accepted() { startblit(); for (int i = 0; i < currentShader->num_parameters; i++) { - QDoubleSpinBox* box = (QDoubleSpinBox*)this->findChild(QString(currentShader->parameters[i].id)); + QDoubleSpinBox *box = (QDoubleSpinBox *) this->findChild(QString(currentShader->parameters[i].id)); if (box) { - float val = (float)box->value(); + float val = (float) box->value(); currentShader->parameters[i].value = val; } } diff --git a/src/qt/qt_openglshaderconfig.hpp b/src/qt/qt_openglshaderconfig.hpp index f71299d380d..307aae4029b 100644 --- a/src/qt/qt_openglshaderconfig.hpp +++ b/src/qt/qt_openglshaderconfig.hpp @@ -9,8 +9,7 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/qt-glslp-parser.h> } @@ -22,7 +21,7 @@ class OpenGLShaderConfig : public QDialog { Q_OBJECT public: - explicit OpenGLShaderConfig(QWidget *parent = nullptr, glslp_t* shader = nullptr); + explicit OpenGLShaderConfig(QWidget *parent = nullptr, glslp_t *shader = nullptr); ~OpenGLShaderConfig(); private slots: @@ -32,7 +31,7 @@ private slots: private: Ui::OpenGLShaderConfig *ui; - glslp_t* currentShader; + glslp_t *currentShader; std::map defaultValues; }; diff --git a/src/qt/qt_openglshadermanagerdialog.cpp b/src/qt/qt_openglshadermanagerdialog.cpp index ac252c092f5..f9678c6da36 100644 --- a/src/qt/qt_openglshadermanagerdialog.cpp +++ b/src/qt/qt_openglshadermanagerdialog.cpp @@ -3,7 +3,7 @@ #include "qt_mainwindow.hpp" #include "qt_util.hpp" -extern MainWindow* main_window; +extern MainWindow *main_window; #include "qt_openglshaderconfig.hpp" @@ -41,14 +41,14 @@ OpenGLShaderManagerDialog::OpenGLShaderManagerDialog(QWidget *parent) for (int i = 0; i < MAX_USER_SHADERS; i++) { if (gl3_shader_file[i][0] != 0) { - char* filename = path_get_filename(gl3_shader_file[i]); + char *filename = path_get_filename(gl3_shader_file[i]); if (filename[0] != 0) { - glslp_t* shaderfile = glslp_parse(gl3_shader_file[i]); + glslp_t *shaderfile = glslp_parse(gl3_shader_file[i]); if (shaderfile) { - QListWidgetItem* item = new QListWidgetItem(ui->shaderListWidget); + QListWidgetItem *item = new QListWidgetItem(ui->shaderListWidget); item->setText(filename); item->setData(Qt::UserRole + 1, QString(gl3_shader_file[i])); - item->setData(Qt::UserRole + 2, (qulonglong)(uintptr_t)shaderfile); + item->setData(Qt::UserRole + 2, (qulonglong) (uintptr_t) shaderfile); } } } @@ -57,7 +57,7 @@ OpenGLShaderManagerDialog::OpenGLShaderManagerDialog(QWidget *parent) ui->shaderListWidget->setCurrentRow(ui->shaderListWidget->count() - 1); auto current = ui->shaderListWidget->currentItem(); if (current) { - glslp_t* shader = (glslp_t*)current->data(Qt::UserRole + 2).toULongLong(); + glslp_t *shader = (glslp_t *) current->data(Qt::UserRole + 2).toULongLong(); if (shader->num_parameters > 0) ui->buttonConfigure->setEnabled(true); else @@ -78,13 +78,14 @@ OpenGLShaderManagerDialog::~OpenGLShaderManagerDialog() { for (int i = 0; i < ui->shaderListWidget->count(); i++) { if (ui->shaderListWidget->item(i) && ui->shaderListWidget->item(i)->data(Qt::UserRole + 2).toULongLong()) { - glslp_free((glslp_t*)ui->shaderListWidget->item(i)->data(Qt::UserRole + 2).toULongLong()); + glslp_free((glslp_t *) ui->shaderListWidget->item(i)->data(Qt::UserRole + 2).toULongLong()); } } delete ui; } -void OpenGLShaderManagerDialog::on_buttonBox_clicked(QAbstractButton *button) +void +OpenGLShaderManagerDialog::on_buttonBox_clicked(QAbstractButton *button) { if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole) { accept(); @@ -96,20 +97,20 @@ void OpenGLShaderManagerDialog::on_buttonBox_clicked(QAbstractButton *button) } } - -void OpenGLShaderManagerDialog::on_buttonMoveUp_clicked() +void +OpenGLShaderManagerDialog::on_buttonMoveUp_clicked() { if (ui->shaderListWidget->currentRow() == 0) return; - int row = ui->shaderListWidget->currentRow(); + int row = ui->shaderListWidget->currentRow(); auto item = ui->shaderListWidget->takeItem(row); ui->shaderListWidget->insertItem(row - 1, item); ui->shaderListWidget->setCurrentItem(item); } - -void OpenGLShaderManagerDialog::on_shaderListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) +void +OpenGLShaderManagerDialog::on_shaderListWidget_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) { if (current == nullptr) { ui->buttonRemove->setDisabled(true); @@ -121,7 +122,7 @@ void OpenGLShaderManagerDialog::on_shaderListWidget_currentItemChanged(QListWidg ui->buttonRemove->setDisabled(false); ui->buttonConfigure->setDisabled(true); if (current) { - glslp_t* shader = (glslp_t*)current->data(Qt::UserRole + 2).toULongLong(); + glslp_t *shader = (glslp_t *) current->data(Qt::UserRole + 2).toULongLong(); if (shader->num_parameters > 0) ui->buttonConfigure->setEnabled(true); } @@ -130,8 +131,8 @@ void OpenGLShaderManagerDialog::on_shaderListWidget_currentItemChanged(QListWidg ui->buttonMoveDown->setDisabled(ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1)); } - -void OpenGLShaderManagerDialog::on_shaderListWidget_currentRowChanged(int currentRow) +void +OpenGLShaderManagerDialog::on_shaderListWidget_currentRowChanged(int currentRow) { auto current = ui->shaderListWidget->currentItem(); if (current == nullptr) { @@ -144,7 +145,7 @@ void OpenGLShaderManagerDialog::on_shaderListWidget_currentRowChanged(int curren ui->buttonRemove->setDisabled(false); ui->buttonConfigure->setDisabled(true); if (current) { - glslp_t* shader = (glslp_t*)current->data(Qt::UserRole + 2).toULongLong(); + glslp_t *shader = (glslp_t *) current->data(Qt::UserRole + 2).toULongLong(); if (shader->num_parameters > 0) ui->buttonConfigure->setEnabled(true); } @@ -153,32 +154,32 @@ void OpenGLShaderManagerDialog::on_shaderListWidget_currentRowChanged(int curren ui->buttonMoveDown->setDisabled(ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1)); } - -void OpenGLShaderManagerDialog::on_buttonMoveDown_clicked() +void +OpenGLShaderManagerDialog::on_buttonMoveDown_clicked() { if (ui->shaderListWidget->currentRow() == (ui->shaderListWidget->count() - 1)) return; - int row = ui->shaderListWidget->currentRow(); + int row = ui->shaderListWidget->currentRow(); auto item = ui->shaderListWidget->takeItem(row); ui->shaderListWidget->insertItem(row + 1, item); ui->shaderListWidget->setCurrentItem(item); } - -void OpenGLShaderManagerDialog::on_buttonAdd_clicked() +void +OpenGLShaderManagerDialog::on_buttonAdd_clicked() { auto res = QFileDialog::getOpenFileName(this, QString(), QString(), tr("GLSL shaders") % util::DlgFilter({ "glslp", "glsl" }) % tr("All files") % util::DlgFilter({ "*" }, true)); if (!res.isEmpty()) { - auto glslp_file = res.toUtf8(); - glslp_t* shaderfile = glslp_parse(glslp_file.data()); + auto glslp_file = res.toUtf8(); + glslp_t *shaderfile = glslp_parse(glslp_file.data()); if (shaderfile) { - auto filename = path_get_filename(glslp_file.data()); - QListWidgetItem* item = new QListWidgetItem(ui->shaderListWidget); + auto filename = path_get_filename(glslp_file.data()); + QListWidgetItem *item = new QListWidgetItem(ui->shaderListWidget); item->setText(filename); item->setData(Qt::UserRole + 1, res); - item->setData(Qt::UserRole + 2, (qulonglong)(uintptr_t)shaderfile); + item->setData(Qt::UserRole + 2, (qulonglong) (uintptr_t) shaderfile); if (ui->shaderListWidget->count()) { ui->shaderListWidget->setCurrentRow(ui->shaderListWidget->count() - 1); ui->buttonAdd->setDisabled(ui->shaderListWidget->count() >= MAX_USER_SHADERS); @@ -189,14 +190,14 @@ void OpenGLShaderManagerDialog::on_buttonAdd_clicked() } } - -void OpenGLShaderManagerDialog::on_buttonRemove_clicked() +void +OpenGLShaderManagerDialog::on_buttonRemove_clicked() { if (ui->shaderListWidget->currentItem()) { auto item = ui->shaderListWidget->takeItem(ui->shaderListWidget->currentRow()); if (item->data(Qt::UserRole + 2).toULongLong()) { - glslp_free((glslp_t*)item->data(Qt::UserRole + 2).toULongLong()); + glslp_free((glslp_t *) item->data(Qt::UserRole + 2).toULongLong()); } delete item; @@ -205,7 +206,8 @@ void OpenGLShaderManagerDialog::on_buttonRemove_clicked() ui->buttonAdd->setDisabled(ui->shaderListWidget->count() >= MAX_USER_SHADERS); } -void OpenGLShaderManagerDialog::on_OpenGLShaderManagerDialog_accepted() +void +OpenGLShaderManagerDialog::on_OpenGLShaderManagerDialog_accepted() { memset(gl3_shader_file, 0, sizeof(gl3_shader_file)); for (int i = 0; i < ui->shaderListWidget->count(); i++) { @@ -222,43 +224,43 @@ void OpenGLShaderManagerDialog::on_OpenGLShaderManagerDialog_accepted() endblit(); } - -void OpenGLShaderManagerDialog::on_buttonConfigure_clicked() +void +OpenGLShaderManagerDialog::on_buttonConfigure_clicked() { auto item = ui->shaderListWidget->currentItem(); if (item) { - glslp_t* shader = (glslp_t*)item->data(Qt::UserRole + 2).toULongLong(); + glslp_t *shader = (glslp_t *) item->data(Qt::UserRole + 2).toULongLong(); auto configDialog = new OpenGLShaderConfig(this, shader); configDialog->exec(); } } - -void OpenGLShaderManagerDialog::on_radioButtonVideoSync_clicked() +void +OpenGLShaderManagerDialog::on_radioButtonVideoSync_clicked() { ui->targetFrameRate->setDisabled(true); } - -void OpenGLShaderManagerDialog::on_radioButtonTargetFramerate_clicked() +void +OpenGLShaderManagerDialog::on_radioButtonTargetFramerate_clicked() { ui->targetFrameRate->setDisabled(false); } - -void OpenGLShaderManagerDialog::on_horizontalSliderFramerate_sliderMoved(int position) +void +OpenGLShaderManagerDialog::on_horizontalSliderFramerate_sliderMoved(int position) { - (void)position; + (void) position; if (ui->horizontalSliderFramerate->value() != ui->targetFrameRate->value()) ui->targetFrameRate->setValue(ui->horizontalSliderFramerate->value()); } - -void OpenGLShaderManagerDialog::on_targetFrameRate_valueChanged(int arg1) +void +OpenGLShaderManagerDialog::on_targetFrameRate_valueChanged(int arg1) { - (void)arg1; + (void) arg1; if (ui->horizontalSliderFramerate->value() != ui->targetFrameRate->value()) ui->horizontalSliderFramerate->setValue(ui->targetFrameRate->value()); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index d276dc8bda1..a042d8b7d16 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -17,7 +17,7 @@ * Copyright 2021-2022 Teemu Korhonen */ #ifdef __HAIKU__ -#include +# include #endif #include @@ -125,7 +125,7 @@ extern "C" { #include <86box/config.h> #include <86box/ui.h> #ifdef DISCORD -# include <86box/discord.h> +# include <86box/discord.h> #endif #include "../cpu/cpu.h" @@ -186,9 +186,9 @@ plat_get_exe_name(char *s, int size) if (acp_utf8) GetModuleFileNameA(NULL, s, size); else { - temp = (wchar_t*)calloc(size, sizeof(wchar_t)); + temp = (wchar_t *) calloc(size, sizeof(wchar_t)); GetModuleFileNameW(NULL, temp, size); - c16stombs(s, (uint16_t*)temp, size); + c16stombs(s, (uint16_t *) temp, size); free(temp); } #else @@ -254,7 +254,7 @@ plat_file_check(const char *path) { #ifdef _WIN32 auto data = QString::fromUtf8(path).toStdWString(); - auto res = GetFileAttributesW(data.c_str()); + auto res = GetFileAttributesW(data.c_str()); return (res != INVALID_FILE_ATTRIBUTES) && !(res & FILE_ATTRIBUTE_DIRECTORY); #else struct stat stats; @@ -269,12 +269,12 @@ plat_getcwd(char *bufp, int max) { #ifdef __APPLE__ /* Working directory for .app bundles is undefined. */ -#ifdef USE_EXE_PATH +# ifdef USE_EXE_PATH strncpy(bufp, exe_path, max); -#else +# else CharPointer(bufp, max) = QDir::homePath().toUtf8(); path_append_filename(bufp, bufp, "Library/86Box"); -#endif +# endif #else CharPointer(bufp, max) = QDir::currentPath().toUtf8(); #endif @@ -320,7 +320,7 @@ path_get_filename(char *s) return s; #else - auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); + auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); if (idx >= 0) { return s + idx + 1; } @@ -390,7 +390,7 @@ path_append_filename(char *dest, const char *s1, const char *s2) if (len > 0 && dest[len - 1] != '/' && dest[len - 1] != '\\') { if (len + 1 < dest_size) { dest[len++] = '/'; - dest[len] = '\0'; + dest[len] = '\0'; } } @@ -453,58 +453,58 @@ extern bool cpu_thread_running; #ifdef Q_OS_WINDOWS /* SetThreadDescription was added in 14393 and SetProcessInformation in 8. Revisit if we ever start requiring 10. */ -static void *kernel32_handle = NULL; -static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; +static void *kernel32_handle = NULL; +static HRESULT(WINAPI *pSetThreadDescription)(HANDLE hThread, PCWSTR lpThreadDescription) = NULL; static HRESULT(WINAPI *pSetProcessInformation)(HANDLE hProcess, PROCESS_INFORMATION_CLASS ProcessInformationClass, LPVOID ProcessInformation, DWORD ProcessInformationSize) = NULL; -static dllimp_t kernel32_imports[] = { - // clang-format off +static dllimp_t kernel32_imports[] = { + // clang-format off { "SetThreadDescription", &pSetThreadDescription }, { "SetProcessInformation", &pSetProcessInformation }, { NULL, NULL } - // clang-format on + // clang-format on }; static void enter_pause(void) { - PROCESS_POWER_THROTTLING_STATE state{}; - state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; + PROCESS_POWER_THROTTLING_STATE state {}; + state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; state.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED | PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; - state.StateMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED | PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; + state.StateMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED | PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; if (!kernel32_handle) { kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ - pSetThreadDescription = NULL; + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ + pSetThreadDescription = NULL; pSetProcessInformation = NULL; } } if (pSetProcessInformation) { - pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, (LPVOID)&state, sizeof(state)); + pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, (LPVOID) &state, sizeof(state)); } } void exit_pause(void) { - PROCESS_POWER_THROTTLING_STATE state{}; - state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; + PROCESS_POWER_THROTTLING_STATE state {}; + state.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION; state.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED | PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION; - state.StateMask = 0; + state.StateMask = 0; if (!kernel32_handle) { kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ - pSetThreadDescription = NULL; + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ + pSetThreadDescription = NULL; pSetProcessInformation = NULL; } } if (pSetProcessInformation) { - pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, (LPVOID)&state, sizeof(state)); + pSetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling, (LPVOID) &state, sizeof(state)); } } #endif @@ -695,13 +695,13 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# define LIB_NAME_GS "gsdll64.dll" -# define LIB_NAME_GPCL "gpcl6dll64.dll" -# define LIB_NAME_PCAP "Npcap" +# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GPCL "gpcl6dll64.dll" +# define LIB_NAME_PCAP "Npcap" #else -# define LIB_NAME_GS "libgs" -# define LIB_NAME_GPCL "libgpcl6" -# define LIB_NAME_PCAP "libpcap" +# define LIB_NAME_GS "libgs" +# define LIB_NAME_GPCL "libgpcl6" +# define LIB_NAME_PCAP "libpcap" #endif QMap ProgSettings::translatedstrings; @@ -837,15 +837,40 @@ plat_init_rom_paths(void) } void -plat_get_cpu_string(char *outbuf, uint8_t len) { +plat_init_asset_paths(void) +{ + auto paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); + +#ifdef _WIN32 + // HACK: The standard locations returned for GenericDataLocation include + // the EXE path and a `data` directory within it as the last two entries. + + // Remove the entries as we don't need them. + paths.removeLast(); + paths.removeLast(); +#endif + + for (auto &path : paths) { +#ifdef __APPLE__ + asset_add_path(QDir(path).filePath("net.86Box.86Box/assets").toUtf8().constData()); + asset_add_path(QDir(path).filePath("86Box/assets").toUtf8().constData()); +#else + asset_add_path(QDir(path).filePath("86Box/assets").toUtf8().constData()); +#endif + } +} + +void +plat_get_cpu_string(char *outbuf, uint8_t len) +{ auto cpu_string = QString("Unknown"); /* Write the default string now in case we have to exit early from an error */ qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); #if defined(Q_OS_MACOS) - auto *process = new QProcess(nullptr); + auto *process = new QProcess(nullptr); QStringList arguments; - QString program = "/usr/sbin/sysctl"; + QString program = "/usr/sbin/sysctl"; arguments << "machdep.cpu.brand_string"; process->start(program, arguments); if (!process->waitForStarted()) { @@ -854,9 +879,9 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { if (!process->waitForFinished()) { return; } - QByteArray result = process->readAll(); - auto command_result = QString(result).split(": ").last().trimmed(); - if(!command_result.isEmpty()) { + QByteArray result = process->readAll(); + auto command_result = QString(result).split(": ").last().trimmed(); + if (!command_result.isEmpty()) { cpu_string = command_result; } #elif defined(Q_OS_WINDOWS) @@ -868,38 +893,36 @@ plat_get_cpu_string(char *outbuf, uint8_t len) { bufSize = 32768; if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { - cpu_string = reinterpret_cast(buf); + cpu_string = reinterpret_cast(buf); } RegCloseKey(hKey); } #elif defined(Q_OS_LINUX) - auto cpuinfo = QString("/proc/cpuinfo"); + auto cpuinfo = QString("/proc/cpuinfo"); auto cpuinfo_fi = QFileInfo(cpuinfo); - if(!cpuinfo_fi.isReadable()) { + if (!cpuinfo_fi.isReadable()) { return; } QFile file(cpuinfo); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream textStream(&file); - while(true) { + while (true) { QString line = textStream.readLine(); if (line.isNull()) { break; } - if(QRegularExpression("model name.*:").match(line).hasMatch()) { + if (QRegularExpression("model name.*:").match(line).hasMatch()) { auto list = line.split(": "); - if(!list.last().isEmpty()) { + if (!list.last().isEmpty()) { cpu_string = list.last(); break; } } - } } #endif qstrncpy(outbuf, cpu_string.toUtf8().constData(), len); - } void @@ -909,14 +932,14 @@ plat_set_thread_name(void *thread, const char *name) if (!kernel32_handle) { kernel32_handle = dynld_module("kernel32.dll", kernel32_imports); if (!kernel32_handle) { - kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ - pSetThreadDescription = NULL; + kernel32_handle = kernel32_imports; /* store dummy pointer to avoid trying again */ + pSetThreadDescription = NULL; pSetProcessInformation = NULL; } } if (pSetThreadDescription) { - size_t len = strlen(name) + 1; + size_t len = strlen(name) + 1; wchar_t wname[2048]; mbstowcs(wname, name, (len >= 1024) ? 1024 : len); pSetThreadDescription(thread ? (HANDLE) thread : GetCurrentThread(), wname); @@ -935,7 +958,7 @@ plat_set_thread_name(void *thread, const char *name) # if defined(Q_OS_DARWIN) pthread_setname_np(truncated); # elif defined(Q_OS_NETBSD) - pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated, (void*)"%s"); + pthread_setname_np(thread ? *((pthread_t *) thread) : pthread_self(), truncated, (void *) "%s"); # elif defined(__HAIKU__) rename_thread(find_thread(NULL), truncated); # elif defined(Q_OS_OPENBSD) diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index ac1d6478fb7..268cec8945b 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -40,7 +40,7 @@ extern "C" { #include <86box/video.h> } -extern MainWindow *main_window; +extern MainWindow *main_window; ProgSettings::CustomTranslator *ProgSettings::translator = nullptr; QTranslator *ProgSettings::qtTranslator = nullptr; diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 9445d2f866d..2ada8c2bfaa 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -17,10 +17,10 @@ class ProgSettings : public QDialog { #ifdef Q_OS_WINDOWS static QString getFontName(int langId); #endif - static int languageCodeToId(QString langCode); - static QString languageIdToCode(int id); - static void loadTranslators(QObject *parent = nullptr); - static void reloadStrings(); + static int languageCodeToId(QString langCode); + static QString languageIdToCode(int id); + static void loadTranslators(QObject *parent = nullptr); + static void reloadStrings(); class CustomTranslator : public QTranslator { public: CustomTranslator(QObject *parent = nullptr) @@ -33,10 +33,10 @@ class ProgSettings : public QDialog { return QTranslator::translate("", sourceText, disambiguation, n); } }; - static CustomTranslator *translator; - static QTranslator *qtTranslator; - static QVector> languages; - static QMap translatedstrings; + static CustomTranslator *translator; + static QTranslator *qtTranslator; + static QVector> languages; + static QMap translatedstrings; protected slots: void accept() override; @@ -49,7 +49,7 @@ private slots: private: Ui::ProgSettings *ui; - static bool loadQtTranslations(const QString name); + static bool loadQtTranslations(const QString name); friend class MainWindow; double mouseSensitivity; diff --git a/src/qt/qt_progsettings.ui b/src/qt/qt_progsettings.ui index ca33726b155..6d5f80830f6 100644 --- a/src/qt/qt_progsettings.ui +++ b/src/qt/qt_progsettings.ui @@ -27,19 +27,31 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize - + Language: + + + + 30 + + + + (System Default) + + + + - Qt::Orientation::Horizontal + Qt::Horizontal @@ -49,43 +61,17 @@ - - - - Inhibit multimedia keys - - - - - - - Mouse sensitivity: - - - - - + + Default - - - - 30 - - - - (System Default) - - - - - - + + - Ask for confirmation before saving settings + Mouse sensitivity: @@ -107,11 +93,31 @@ 100 - Qt::Orientation::Horizontal + Qt::Horizontal - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Default + + + + <html><head/><body><p>When selecting media images (CD-ROM, floppy, etc.) the open dialog will start in the same directory as the 86Box configuration file. This setting will likely only make a difference on macOS.</p></body></html> @@ -121,78 +127,89 @@ - - + + - Default + Inhibit multimedia keys - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - + + + + Ask for confirmation before saving settings - + - + Ask for confirmation before quitting - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok - - - - + Ask for confirmation before hard resetting - - - - Color scheme - - - - - - System - - - - - - - Light - - - - - - - Dark - - - - + + + + + + Color scheme + + + + + + System + + + + + + + Light + + + + + + + Dark + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index d34cad15b76..944f21349aa 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -117,13 +117,13 @@ void RendererCommon::onResize(int width, int height) { /* This is needed so that the if below does not take like, 5 lines. */ - bool is_fs = (video_fullscreen == 0); - bool parent_max = (parentWidget->isMaximized() == false); + bool is_fs = (video_fullscreen == 0); + bool parent_max = (parentWidget->isMaximized() == false); bool main_is_ancestor = main_window->isAncestorOf(parentWidget); - bool main_max = main_window->isMaximized(); - bool main_is_max = (main_is_ancestor && main_max == false); + bool main_max = main_window->isMaximized(); + bool main_is_max = (main_is_ancestor && main_max == false); - width = round(pixelRatio * width); + width = round(pixelRatio * width); height = round(pixelRatio * height); if (is_fs && (video_fullscreen_scale_maximized ? (parent_max && main_is_max) : 1) && !(force_43 && vid_resize)) @@ -142,7 +142,7 @@ RendererCommon::onResize(int width, int height) double gh = source.height(); double hsr = hw / hh; double r43 = 4.0 / 3.0; - + if (force_43 && is_fs && vid_resize) { if (!video_fullscreen_scale_maximized || (video_fullscreen_scale_maximized && parent_max && main_is_max)) temp_fullscreen_scale = FULLSCR_SCALE_43; @@ -155,7 +155,7 @@ RendererCommon::onResize(int width, int height) if (temp_fullscreen_scale == FULLSCR_SCALE_INT43) { gh = gw / r43; -// gw = gw; + // gw = gw; gsr = r43; } @@ -203,8 +203,8 @@ RendererCommon::onResize(int width, int height) monitors[r_monitor_index].mon_res_x = (double) destination.width(); monitors[r_monitor_index].mon_res_y = (double) destination.height(); - destinationF.setRect((double)destination.x() / (double)width, (double)destination.y() / (double)height, - (double)destination.width() / (double)width, (double)destination.height() / (double)height); + destinationF.setRect((double) destination.x() / (double) width, (double) destination.y() / (double) height, + (double) destination.width() / (double) width, (double) destination.height() / (double) height); } bool @@ -220,10 +220,12 @@ RendererCommon::eventDelegate(QEvent *event, bool &result) case QEvent::MouseButtonPress: case QEvent::MouseMove: case QEvent::MouseButtonRelease: +#ifdef TOUCH_PR case QEvent::TouchBegin: case QEvent::TouchEnd: case QEvent::TouchCancel: case QEvent::TouchUpdate: +#endif case QEvent::Wheel: case QEvent::Enter: case QEvent::Leave: diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 6bfa51a8d86..827646bab14 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -40,12 +40,12 @@ class RendererCommon { /* Should the renderer take screenshots itself? */ virtual bool rendererTakeScreenshot() { return false; } - int r_monitor_index = 0; - QRectF destinationF = QRectF(0, 0, 1, 1); /* normalized to 0.0-1.0 range. */ + int r_monitor_index = 0; + QRectF destinationF = QRectF(0, 0, 1, 1); /* normalized to 0.0-1.0 range. */ protected: - bool eventDelegate(QEvent *event, bool &result); - void drawStatusBarIcons(QPainter* painter); + bool eventDelegate(QEvent *event, bool &result); + void drawStatusBarIcons(QPainter *painter); QRect source { 0, 0, 0, 0 }; QRect destination; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index ad8172d1183..41d17d8971b 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -35,7 +35,9 @@ #include #include +#ifdef TOUCH_PR #include +#endif #include #include @@ -75,14 +77,14 @@ extern "C" { struct mouseinputdata { atomic_bool mouse_tablet_in_proximity; - char *mouse_type; + char *mouse_type; }; static mouseinputdata mousedata; extern MainWindow *main_window; #ifdef Q_OS_WINDOWS -HWND rw_hwnd; +HWND rw_hwnd; #endif RendererStack::RendererStack(QWidget *parent, int monitor_index) @@ -91,10 +93,12 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) , ui(new Ui::RendererStack) { boxLayout->setContentsMargins(0, 0, 0, 0); +#ifdef TOUCH_PR setAttribute(Qt::WA_AcceptTouchEvents, true); +#endif #ifdef Q_OS_WINDOWS setAttribute(Qt::WA_NativeWindow, true); - (void)winId(); + (void) winId(); #endif rendererTakesScreenshots = false; #ifdef Q_OS_WINDOWS @@ -107,18 +111,17 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) m_monitor_index = monitor_index; - if (monitor_index >= 1) { - QTimer* frameRateTimer = new QTimer(this); + QTimer *frameRateTimer = new QTimer(this); frameRateTimer->setSingleShot(false); frameRateTimer->setInterval(1000); connect(frameRateTimer, &QTimer::timeout, [this] { - this->setWindowTitle(QObject::tr("86Box Monitor #") + QString::number(m_monitor_index + 1) + QString(" - ") + tr("%1 Hz").arg(QString::number(monitors[m_monitor_index].mon_actualrenderedframes.load()) + (monitors[m_monitor_index].mon_interlace ? "i" : ""))); + this->setWindowTitle(QObject::tr("86Box Monitor #%1").arg(m_monitor_index + 1) + QString(" - ") + tr("%1 Hz").arg(QString::number(monitors[m_monitor_index].mon_actualrenderedframes.load()) + (monitors[m_monitor_index].mon_interlace ? "i" : ""))); }); frameRateTimer->start(1000); } #if defined __unix__ && !defined __HAIKU__ - memset(auto_mouse_type, 0, sizeof (auto_mouse_type)); + memset(auto_mouse_type, 0, sizeof(auto_mouse_type)); mousedata.mouse_type = getenv("EMU86BOX_MOUSE"); if (!mousedata.mouse_type || (mousedata.mouse_type[0] == '\0') || !stricmp(mousedata.mouse_type, "auto")) { if (QApplication::platformName().contains("wayland")) @@ -159,7 +162,7 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) RendererStack::~RendererStack() { - while (QApplication::overrideCursor()) + while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); delete ui; } @@ -169,7 +172,8 @@ qt_mouse_capture(int on) { if (!on) { mouse_capture = 0; - while (QApplication::overrideCursor()) QApplication::restoreOverrideCursor(); + while (QApplication::overrideCursor()) + QApplication::restoreOverrideCursor(); #ifdef __APPLE__ CGAssociateMouseAndMouseCursorPosition(true); #endif @@ -188,7 +192,7 @@ void RendererStack::mouseReleaseEvent(QMouseEvent *event) { #ifdef Q_OS_WINDOWS - rw_hwnd = (HWND) this->winId(); + rw_hwnd = (HWND) this->winId(); #endif event->accept(); @@ -197,9 +201,7 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event) #else if (!dopause && this->geometry().contains(m_monitor_index >= 1 ? event->globalPos() : event->pos()) && #endif - (event->button() == Qt::LeftButton) && !mouse_capture && - (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && - (mouse_input_mode == 0)) { + (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_input_mode == 0)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); if (!ignoreNextMouseEvent) @@ -215,15 +217,13 @@ RendererStack::mouseReleaseEvent(QMouseEvent *event) } if (mouse_capture || (mouse_input_mode >= 1)) { #ifdef Q_OS_WINDOWS - if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - ((m_monitor_index < 1) && (mouse_input_mode >= 1))) -#else -#ifndef __APPLE__ - if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - (m_monitor_index < 1)) + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || ((m_monitor_index < 1) && (mouse_input_mode >= 1))) #else +# ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || (m_monitor_index < 1)) +# else if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) -#endif +# endif #endif mouse_set_buttons_ex(mouse_get_buttons_ex() & ~event->button()); } @@ -236,15 +236,13 @@ RendererStack::mousePressEvent(QMouseEvent *event) isMouseDown |= 1; if (mouse_capture || (mouse_input_mode >= 1)) { #ifdef Q_OS_WINDOWS - if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - ((m_monitor_index < 1) && (mouse_input_mode >= 1))) -#else -#ifndef __APPLE__ - if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || - (m_monitor_index < 1)) + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || ((m_monitor_index < 1) && (mouse_input_mode >= 1))) #else +# ifndef __APPLE__ + if (((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) || (m_monitor_index < 1)) +# else if ((m_monitor_index >= 1) && (mouse_input_mode >= 1) && mousedata.mouse_tablet_in_proximity) -#endif +# endif #endif mouse_set_buttons_ex(mouse_get_buttons_ex() | event->button()); } @@ -260,7 +258,7 @@ RendererStack::wheelEvent(QWheelEvent *event) } #if !defined(Q_OS_WINDOWS) && !defined(__APPLE__) - double numSteps = (double) event->angleDelta().y() / 120.0; + double numSteps = (double) event->angleDelta().y() / 120.0; double numStepsW = (double) event->angleDelta().x() / 120.0; mouse_set_z((int) numSteps); @@ -292,18 +290,18 @@ RendererStack::mouseMoveEvent(QMouseEvent *event) return; } -#if defined __unix__ && !defined __HAIKU__ +# if defined __unix__ && !defined __HAIKU__ if (!stricmp(mousedata.mouse_type, "wayland")) mouse_scale(event->pos().x() - oldPos.x(), event->pos().y() - oldPos.y()); -#endif +# endif if (QApplication::platformName() == "eglfs") { leaveEvent((QEvent *) event); ignoreNextMouseEvent--; } -#if !defined _WIN32 +# if !defined _WIN32 QCursor::setPos(mapToGlobal(QPoint(width() / 2, height() / 2))); -#endif +# endif ignoreNextMouseEvent = 2; oldPos = event->pos(); #endif @@ -347,7 +345,7 @@ RendererStack::leaveEvent(QEvent *event) void RendererStack::switchRenderer(Renderer renderer) { - //startblit(); + // startblit(); switchInProgress = true; if (current) { rendererWindow->finalize(); @@ -385,12 +383,12 @@ RendererStack::createRenderer(Renderer renderer) { this->createWinId(); this->rendererTakesScreenshots = true; - auto hw = new OpenGLRenderer(this); - rendererWindow = hw; + auto hw = new OpenGLRenderer(this); + rendererWindow = hw; connect(this, &RendererStack::blitToRenderer, hw, &OpenGLRenderer::onBlit, Qt::QueuedConnection); connect(hw, &OpenGLRenderer::initialized, [=]() { /* Buffers are available only after initialization. */ - imagebufs = rendererWindow->getBuffers(); + imagebufs = rendererWindow->getBuffers(); switchInProgress = false; emit rendererChanged(); }); @@ -422,7 +420,7 @@ RendererStack::createRenderer(Renderer renderer) connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection); connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() { /* Buffers are available only after initialization. */ - imagebufs = rendererWindow->getBuffers(); + imagebufs = rendererWindow->getBuffers(); switchInProgress = false; emit rendererChanged(); }); @@ -456,7 +454,7 @@ RendererStack::createRenderer(Renderer renderer) currentBuf = 0; if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) { - imagebufs = rendererWindow->getBuffers(); + imagebufs = rendererWindow->getBuffers(); switchInProgress = false; emit rendererChanged(); } @@ -466,10 +464,7 @@ RendererStack::createRenderer(Renderer renderer) void RendererStack::blit(int x, int y, int w, int h) { - if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || - (w > 2048) || (h > 2048) || (switchInProgress) || - (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || - std::get(imagebufs[currentBuf])->test_and_set()) { + if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || ((w + y) > 2048) || ((h + x) > 2048) || (switchInProgress) || (monitors[m_monitor_index].target_buffer == NULL) || imagebufs.empty() || std::get(imagebufs[currentBuf])->test_and_set()) { video_blit_complete_monitor(m_monitor_index); return; } @@ -513,48 +508,99 @@ RendererStack::changeEvent(QEvent *event) } bool -RendererStack::event(QEvent* event) +RendererStack::event(QEvent *event) { if (event->type() == QEvent::MouseMove) { - QMouseEvent* mouse_event = (QMouseEvent*)event; + QMouseEvent *mouse_event = (QMouseEvent *) event; if (m_monitor_index >= 1) { if (mouse_input_mode >= 1) { +#ifdef TOUCH_PR #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - mouse_x_abs = (mouse_event->position().x()) / (double)width(); - mouse_y_abs = (mouse_event->position().y()) / (double)height(); + mouse_x_abs = (mouse_event->position().x()) / (double) width(); + mouse_y_abs = (mouse_event->position().y()) / (double) height(); #else - mouse_x_abs = (mouse_event->localPos().x()) / (double)width(); - mouse_y_abs = (mouse_event->localPos().y()) / (double)height(); + mouse_x_abs = (mouse_event->localPos().x()) / (double) width(); + mouse_y_abs = (mouse_event->localPos().y()) / (double) height(); +#endif +#else +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + mouse_x_abs = (mouse_event->position().x()) / (long double)width(); + mouse_y_abs = (mouse_event->position().y()) / (long double)height(); +#else + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); +#endif #endif if (!mouse_tablet_in_proximity) mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; mouse_x_abs -= rendererWindow->destinationF.left(); mouse_y_abs -= rendererWindow->destinationF.top(); - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; mouse_x_abs /= rendererWindow->destinationF.width(); mouse_y_abs /= rendererWindow->destinationF.height(); - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; } return QWidget::event(event); } +#ifdef TOUCH_PR #ifdef Q_OS_WINDOWS if (mouse_input_mode == 0) { +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + mouse_x_abs = (mouse_event->position().x()) / (double) width(); + mouse_y_abs = (mouse_event->position().y()) / (double) height(); +# else + mouse_x_abs = (mouse_event->localPos().x()) / (double) width(); + mouse_y_abs = (mouse_event->localPos().y()) / (double) height(); +# endif + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); + + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; + + mouse_x_abs /= rendererWindow->destinationF.width(); + mouse_y_abs /= rendererWindow->destinationF.height(); + + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; + return QWidget::event(event); + } +#endif + #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - mouse_x_abs = (mouse_event->position().x()) / (double)width(); - mouse_y_abs = (mouse_event->position().y()) / (double)height(); + mouse_x_abs = (mouse_event->position().x()) / (double) width(); + mouse_y_abs = (mouse_event->position().y()) / (double) height(); #else - mouse_x_abs = (mouse_event->localPos().x()) / (double)width(); - mouse_y_abs = (mouse_event->localPos().y()) / (double)height(); + mouse_x_abs = (mouse_event->localPos().x()) / (double) width(); + mouse_y_abs = (mouse_event->localPos().y()) / (double) height(); #endif - mouse_x_abs -= rendererWindow->destinationF.left(); - mouse_y_abs -= rendererWindow->destinationF.top(); +#else +#ifdef Q_OS_WINDOWS + if (mouse_input_mode == 0) { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + mouse_x_abs = (mouse_event->position().x()) / (long double)width(); + mouse_y_abs = (mouse_event->position().y()) / (long double)height(); +#else + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); +#endif + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); if (mouse_x_abs < 0) mouse_x_abs = 0; if (mouse_y_abs < 0) mouse_y_abs = 0; @@ -569,123 +615,151 @@ RendererStack::event(QEvent* event) #endif #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - mouse_x_abs = (mouse_event->position().x()) / (double)width(); - mouse_y_abs = (mouse_event->position().y()) / (double)height(); + mouse_x_abs = (mouse_event->position().x()) / (long double)width(); + mouse_y_abs = (mouse_event->position().y()) / (long double)height(); #else - mouse_x_abs = (mouse_event->localPos().x()) / (double)width(); - mouse_y_abs = (mouse_event->localPos().y()) / (double)height(); + mouse_x_abs = (mouse_event->localPos().x()) / (long double)width(); + mouse_y_abs = (mouse_event->localPos().y()) / (long double)height(); +#endif #endif mouse_x_abs -= rendererWindow->destinationF.left(); mouse_y_abs -= rendererWindow->destinationF.top(); - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; mouse_x_abs /= rendererWindow->destinationF.width(); mouse_y_abs /= rendererWindow->destinationF.height(); - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; mouse_tablet_in_proximity = mousedata.mouse_tablet_in_proximity; - } else switch (event->type()) { - case QEvent::TouchBegin: - case QEvent::TouchUpdate: - { +#ifdef TOUCH_PR + } else + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QTouchEvent* touchevent = (QTouchEvent*)event; - if (mouse_input_mode == 0) break; - if (touchevent->touchPoints().count()) { - mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double)width(); - mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double)height(); - mouse_x_abs -= rendererWindow->destinationF.left(); - mouse_y_abs -= rendererWindow->destinationF.top(); - - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; - - mouse_x_abs /= rendererWindow->destinationF.width(); - mouse_y_abs /= rendererWindow->destinationF.height(); - - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; - } - mouse_set_buttons_ex(mouse_get_buttons_ex() | 1); - touchevent->accept(); - return true; + QTouchEvent *touchevent = (QTouchEvent *) event; + if (mouse_input_mode == 0) + break; + if (touchevent->touchPoints().count()) { + mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double) width(); + mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double) height(); + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); + + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; + + mouse_x_abs /= rendererWindow->destinationF.width(); + mouse_y_abs /= rendererWindow->destinationF.height(); + + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; + } + mouse_set_buttons_ex(mouse_get_buttons_ex() | 1); + touchevent->accept(); + return true; #else - QTouchEvent* touchevent = (QTouchEvent*)event; - if (mouse_input_mode == 0) break; - if (touchevent->pointCount()) { - mouse_x_abs = (touchevent->point(0).position().x()) / (double)width(); - mouse_y_abs = (touchevent->point(0).position().y()) / (double)height(); - mouse_x_abs -= rendererWindow->destinationF.left(); - mouse_y_abs -= rendererWindow->destinationF.top(); - - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; - - mouse_x_abs /= rendererWindow->destinationF.width(); - mouse_y_abs /= rendererWindow->destinationF.height(); - - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; - } - mouse_set_buttons_ex(mouse_get_buttons_ex() | 1); - touchevent->accept(); - return true; + QTouchEvent *touchevent = (QTouchEvent *) event; + if (mouse_input_mode == 0) + break; + if (touchevent->pointCount()) { + mouse_x_abs = (touchevent->point(0).position().x()) / (double) width(); + mouse_y_abs = (touchevent->point(0).position().y()) / (double) height(); + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); + + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; + + mouse_x_abs /= rendererWindow->destinationF.width(); + mouse_y_abs /= rendererWindow->destinationF.height(); + + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; + } + mouse_set_buttons_ex(mouse_get_buttons_ex() | 1); + touchevent->accept(); + return true; #endif - } - case QEvent::TouchEnd: - case QEvent::TouchCancel: - { + } + case QEvent::TouchEnd: + case QEvent::TouchCancel: + { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QTouchEvent* touchevent = (QTouchEvent*)event; - if (mouse_input_mode == 0) break; - if (touchevent->touchPoints().count()) { - mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double)width(); - mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double)height(); - mouse_x_abs -= rendererWindow->destinationF.left(); - mouse_y_abs -= rendererWindow->destinationF.top(); - - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; - - mouse_x_abs /= rendererWindow->destinationF.width(); - mouse_y_abs /= rendererWindow->destinationF.height(); - - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; - } - mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1); - touchevent->accept(); - return true; + QTouchEvent *touchevent = (QTouchEvent *) event; + if (mouse_input_mode == 0) + break; + if (touchevent->touchPoints().count()) { + mouse_x_abs = (touchevent->touchPoints()[0].pos().x()) / (double) width(); + mouse_y_abs = (touchevent->touchPoints()[0].pos().y()) / (double) height(); + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); + + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; + + mouse_x_abs /= rendererWindow->destinationF.width(); + mouse_y_abs /= rendererWindow->destinationF.height(); + + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; + } + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1); + touchevent->accept(); + return true; #else - QTouchEvent* touchevent = (QTouchEvent*)event; - if (mouse_input_mode == 0) break; - if (touchevent->pointCount()) { - mouse_x_abs = (touchevent->point(0).position().x()) / (double)width(); - mouse_y_abs = (touchevent->point(0).position().y()) / (double)height(); - mouse_x_abs -= rendererWindow->destinationF.left(); - mouse_y_abs -= rendererWindow->destinationF.top(); - - if (mouse_x_abs < 0) mouse_x_abs = 0; - if (mouse_y_abs < 0) mouse_y_abs = 0; - - mouse_x_abs /= rendererWindow->destinationF.width(); - mouse_y_abs /= rendererWindow->destinationF.height(); - - if (mouse_x_abs > 1) mouse_x_abs = 1; - if (mouse_y_abs > 1) mouse_y_abs = 1; - } - mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1); - touchevent->accept(); - return true; + QTouchEvent *touchevent = (QTouchEvent *) event; + if (mouse_input_mode == 0) + break; + if (touchevent->pointCount()) { + mouse_x_abs = (touchevent->point(0).position().x()) / (double) width(); + mouse_y_abs = (touchevent->point(0).position().y()) / (double) height(); + mouse_x_abs -= rendererWindow->destinationF.left(); + mouse_y_abs -= rendererWindow->destinationF.top(); + + if (mouse_x_abs < 0) + mouse_x_abs = 0; + if (mouse_y_abs < 0) + mouse_y_abs = 0; + + mouse_x_abs /= rendererWindow->destinationF.width(); + mouse_y_abs /= rendererWindow->destinationF.height(); + + if (mouse_x_abs > 1) + mouse_x_abs = 1; + if (mouse_y_abs > 1) + mouse_y_abs = 1; + } + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~1); + touchevent->accept(); + return true; #endif - } + } - default: - return QWidget::event(event); - } + default: + return QWidget::event(event); +#endif /*TOUCH_PR*/ + } return QWidget::event(event); } @@ -703,7 +777,7 @@ RendererStack::onResize(int width, int height) #ifdef Q_OS_WINDOWS if (mouse_capture) { RECT rect; - if (GetWindowRect((HWND)this->winId(), &rect)) { + if (GetWindowRect((HWND) this->winId(), &rect)) { ClipCursor(&rect); } } diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index a3a8d47f738..02bf85a85eb 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -24,9 +24,8 @@ namespace Ui { class RendererStack; } -extern "C" -{ - extern int vid_resize; +extern "C" { +extern int vid_resize; } class RendererCommon; @@ -54,16 +53,18 @@ class RendererStack : public QWidget { if (this->m_monitor_index != 0 && vid_resize != 1) { int newX = pos().x(); int newY = pos().y(); - + if (((frameGeometry().x() + event->size().width() + 1) > util::screenOfWidget(this)->availableGeometry().right())) { - //move(util::screenOfWidget(this)->availableGeometry().right() - size().width() - 1, pos().y()); + // move(util::screenOfWidget(this)->availableGeometry().right() - size().width() - 1, pos().y()); newX = util::screenOfWidget(this)->availableGeometry().right() - frameGeometry().width() - 1; - if (newX < 1) newX = 1; + if (newX < 1) + newX = 1; } - + if (((frameGeometry().y() + event->size().height() + 1) > util::screenOfWidget(this)->availableGeometry().bottom())) { newY = util::screenOfWidget(this)->availableGeometry().bottom() - frameGeometry().height() - 1; - if (newY < 1) newY = 1; + if (newY < 1) + newY = 1; } move(newX, newY); } @@ -77,7 +78,7 @@ class RendererStack : public QWidget { { event->ignore(); } - bool event(QEvent* event) override; + bool event(QEvent *event) override; enum class Renderer { Software, @@ -99,12 +100,12 @@ class RendererStack : public QWidget { void setFocusRenderer(); void onResize(int width, int height); - QWidget* currentWidget() { return current.get(); } + QWidget *currentWidget() { return current.get(); } void (*mouse_capture_func)(QWindow *window) = nullptr; void (*mouse_uncapture_func)() = nullptr; - void (*mouse_exit_func)() = nullptr; + void (*mouse_exit_func)() = nullptr; signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); @@ -116,7 +117,7 @@ public slots: private: void createRenderer(Renderer renderer); - QBoxLayout* boxLayout = nullptr; + QBoxLayout *boxLayout = nullptr; Ui::RendererStack *ui; @@ -139,7 +140,7 @@ public slots: std::unique_ptr current; std::atomic_bool rendererTakesScreenshots; - std::atomic_bool switchInProgress{false}; + std::atomic_bool switchInProgress { false }; char auto_mouse_type[16]; }; diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index d892053f898..3920aaeb269 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -187,8 +187,7 @@ Settings::Settings(QWidget *parent) &SettingsOtherRemovable::reloadBusChannels_MO); connect(ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, this, - [this](const QModelIndex ¤t, const QModelIndex &previous) { - ui->stackedWidget->setCurrentIndex(current.row()); }); + [this](const QModelIndex ¤t, const QModelIndex &previous) { ui->stackedWidget->setCurrentIndex(current.row()); }); ui->listView->setCurrentIndex(model->index(0, 0)); @@ -224,14 +223,12 @@ 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.")), + 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); }); + QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { confirm_save = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); if (questionbox.result() == QMessageBox::Cancel) { confirm_save = true; diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index 9cfe6c8ac93..aee57da1bdb 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -47,7 +47,7 @@ SettingsBusTracking::next_free_mke_channel() uint8_t ret = CHANNEL_NONE; for (uint8_t i = 0; i < 4; i++) { - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(mke_tracking & mask)) { ret = (uint8_t) i; @@ -65,7 +65,7 @@ SettingsBusTracking::next_free_mfm_channel() uint8_t ret = CHANNEL_NONE; for (uint8_t i = 0; i < 2; i++) { - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(mfm_tracking & mask)) { ret = (uint8_t) i; @@ -83,7 +83,7 @@ SettingsBusTracking::next_free_esdi_channel() uint8_t ret = CHANNEL_NONE; for (uint8_t i = 0; i < 2; i++) { - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(esdi_tracking & mask)) { ret = (uint8_t) i; @@ -101,7 +101,7 @@ SettingsBusTracking::next_free_xta_channel() uint8_t ret = CHANNEL_NONE; for (uint8_t i = 0; i < 2; i++) { - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(xta_tracking & mask)) { ret = (uint8_t) i; @@ -236,7 +236,9 @@ SettingsBusTracking::scsi_bus_full() return (count == 64); } -QList SettingsBusTracking::busChannelsInUse(const int bus) { +QList +SettingsBusTracking::busChannelsInUse(const int bus) +{ QList channelsInUse; int element; @@ -277,7 +279,7 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { case HDD_BUS_IDE: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); if (ide_tracking[element] & mask) channelsInUse.append(i); } @@ -285,7 +287,7 @@ QList SettingsBusTracking::busChannelsInUse(const int bus) { case HDD_BUS_ATAPI: for (uint8_t i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); + mask = ((uint64_t) 0xffULL) << ((uint64_t) ((i << 3) & 0x3f)); if (ide_tracking[element] & mask) channelsInUse.append(i); } diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 8e3a725890c..6df4d5edc51 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -43,10 +43,10 @@ SettingsDisplay::SettingsDisplay(QWidget *parent) { ui->setupUi(this); - for (uint8_t i = 0; i < GFXCARD_MAX; i ++) + for (uint8_t i = 0; i < GFXCARD_MAX; i++) videoCard[i] = gfxcard[i]; - ui->lineEdit->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid", "txt" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + ui->lineEditCustomEDID->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid", "txt" }) % tr("All files") % util::DlgFilter({ "*" }, true)); onCurrentMachineChanged(machine); } @@ -67,7 +67,7 @@ SettingsDisplay::save() } #else gfxcard[0] = ui->comboBoxVideo->currentData().toInt(); - for (uint8_t i = 1; i < GFXCARD_MAX; i ++) + for (uint8_t i = 1; i < GFXCARD_MAX; i++) gfxcard[i] = ui->comboBoxVideoSecondary->currentData().toInt(); #endif @@ -77,7 +77,7 @@ SettingsDisplay::save() da2_standalone_enabled = ui->checkBoxDa2->isChecked() ? 1 : 0; monitor_edid = ui->radioButtonCustom->isChecked() ? 1 : 0; - strncpy(monitor_edid_path, ui->lineEdit->fileName().toUtf8().data(), sizeof(monitor_edid_path) - 1); + strncpy(monitor_edid_path, ui->lineEditCustomEDID->fileName().toUtf8().data(), sizeof(monitor_edid_path) - 1); } void @@ -129,21 +129,21 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) } ui->comboBoxVideo->setCurrentIndex(selectedRow); // TODO - for (uint8_t i = 1; i < GFXCARD_MAX; i ++) + for (uint8_t i = 1; i < GFXCARD_MAX; i++) if (gfxcard[i] == 0) ui->pushButtonConfigureVideoSecondary->setEnabled(false); ui->radioButtonDefault->setChecked(monitor_edid == 0); ui->radioButtonCustom->setChecked(monitor_edid == 1); - ui->lineEdit->setFileName(monitor_edid_path); - ui->lineEdit->setEnabled(monitor_edid == 1); + ui->lineEditCustomEDID->setFileName(monitor_edid_path); + ui->lineEditCustomEDID->setEnabled(monitor_edid == 1); } void SettingsDisplay::on_pushButtonConfigureVideo_clicked() { - int videoCard = ui->comboBoxVideo->currentData().toInt(); - auto *device = video_card_getdevice(videoCard); + int videoCard = ui->comboBoxVideo->currentData().toInt(); + auto *device = video_card_getdevice(videoCard); if (videoCard == VID_INTERNAL) device = machine_get_vid_device(machineId); DeviceConfig::ConfigureDevice(device); @@ -185,11 +185,10 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) return; static QRegularExpression voodooRegex("3dfx|voodoo|banshee|raven", QRegularExpression::CaseInsensitiveOption); - auto curVideoCard_2 = videoCard[1]; - videoCard[0] = ui->comboBoxVideo->currentData().toInt(); + auto curVideoCard_2 = videoCard[1]; + videoCard[0] = ui->comboBoxVideo->currentData().toInt(); if (videoCard[0] == VID_INTERNAL) - ui->pushButtonConfigureVideo->setEnabled(machine_has_flags(machineId, MACHINE_VIDEO) && - device_has_config(machine_get_vid_device(machineId))); + ui->pushButtonConfigureVideo->setEnabled(machine_has_flags(machineId, MACHINE_VIDEO) && device_has_config(machine_get_vid_device(machineId))); else ui->pushButtonConfigureVideo->setEnabled(video_card_has_config(videoCard[0]) > 0); bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; @@ -203,7 +202,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool machineSupports8514 = ((machineHasIsa16 || machineHasMca) && !videoCardHas8514); bool machineSupportsXga = ((machineHasMca && device_available(&xga_device)) && !videoCardHasXga); - bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device); + bool machineSupportsDa2 = machineHasMca && device_available(&ps55da2_device); ui->checkBox8514->setEnabled(machineSupports8514); ui->checkBox8514->setChecked(ibm8514_standalone_enabled && machineSupports8514); @@ -322,30 +321,32 @@ SettingsDisplay::on_pushButtonConfigureVideoSecondary_clicked() DeviceConfig::ConfigureDevice(device); } -void SettingsDisplay::on_radioButtonDefault_clicked() +void +SettingsDisplay::on_radioButtonDefault_clicked() { ui->radioButtonDefault->setChecked(true); ui->radioButtonCustom->setChecked(false); - ui->lineEdit->setEnabled(false); + ui->lineEditCustomEDID->setEnabled(false); } - -void SettingsDisplay::on_radioButtonCustom_clicked() +void +SettingsDisplay::on_radioButtonCustom_clicked() { ui->radioButtonDefault->setChecked(false); ui->radioButtonCustom->setChecked(true); - ui->lineEdit->setEnabled(true); + ui->lineEditCustomEDID->setEnabled(true); } -void SettingsDisplay::on_pushButtonExportDefault_clicked() +void +SettingsDisplay::on_pushButtonExportDefault_clicked() { auto str = QFileDialog::getSaveFileName(this, tr("Export EDID")); if (!str.isEmpty()) { QFile file(str); if (file.open(QFile::WriteOnly)) { uint8_t *bytes = nullptr; - auto size = ddc_create_default_edid(&bytes); - file.write((char*)bytes, size); + auto size = ddc_create_default_edid(&bytes); + file.write((char *) bytes, size); file.close(); } } diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 8854b037353..d74aabfffbd 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -48,7 +48,7 @@ private slots: private: Ui::SettingsDisplay *ui; - int machineId = 0; + int machineId = 0; int videoCard[VIDEOCARD_MAX] = { 0, 0 }; }; diff --git a/src/qt/qt_settingsdisplay.ui b/src/qt/qt_settingsdisplay.ui index 6e4c1415206..5ab71f4c0a9 100644 --- a/src/qt/qt_settingsdisplay.ui +++ b/src/qt/qt_settingsdisplay.ui @@ -26,24 +26,42 @@ 0 - - + + + + + 0 + 0 + + - Voodoo 1 or 2 Graphics + Video: - - - - Configure + + + + + 0 + 0 + + + + 30 - - + + + + + 0 + 0 + + - IBM 8514/A Graphics + Configure @@ -60,6 +78,47 @@ + + + + + 0 + 0 + + + + 30 + + + + + + + Configure + + + + + + + Voodoo 1 or 2 Graphics + + + + + + + Configure + + + + + + + IBM 8514/A Graphics + + + @@ -67,6 +126,13 @@ + + + + XGA Graphics + + + @@ -74,8 +140,22 @@ + + + + IBM PS/55 Display Adapter Graphics + + + + + + + Configure + + + - + 0 @@ -85,9 +165,9 @@ Monitor EDID - + - + @@ -111,9 +191,9 @@ - + - QLayout::SizeConstraint::SetNoConstraint + QLayout::SetNoConstraint @@ -123,7 +203,7 @@ - + 0 @@ -137,23 +217,20 @@ - - + + - + 0 0 - - 30 - - Qt::Orientation::Vertical + Qt::Vertical @@ -163,83 +240,6 @@ - - - - Configure - - - - - - - - 0 - 0 - - - - Configure - - - - - - - - 0 - 0 - - - - Video: - - - - - - - Configure - - - - - - - - 0 - 0 - - - - 30 - - - - - - - XGA Graphics - - - - - - - IBM PS/55 Display Adapter Graphics - - - - - - - - 0 - 0 - - - - @@ -250,6 +250,23 @@ 1 + + comboBoxVideo + pushButtonConfigureVideo + comboBoxVideoSecondary + pushButtonConfigureVideoSecondary + checkBoxVoodoo + pushButtonConfigureVoodoo + checkBox8514 + pushButtonConfigure8514 + checkBoxXga + pushButtonConfigureXga + checkBoxDa2 + pushButtonConfigureDa2 + radioButtonDefault + pushButtonExportDefault + radioButtonCustom + diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index b1b099b62d1..8fcad3f210e 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -114,8 +114,8 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) ui->setupUi(this); floppy_disabled_icon = QIcon(":/settings/qt/icons/floppy_disabled.ico"); - floppy_525_icon = QIcon(":/settings/qt/icons/floppy_525.ico"); - floppy_35_icon = QIcon(":/settings/qt/icons/floppy_35.ico"); + floppy_525_icon = QIcon(":/settings/qt/icons/floppy_525.ico"); + floppy_35_icon = QIcon(":/settings/qt/icons/floppy_35.ico"); auto *model = ui->comboBoxFloppyType->model(); int i = 0; @@ -135,7 +135,7 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) model->setHeaderData(2, Qt::Horizontal, tr("Check BPB")); model->setHeaderData(3, Qt::Horizontal, tr("Audio")); -model->insertRows(0, FDD_NUM); + model->insertRows(0, FDD_NUM); /* Floppy drives category */ for (int i = 0; i < FDD_NUM; i++) { auto idx = model->index(i, 0); @@ -169,7 +169,7 @@ model->insertRows(0, FDD_NUM); connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onFloppyRowChanged); - + #ifndef DISABLE_FDD_AUDIO ui->comboBoxFloppyAudio->setVisible(true); int profile_count = fdd_audio_get_profile_count(); @@ -190,7 +190,7 @@ model->insertRows(0, FDD_NUM); onFloppyRowChanged(model->index(0, 0)); cdrom_disabled_icon = QIcon(":/settings/qt/icons/cdrom_disabled.ico"); - cdrom_icon = QIcon(":/settings/qt/icons/cdrom.ico"); + cdrom_icon = QIcon(":/settings/qt/icons/cdrom.ico"); Harddrives::populateCDROMBuses(ui->comboBoxBus->model()); model = ui->comboBoxSpeed->model(); @@ -204,8 +204,8 @@ model->insertRows(0, FDD_NUM); model->setHeaderData(2, Qt::Horizontal, tr("Type")); model->insertRows(0, CDROM_NUM); for (int i = 0; i < CDROM_NUM; i++) { - auto idx = model->index(i, 0); - int type = cdrom_get_type(i); + auto idx = model->index(i, 0); + int type = cdrom_get_type(i); setCDROMBus(model, idx, cdrom[i].bus_type, cdrom[i].res); setCDROMType(model, idx.siblingAtColumn(2), type); int speed = cdrom_get_speed(type); @@ -230,19 +230,16 @@ model->insertRows(0, FDD_NUM); ui->tableViewCDROM->setCurrentIndex(model->index(0, 0)); uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); - int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); + int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); auto *modelType = ui->comboBoxCDROMType->model(); int removeRows = modelType->rowCount(); uint32_t j = 0; - int selectedTypeRow = 0; - int eligibleRows = 0; + int selectedTypeRow = 0; + int eligibleRows = 0; while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { - if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) || - (bus_type == CDROM_BUS_SCSI)) && - ((cdrom_drive_types[j].bus_type == bus_type) || - ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { + if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus_type) || ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (cdrom[cdromIdx].type == j) @@ -278,16 +275,16 @@ SettingsFloppyCDROM::save() /* Removable devices category */ model = ui->tableViewCDROM->model(); for (int i = 0; i < CDROM_NUM; i++) { - cdrom[i].priv = NULL; - cdrom[i].ops = NULL; - cdrom[i].local = NULL; - cdrom[i].insert = NULL; - cdrom[i].close = NULL; - cdrom[i].get_volume = NULL; + cdrom[i].priv = NULL; + cdrom[i].ops = NULL; + cdrom[i].local = 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(); + 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(); cdrom_set_type(i, model->index(i, 2).data(Qt::UserRole).toInt()); } @@ -307,8 +304,66 @@ SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) ui->checkBoxCheckBPB->setChecked(current.siblingAtColumn(2).data() == tr("On")); int prof = current.siblingAtColumn(3).data(Qt::UserRole).toInt(); + +#ifndef DISABLE_FDD_AUDIO + // Rebuild audio profile combo box based on drive type + ui->comboBoxFloppyAudio->clear(); + + if (type == 0) { + ui->comboBoxFloppyAudio->addItem(tr("None"), 0); + ui->comboBoxFloppyAudio->setCurrentIndex(0); + ui->comboBoxFloppyAudio->setEnabled(false); + + // Update the model to reflect "None" profile + auto audioIdx = current.siblingAtColumn(3); + ui->tableViewFloppy->model()->setData(audioIdx, tr("None")); + ui->tableViewFloppy->model()->setData(audioIdx, 0, Qt::UserRole); + return; + } + + ui->comboBoxFloppyAudio->setEnabled(true); + + // Get drive type's track count to determine 40-track vs 80-track + int drive_max_tracks = fdd_get_type_max_track(type); + bool is_40_track = (drive_max_tracks <= 43); + + int profile_count = fdd_audio_get_profile_count(); + int currentProfileIndex = -1; + int comboIndex = 0; + + for (int i = 0; i < profile_count; i++) { + const char *name = fdd_audio_get_profile_name(i); + if (name) { + const fdd_audio_profile_config_t *profile = fdd_audio_get_profile(i); + if (profile) { + // Only show profiles that match the drive type's track count + if (profile->total_tracks == 0 || + (is_40_track && profile->total_tracks == 40) || + (!is_40_track && profile->total_tracks == 80)) { + ui->comboBoxFloppyAudio->addItem(name, i); + if (i == prof) { + currentProfileIndex = comboIndex; + } + comboIndex++; + } + } + } + } + + // If current profile is not compatible, select "None" (profile 0) + if (currentProfileIndex == -1) { + currentProfileIndex = ui->comboBoxFloppyAudio->findData(0); + // Update the model to reflect "None" profile + auto audioIdx = current.siblingAtColumn(3); + ui->tableViewFloppy->model()->setData(audioIdx, tr("None")); + ui->tableViewFloppy->model()->setData(audioIdx, 0, Qt::UserRole); + } + + ui->comboBoxFloppyAudio->setCurrentIndex(currentProfileIndex); +#else int comboIndex = ui->comboBoxFloppyAudio->findData(prof); ui->comboBoxFloppyAudio->setCurrentIndex(comboIndex); +#endif } void @@ -319,9 +374,9 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) uint32_t type = current.siblingAtColumn(2).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()) + 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(); @@ -329,9 +384,9 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) if (!match.isEmpty()) ui->comboBoxChannel->setCurrentIndex(match.first().row()); - int speed = cdrom_get_speed(type); + int speed = cdrom_get_speed(type); if (speed == -1) { - speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); ui->comboBoxSpeed->setEnabled((bus == CDROM_BUS_DISABLED) ? false : true); } else ui->comboBoxSpeed->setEnabled(false); @@ -341,13 +396,10 @@ SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) int removeRows = modelType->rowCount(); uint32_t j = 0; - int selectedTypeRow = 0; - int eligibleRows = 0; + int selectedTypeRow = 0; + int eligibleRows = 0; while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { - if (((bus == CDROM_BUS_MKE) || (bus == CDROM_BUS_ATAPI) || - (bus == CDROM_BUS_SCSI)) && - ((cdrom_drive_types[j].bus_type == bus) || - ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus != BUS_TYPE_MKE)))) { + if (((bus == CDROM_BUS_MKE) || (bus == CDROM_BUS_ATAPI) || (bus == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus) || ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (type == j) @@ -368,24 +420,24 @@ 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")); + 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")); + 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); + auto currentIndex = ui->tableViewFloppy->selectionModel()->currentIndex(); + setFloppyType(ui->tableViewFloppy->model(), currentIndex, index); + + // Trigger row changed to rebuild audio profile list + onFloppyRowChanged(currentIndex); } void @@ -403,6 +455,9 @@ SettingsFloppyCDROM::on_comboBoxFloppyAudio_activated(int) } else { profName = tr("None"); } + if (prof > 0) { + load_profile_samples(prof); + } #else profName = tr("None"); #endif @@ -412,7 +467,9 @@ SettingsFloppyCDROM::on_comboBoxFloppyAudio_activated(int) ui->tableViewFloppy->model()->setData(audioIdx, prof, Qt::UserRole); } -void SettingsFloppyCDROM::reloadBusChannels() { +void +SettingsFloppyCDROM::reloadBusChannels() +{ auto selected = ui->comboBoxChannel->currentIndex(); Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); ui->comboBoxChannel->setCurrentIndex(selected); @@ -447,9 +504,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) uint8_t bus_type = ui->comboBoxBus->currentData().toUInt(); int cdromIdx = ui->tableViewCDROM->selectionModel()->currentIndex().data().toInt(); - Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, - Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, - Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); if (bus_type == CDROM_BUS_MKE) ui->comboBoxChannel->setCurrentIndex(Harddrives::busTrackClass->next_free_mke_channel()); else if (bus_type == CDROM_BUS_ATAPI) @@ -463,21 +518,16 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) ui->tableViewCDROM->selectionModel()->currentIndex(), bus_type, 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()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); auto *modelType = ui->comboBoxCDROMType->model(); int removeRows = modelType->rowCount(); - uint32_t j = 0; - int selectedTypeRow = 0; - int eligibleRows = 0; + uint32_t j = 0; + int selectedTypeRow = 0; + int eligibleRows = 0; while (cdrom_drive_types[j].bus_type != BUS_TYPE_NONE) { - if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) || - (bus_type == CDROM_BUS_SCSI)) && - ((cdrom_drive_types[j].bus_type == bus_type) || - ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { + if (((bus_type == CDROM_BUS_MKE) || (bus_type == CDROM_BUS_ATAPI) || (bus_type == CDROM_BUS_SCSI)) && ((cdrom_drive_types[j].bus_type == bus_type) || ((cdrom_drive_types[j].bus_type == BUS_TYPE_BOTH) && (bus_type != BUS_TYPE_MKE)))) { QString name = CDROMName(j); Models::AddEntry(modelType, name, j); if (cdrom[cdromIdx].type == j) @@ -502,7 +552,7 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) } else { ui->comboBoxSpeed->setEnabled(false); if (bus_type == CDROM_BUS_MITSUMI) // temp hack - speed = 0; + speed = 0; } ui->comboBoxSpeed->setCurrentIndex(speed == 0 ? 7 : speed - 1); setCDROMSpeed(ui->tableViewCDROM->model(), @@ -514,10 +564,10 @@ SettingsFloppyCDROM::on_comboBoxBus_activated(int) void SettingsFloppyCDROM::enableCurrentlySelectedChannel() { - const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); const auto index = ui->comboBoxChannel->currentIndex(); auto *item = item_model->item(index); - if(item) + if (item) item->setEnabled(true); } @@ -525,16 +575,12 @@ 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()); + 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()); + Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); emit cdromChannelChanged(); } diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 9a53dd88ff2..98ca73c2c08 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -35,12 +35,11 @@ private slots: void on_comboBoxSpeed_activated(int index); void on_comboBoxCDROMType_activated(int index); - private: Ui::SettingsFloppyCDROM *ui; - void setFloppyType(QAbstractItemModel *model, const QModelIndex &idx, int type); - void setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel); - void enableCurrentlySelectedChannel(); + void setFloppyType(QAbstractItemModel *model, const QModelIndex &idx, int type); + void setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel); + void enableCurrentlySelectedChannel(); QIcon floppy_disabled_icon; QIcon floppy_525_icon; diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index 3f0447dffc9..0f12c8e6f65 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -74,12 +74,12 @@ static void addRow(QAbstractItemModel *model, hard_disk_t *hd) { const QString userPath = usr_path; - int row = model->rowCount(); + int row = model->rowCount(); model->insertRow(row); - auto busIndex = model->index(row, ColumnBus); - QString busName = Harddrives::BusChannelName(hd->bus_type, hd->channel); + auto busIndex = model->index(row, ColumnBus); + QString busName = Harddrives::BusChannelName(hd->bus_type, hd->channel); model->setData(busIndex, busName); model->setData(busIndex, hard_disk_icon, Qt::DecorationRole); model->setData(busIndex, hd->bus_type, DataBus); @@ -87,8 +87,8 @@ addRow(QAbstractItemModel *model, hard_disk_t *hd) model->setData(busIndex, hd->channel, DataBusChannel); model->setData(busIndex, hd->channel, DataBusChannelPrevious); Harddrives::busTrackClass->device_track(1, DEV_HDD, hd->bus_type, hd->channel); - auto filenameIndex = model->index(row, ColumnFilename); - QString fileName = hd->fn; + auto filenameIndex = model->index(row, ColumnFilename); + QString fileName = hd->fn; if (fileName.startsWith(userPath, Qt::CaseInsensitive)) model->setData(filenameIndex, fileName.mid(userPath.size())); else @@ -169,7 +169,9 @@ SettingsHarddisks::save() } } -void SettingsHarddisks::reloadBusChannels() { +void +SettingsHarddisks::reloadBusChannels() +{ const auto selected = ui->comboBoxChannel->currentIndex(); Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt(), Harddrives::busTrackClass); ui->comboBoxChannel->setCurrentIndex(selected); @@ -248,10 +250,10 @@ SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) void SettingsHarddisks::enableCurrentlySelectedChannel() { - const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); - const auto index = ui->comboBoxChannel->currentIndex(); - auto *item = item_model->item(index); - if(item) + const auto *item_model = qobject_cast(ui->comboBoxChannel->model()); + const auto index = ui->comboBoxChannel->currentIndex(); + auto *item = item_model->item(index); + if (item) item->setEnabled(true); } @@ -359,8 +361,8 @@ SettingsHarddisks::on_pushButtonRemove_clicked() if (!idx.isValid()) return; - auto *model = ui->tableView->model(); - const auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + const auto col = idx.siblingAtColumn(ColumnBus); Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toInt()); model->removeRow(idx.row()); ui->pushButtonNew->setEnabled(true); diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index c540aa2edac..3ba74d37298 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -61,7 +61,7 @@ SettingsInput::SettingsInput(QWidget *parent) keyTable->setColumnWidth(0, 200); keyTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); QStringList headers; - //headers << "Action" << "Bound key"; + // headers << "Action" << "Bound key"; keyTable->setHorizontalHeaderLabels(horizontalHeader); keyTable->verticalHeader()->setVisible(false); keyTable->setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -71,7 +71,7 @@ SettingsInput::SettingsInput(QWidget *parent) // Make a working copy of acc_keys so we can check for dupes later without getting // confused - for(int x = 0; x < NUM_ACCELS; x++) { + for (int x = 0; x < NUM_ACCELS; x++) { strcpy(acc_keys_t[x].name, acc_keys[x].name); strcpy(acc_keys_t[x].desc, acc_keys[x].desc); strcpy(acc_keys_t[x].seq, acc_keys[x].seq); @@ -96,7 +96,7 @@ SettingsInput::save() joystick_type[0] = ui->comboBoxJoystick0->currentData().toInt(); // Copy accelerators from working set to global set - for(int x = 0; x < NUM_ACCELS; x++) { + for (int x = 0; x < NUM_ACCELS; x++) { strcpy(acc_keys[x].name, acc_keys_t[x].name); strcpy(acc_keys[x].desc, acc_keys_t[x].desc); strcpy(acc_keys[x].seq, acc_keys_t[x].seq); @@ -111,7 +111,7 @@ SettingsInput::onCurrentMachineChanged(int machineId) this->machineId = machineId; auto *keyboardModel = ui->comboBoxKeyboard->model(); - auto removeRows = keyboardModel->rowCount(); + auto removeRows = keyboardModel->rowCount(); int selectedRow = 0; @@ -119,11 +119,10 @@ SettingsInput::onCurrentMachineChanged(int machineId) int has_int_kbd = !!machine_has_flags(machineId, MACHINE_KEYBOARD); for (int i = 0; i < keyboard_get_ndev(); ++i) { - const auto *dev = keyboard_get_device(i); - int ikbd = (i == KEYBOARD_TYPE_INTERNAL); + const auto *dev = keyboard_get_device(i); + int ikbd = (i == KEYBOARD_TYPE_INTERNAL); - int pc5086_filter = (strstr(keyboard_get_internal_name(i), "ps") && - machines[machineId].init == machine_xt_pc5086_init); + int pc5086_filter = (strstr(keyboard_get_internal_name(i), "ps") && machines[machineId].init == machine_xt_pc5086_init); if ((ikbd != has_int_kbd) || !device_is_valid(dev, machineId) || pc5086_filter) continue; @@ -209,7 +208,7 @@ void SettingsInput::on_tableKeys_currentCellChanged(int currentRow, int currentColumn, int previousRow, int previousColumn) { // Enable/disable bind/clear buttons if user clicked valid row - QTableWidgetItem *cell = ui->tableKeys->item(currentRow,1); + QTableWidgetItem *cell = ui->tableKeys->item(currentRow, 1); if (!cell) { ui->pushButtonBind->setEnabled(false); ui->pushButtonClearBind->setEnabled(false); @@ -223,7 +222,7 @@ void SettingsInput::on_tableKeys_cellDoubleClicked(int row, int col) { // Edit bind - QTableWidgetItem *cell = ui->tableKeys->item(row,1); + QTableWidgetItem *cell = ui->tableKeys->item(row, 1); if (!cell) return; @@ -236,8 +235,8 @@ SettingsInput::on_tableKeys_cellDoubleClicked(int row, int col) // Otherwise, check for conflicts. // Check against the *working* copy - NOT the one in use by the app, // so we don't test against shortcuts the user already changed. - for(int x = 0; x < NUM_ACCELS; x++) { - if(QString::fromStdString(acc_keys_t[x].seq) == keyseq.toString(QKeySequence::PortableText)) { + for (int x = 0; x < NUM_ACCELS; x++) { + if (QString::fromStdString(acc_keys_t[x].seq) == keyseq.toString(QKeySequence::PortableText)) { // That key is already in use QMessageBox::warning(this, tr("Bind conflict"), tr("This key combo is already in use."), QMessageBox::StandardButton::Ok); return; @@ -247,7 +246,7 @@ SettingsInput::on_tableKeys_cellDoubleClicked(int row, int col) // Go ahead and apply the bind. // Find the correct accelerator key entry - int accKeyID = FindAccelerator(ui->tableKeys->item(row,2)->text().toUtf8().constData()); + int accKeyID = FindAccelerator(ui->tableKeys->item(row, 2)->text().toUtf8().constData()); if (accKeyID < 0) return; // this should never happen @@ -280,7 +279,7 @@ SettingsInput::on_pushButtonClearBind_clicked() cell->setText(""); // Find the correct accelerator key entry - int accKeyID = FindAccelerator(ui->tableKeys->item(cell->row(),2)->text().toUtf8().constData()); + int accKeyID = FindAccelerator(ui->tableKeys->item(cell->row(), 2)->text().toUtf8().constData()); if (accKeyID < 0) return; // this should never happen @@ -335,7 +334,7 @@ SettingsInput::on_pushButtonConfigureMouse_clicked() } static int -get_axis(JoystickConfiguration &jc, int axis, uint8_t gameport_nr, int joystick_nr) +get_axis(JoystickConfiguration &jc, uint8_t gameport_nr, int joystick_nr, int axis) { int axis_sel = jc.selectedAxis(axis); int nr_axes = plat_joystick_state[joystick_state[gameport_nr][joystick_nr].plat_joystick_nr - 1].nr_axes; @@ -351,7 +350,7 @@ get_axis(JoystickConfiguration &jc, int axis, uint8_t gameport_nr, int joystick_ } static int -get_pov(JoystickConfiguration &jc, int pov, uint8_t gameport_nr, int joystick_nr) +get_pov(JoystickConfiguration &jc, uint8_t gameport_nr, int joystick_nr, int pov) { int pov_sel = jc.selectedPov(pov); int nr_povs = plat_joystick_state[joystick_state[gameport_nr][joystick_nr].plat_joystick_nr - 1].nr_povs * 2; @@ -379,17 +378,15 @@ updateJoystickConfig(int type, uint8_t gameport_nr, int joystick_nr, QWidget *pa joystick_state[gameport_nr][joystick_nr].plat_joystick_nr = jc.selectedDevice(); if (joystick_state[gameport_nr][joystick_nr].plat_joystick_nr) { - for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) { - joystick_state[gameport_nr][joystick_nr].axis_mapping[axis_nr] = get_axis(jc, axis_nr, gameport_nr, joystick_nr); - } + for (int axis_nr = 0; axis_nr < joystick_get_axis_count(type); axis_nr++) + joystick_state[gameport_nr][joystick_nr].axis_mapping[axis_nr] = get_axis(jc, gameport_nr, joystick_nr, axis_nr); - for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) { + for (int button_nr = 0; button_nr < joystick_get_button_count(type); button_nr++) joystick_state[gameport_nr][joystick_nr].button_mapping[button_nr] = jc.selectedButton(button_nr); - } - for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type) * 2; pov_nr += 2) { - joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, pov_nr, gameport_nr, joystick_nr); - joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, pov_nr + 1, gameport_nr, joystick_nr); + for (int pov_nr = 0; pov_nr < joystick_get_pov_count(type); pov_nr++) { + joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][0] = get_pov(jc, gameport_nr, joystick_nr, pov_nr * 2); // X Axis + joystick_state[gameport_nr][joystick_nr].pov_mapping[pov_nr][1] = get_pov(jc, gameport_nr, joystick_nr, pov_nr * 2 + 1); // Y Axis } } } diff --git a/src/qt/qt_settingsinput.hpp b/src/qt/qt_settingsinput.hpp index 68748fa3626..d75c944323a 100644 --- a/src/qt/qt_settingsinput.hpp +++ b/src/qt/qt_settingsinput.hpp @@ -47,7 +47,7 @@ private slots: private: Ui::SettingsInput *ui; int machineId = 0; - void refreshInputList(); + void refreshInputList(); }; #endif // QT_SETTINGSINPUT_HPP diff --git a/src/qt/qt_settingsinput.ui b/src/qt/qt_settingsinput.ui index 02b3e388c68..e4c0dc8fae1 100644 --- a/src/qt/qt_settingsinput.ui +++ b/src/qt/qt_settingsinput.ui @@ -30,7 +30,7 @@ - + @@ -43,7 +43,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -96,40 +96,50 @@ - + 30 - - - - - - Joystick 1... - - - - - - - Joystick 2... - - - - - - - Joystick 3... + + + 0 + 0 + - - - - Joystick 4... - - + + + + + + Joystick 1... + + + + + + + Joystick 2... + + + + + + + Joystick 3... + + + + + + + Joystick 4... + + + + @@ -138,7 +148,7 @@ - + QAbstractItemView::NoEditTriggers @@ -157,25 +167,54 @@ - - - - false - - - Clear binding - - - - - - - false - - - Bind - - + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 100 + 0 + + + + Clear binding + + + + + + + false + + + + 100 + 0 + + + + Bind + + + + diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index ae03f4d38fa..e4faeb5ce9c 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -60,10 +60,10 @@ SettingsMachine::SettingsMachine(QWidget *parent) } auto machineListCompleter = new QCompleter(ui->lineEditSearch); - auto machineListModel = new QStandardItemModel(machineListCompleter); + auto machineListModel = new QStandardItemModel(machineListCompleter); machineListCompleter->setModel(machineListModel); ui->lineEditSearch->setCompleter(machineListCompleter); - connect(ui->lineEditSearch, &QLineEdit::editingFinished, this, [this] () { ui->lineEditSearch->setText("");} ); + connect(ui->lineEditSearch, &QLineEdit::editingFinished, this, [this]() { ui->lineEditSearch->setText(""); }); machineListCompleter->setCompletionMode(QCompleter::PopupCompletion); machineListCompleter->setFilterMode(Qt::MatchContains); machineListCompleter->setCompletionRole(Qt::DisplayRole); @@ -101,7 +101,7 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->comboBoxPitMode->setCurrentIndex(pit_mode + 1); int selectedMachineType = 0; - auto * machineTypesModel = ui->comboBoxMachineType->model(); + auto *machineTypesModel = ui->comboBoxMachineType->model(); int i = -1; int j = 0; int cur_j = 0; @@ -116,12 +116,12 @@ SettingsMachine::SettingsMachine(QWidget *parent) selectedMachineType = row; } - i = machine_get_type(j); + i = machine_get_type(j); cur_j = 0; } if (machine_available(j)) { - QStandardItem* item = new QStandardItem(machines[j].name); + QStandardItem *item = new QStandardItem(machines[j].name); item->setData(machine_types[machine_get_type(j)].id); machineListModel->appendRow(item); @@ -137,10 +137,10 @@ SettingsMachine::SettingsMachine(QWidget *parent) ui->radioButtonLargerFrames->setChecked(force_10ms); ui->radioButtonSmallerFrames->setChecked(!force_10ms); - connect(machineListCompleter, QOverload::of(&QCompleter::activated), this, [this] (const QModelIndex& idx) { + connect(machineListCompleter, QOverload::of(&QCompleter::activated), this, [this](const QModelIndex &idx) { ui->lineEditSearch->setText(""); - int machineIdType = idx.model()->data(idx, Qt::UserRole + 1).toInt(); - auto name = idx.model()->data(idx, Qt::DisplayRole).toString(); + int machineIdType = idx.model()->data(idx, Qt::UserRole + 1).toInt(); + auto name = idx.model()->data(idx, Qt::DisplayRole).toString(); for (int i = 0; i < ui->comboBoxMachineType->model()->rowCount(); i++) { if (ui->comboBoxMachineType->model()->data(ui->comboBoxMachineType->model()->index(i, 0), Qt::UserRole).toInt() == machineIdType) { ui->comboBoxMachineType->setCurrentIndex(i); @@ -215,8 +215,7 @@ SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) int selectedMachineRow = 0; for (int i = 0; i < machine_count(); ++i) { - if ((machine_get_type(i) == ui->comboBoxMachineType->currentData().toInt()) && - machine_available(i)) { + if ((machine_get_type(i) == ui->comboBoxMachineType->currentData().toInt()) && machine_available(i)) { int row = Models::AddEntry(model, machines[i].name, i); if (i == machine) selectedMachineRow = row - removeRows; @@ -246,8 +245,7 @@ SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) 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); + 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; @@ -346,7 +344,7 @@ SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) int i = 0; int selectedFpuRow = 0; - for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); + 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, tr(QString("%1").arg(fpuName).toUtf8().data()), fpuType); @@ -374,10 +372,8 @@ SettingsMachine::on_comboBoxFPU_currentIndexChanged(int index) ui->checkBoxFPUSoftfloat->setChecked(false); ui->checkBoxFPUSoftfloat->setEnabled(false); } else { - ui->checkBoxFPUSoftfloat->setChecked(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? - true : fpu_softfloat); - ui->checkBoxFPUSoftfloat->setEnabled(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? - false : true); + ui->checkBoxFPUSoftfloat->setChecked(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? true : fpu_softfloat); + ui->checkBoxFPUSoftfloat->setEnabled(machine_has_flags(machineId, MACHINE_SOFTFLOAT_ONLY) ? false : true); } } } @@ -391,8 +387,10 @@ SettingsMachine::on_pushButtonConfigure_clicked() DeviceConfig::ConfigureDevice(device); } -void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { - if(state == Qt::Checked) { +void +SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) +{ + if (state == Qt::Checked) { ui->softFloatWarningIcon->setVisible(true); ui->softFloatWarningText->setVisible(true); } else { @@ -401,13 +399,14 @@ void SettingsMachine::on_checkBoxFPUSoftfloat_stateChanged(int state) { } } -void SettingsMachine::on_radioButtonSmallerFrames_clicked() +void +SettingsMachine::on_radioButtonSmallerFrames_clicked() { ui->radioButtonLargerFrames->setChecked(false); } - -void SettingsMachine::on_radioButtonLargerFrames_clicked() +void +SettingsMachine::on_radioButtonLargerFrames_clicked() { ui->radioButtonSmallerFrames->setChecked(false); } diff --git a/src/qt/qt_settingsmachine.ui b/src/qt/qt_settingsmachine.ui index 34f0b61605d..fdfda37b6d0 100644 --- a/src/qt/qt_settingsmachine.ui +++ b/src/qt/qt_settingsmachine.ui @@ -41,40 +41,40 @@ 0 - - + + - Machine: + Search: - - + + + + + - CPU type: + Machine type: - - - - - 0 - 0 - + + + + 30 - - + + - Memory: + Machine: - - - + + + 0 @@ -88,47 +88,38 @@ 0 - - - - 0 - 0 - - + 30 - - - Frequency: - - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignVCenter - - - - - + - + 0 0 - - 30 + + Configure - - - + + + + CPU type: + + + + + + 0 @@ -142,7 +133,7 @@ 0 - + 0 @@ -155,14 +146,17 @@ - + - PIT mode: + Frequency: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + 0 @@ -177,17 +171,10 @@ - - + + - Machine type: - - - - - - - 30 + FPU: @@ -199,15 +186,15 @@ - + Wait states: - - - + + + 0 @@ -221,45 +208,58 @@ 0 - + + + + 0 + 0 + + 30 - + + + PIT mode: + + + + + - + 0 0 - - Configure + + 30 - - + + - FPU: + Memory: - - - - Search: + + + + + 0 + 0 + - - - @@ -312,7 +312,7 @@ - Qt::Orientation::Horizontal + Qt::Horizontal @@ -325,92 +325,116 @@ - - - - - - 0 - 0 - - - - CPU frame size - - - Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop - - - - - - Larger frames (less smooth) - - - - - - - Smaller frames (smoother) - - - - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - + + + + + + + + 0 + 0 + + + + Time synchronization + + + + + + Disabled + + + + + + + Enabled (local time) + + + + + + + Enabled (UTC) + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + - - - - - 0 - 0 - - - - Time synchronization - - - - - - Disabled - - - - - - - Enabled (local time) - - - - - - - Enabled (UTC) - - - - - + + + + + + + 0 + 0 + + + + CPU frame size + + + + + + Larger frames (less smooth) + + + + + + + Smaller frames (smoother) + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 40 + + + + + - - + + - Qt::Orientation::Horizontal + Qt::Horizontal @@ -422,19 +446,6 @@ - - - - Qt::Orientation::Vertical - - - - 20 - 40 - - - - diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 16a88541118..fec607b9760 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -37,8 +37,8 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) auto *intf_label = findChild(QString("labelIntf%1").arg(i + 1)); auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); - auto *conf_btn = findChild(QString("pushButtonConf%1").arg(i + 1)); -// auto *net_type_conf_btn = findChild(QString("pushButtonNetTypeConf%1").arg(i + 1)); + auto *conf_btn = findChild(QString("pushButtonConf%1").arg(i + 1)); + // auto *net_type_conf_btn = findChild(QString("pushButtonNetTypeConf%1").arg(i + 1)); auto *vde_socket_label = findChild(QString("labelSocketVDENIC%1").arg(i + 1)); auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); @@ -51,14 +51,14 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) // Switch group auto *switch_group_label = findChild(QString("labelSwitch%1").arg(i + 1)); -// auto *switch_group_hlayout = findChild(QString("HLayoutSwitch%1").arg(i + 1)); -// auto *switch_group_hspacer = findChild(QString("horizontalSpacerSwitch%1").arg(i + 1)); + // auto *switch_group_hlayout = findChild(QString("HLayoutSwitch%1").arg(i + 1)); + // auto *switch_group_hspacer = findChild(QString("horizontalSpacerSwitch%1").arg(i + 1)); auto *switch_group_value = findChild(QString("spinnerSwitch%1").arg(i + 1)); switch_group_value->setMinimum(1); switch_group_value->setMaximum(10); // Promiscuous option - auto *promisc_label = findChild(QString("labelPromisc%1").arg(i + 1)); + auto *promisc_label = findChild(QString("labelPromisc%1").arg(i + 1)); auto *promisc_value = findChild(QString("boxPromisc%1").arg(i + 1)); // Remote switch hostname @@ -68,7 +68,7 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) bridge_line->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_TAP); intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP); conf_btn->setEnabled(network_card_has_config(nic_cbox->currentData().toInt())); -// net_type_conf_btn->setEnabled(network_type_has_config(netType)); + // net_type_conf_btn->setEnabled(network_type_has_config(netType)); // NEW STUFF // Make all options invisible by default @@ -76,7 +76,7 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) // Switch group switch_group_label->setVisible(false); switch_group_value->setVisible(false); -// switch_group_hspacer->setVisible(false); + // switch_group_hspacer->setVisible(false); // Promiscuous options promisc_label->setVisible(false); @@ -103,7 +103,7 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) intf_label->setVisible(false); // Don't enable anything unless there's a nic selected - if(nic_cbox->currentData().toInt() != 0) { + if (nic_cbox->currentData().toInt() != 0) { // Then only enable as needed based on network type switch (net_type_cbox->currentData().toInt()) { #ifdef HAS_VDE @@ -138,15 +138,15 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) #endif #ifdef USE_NETSWITCH - case NET_TYPE_NMSWITCH: -// option_list_label->setText("Local Switch Options"); + case NET_TYPE_NMSWITCH: + // option_list_label->setText("Local Switch Options"); option_list_label->setVisible(true); option_list_line->setVisible(true); // Switch group switch_group_label->setVisible(true); switch_group_value->setVisible(true); -// switch_group_hspacer->setVisible(false); + // switch_group_hspacer->setVisible(false); // Promiscuous options promisc_label->setVisible(true); @@ -154,14 +154,14 @@ SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) break; case NET_TYPE_NRSWITCH: -// option_list_label->setText("Remote Switch Options"); + // option_list_label->setText("Remote Switch Options"); option_list_label->setVisible(true); option_list_line->setVisible(true); // Switch group switch_group_label->setVisible(true); switch_group_value->setVisible(true); -// switch_group_hspacer->setVisible(false); + // switch_group_hspacer->setVisible(false); // Hostname hostname_label->setVisible(true); @@ -204,12 +204,12 @@ void SettingsNetwork::save() { for (int i = 0; i < NET_CARD_MAX; ++i) { - auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); #ifdef HAS_VDE - auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); + auto *socket_line = findChild(QString("socketVDENIC%1").arg(i + 1)); #endif #if defined(__unix__) || defined(__APPLE__) - auto *bridge_line = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); + auto *bridge_line = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); #endif net_cards_conf[i].device_num = cbox->currentData().toInt(); cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); @@ -249,15 +249,15 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) { this->machineId = machineId; - int c = 0; - int selectedRow = 0; + int c = 0; + int selectedRow = 0; // Network Card - QComboBox *cbox_[NET_CARD_MAX] = { 0 }; - QAbstractItemModel *models[NET_CARD_MAX] = { 0 }; - int removeRows_[NET_CARD_MAX] = { 0 }; - int selectedRows[NET_CARD_MAX] = { 0 }; - int m_has_net = machine_has_flags(machineId, MACHINE_NIC); + QComboBox *cbox_[NET_CARD_MAX] = { 0 }; + QAbstractItemModel *models[NET_CARD_MAX] = { 0 }; + int removeRows_[NET_CARD_MAX] = { 0 }; + int selectedRows[NET_CARD_MAX] = { 0 }; + int m_has_net = machine_has_flags(machineId, MACHINE_NIC); for (uint8_t i = 0; i < NET_CARD_MAX; ++i) { cbox_[i] = findChild(QString("comboBoxNIC%1").arg(i + 1)); @@ -286,7 +286,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) } } - c++; + c++; } for (uint8_t i = 0; i < NET_CARD_MAX; ++i) { @@ -308,17 +308,17 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) if (network_devmap.has_vde) Models::AddEntry(model, "VDE", NET_TYPE_VDE); #endif - + #if defined(__unix__) || defined(__APPLE__) Models::AddEntry(model, "TAP", NET_TYPE_TAP); #endif #ifdef USE_NETSWITCH Models::AddEntry(model, "Local Switch", NET_TYPE_NMSWITCH); -#ifdef ENABLE_NET_NRSWITCH +# ifdef ENABLE_NET_NRSWITCH Models::AddEntry(model, "Remote Switch", NET_TYPE_NRSWITCH); -#endif /* ENABLE_NET_NRSWITCH */ -#endif /* USE_NETSWITCH */ +# endif /* ENABLE_NET_NRSWITCH */ +#endif /* USE_NETSWITCH */ model->removeRows(0, removeRows); cbox->setCurrentIndex(cbox->findData(net_cards_conf[i].net_type)); @@ -343,7 +343,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) if (net_cards_conf[i].net_type == NET_TYPE_VDE) { #ifdef HAS_VDE QString currentVdeSocket = net_cards_conf[i].host_dev_name; - auto editline = findChild(QString("socketVDENIC%1").arg(i+1)); + auto editline = findChild(QString("socketVDENIC%1").arg(i + 1)); editline->setText(currentVdeSocket); #else ; @@ -351,7 +351,7 @@ SettingsNetwork::onCurrentMachineChanged(int machineId) #if defined(__unix__) || defined(__APPLE__) } else if (net_cards_conf[i].net_type == NET_TYPE_TAP) { QString currentTapDevice = net_cards_conf[i].host_dev_name; - auto editline = findChild(QString("bridgeTAPNIC%1").arg(i+1)); + auto editline = findChild(QString("bridgeTAPNIC%1").arg(i + 1)); editline->setText(currentTapDevice); #endif #ifdef USE_NETSWITCH diff --git a/src/qt/qt_settingsnetwork.ui b/src/qt/qt_settingsnetwork.ui index 767b4244da0..12b74004fb9 100644 --- a/src/qt/qt_settingsnetwork.ui +++ b/src/qt/qt_settingsnetwork.ui @@ -158,11 +158,11 @@ - TAP Bridge Device + TAP Bridge Device: - + 127 @@ -373,11 +373,11 @@ - TAP Bridge Device + TAP Bridge Device: - + 127 @@ -588,11 +588,11 @@ - TAP Bridge Device + TAP Bridge Device: - + 127 @@ -803,11 +803,11 @@ - TAP Bridge Device + TAP Bridge Device: - + 127 diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index 89254b8ee57..f408bda9559 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -68,8 +68,8 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) if (auto *cb = findChild(QString("comboBoxIsaRomCard%1").arg(i + 1))) cb->clear(); - int c = 0; - int selectedRow = 0; + int c = 0; + int selectedRow = 0; // ISA RTC Cards auto *model = ui->comboBoxRTC->model(); @@ -127,8 +127,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) isamem_cbox[i]->setEnabled(isamem_models[i]->rowCount() > 1); isamem_cbox[i]->setCurrentIndex(-1); isamem_cbox[i]->setCurrentIndex(isamem_selectedRows[i]); - findChild(QString("pushButtonConfigureIsaMemCard%1").arg(i + 1))->setEnabled((isamem_type[i] != 0) && - isamem_has_config(isamem_type[i]) && machineHasIsa); + findChild(QString("pushButtonConfigureIsaMemCard%1").arg(i + 1))->setEnabled((isamem_type[i] != 0) && isamem_has_config(isamem_type[i]) && machineHasIsa); } // ISA ROM Expansion Cards @@ -168,8 +167,7 @@ SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) isarom_cbox[i]->setEnabled(isarom_models[i]->rowCount() > 1); isarom_cbox[i]->setCurrentIndex(-1); isarom_cbox[i]->setCurrentIndex(isarom_selectedRows[i]); - findChild(QString("pushButtonConfigureIsaRomCard%1").arg(i + 1))->setEnabled((isarom_type[i] != 0) && - isarom_has_config(isarom_type[i]) && machineHasIsa); + findChild(QString("pushButtonConfigureIsaRomCard%1").arg(i + 1))->setEnabled((isarom_type[i] != 0) && isarom_has_config(isarom_type[i]) && machineHasIsa); } } @@ -348,12 +346,14 @@ SettingsOtherPeripherals::on_pushButtonConfigureUT_clicked() DeviceConfig::ConfigureDevice(&unittester_device); } -void SettingsOtherPeripherals::on_checkBoxKeyCard_stateChanged(int arg1) +void +SettingsOtherPeripherals::on_checkBoxKeyCard_stateChanged(int arg1) { ui->pushButtonConfigureKeyCard->setEnabled(arg1 != 0); } -void SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() +void +SettingsOtherPeripherals::on_pushButtonConfigureKeyCard_clicked() { DeviceConfig::ConfigureDevice(&novell_keycard_device); } diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index dde8e9bb64f..7b3bb89f634 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -32,15 +32,13 @@ extern "C" { 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); + return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, mo_drive_types[i].revision); } static QString rdiskDriveTypeName(int i) { - return QString("%1 %2 %3").arg(rdisk_drive_types[i].vendor, rdisk_drive_types[i].model, - rdisk_drive_types[i].revision); + return QString("%1 %2 %3").arg(rdisk_drive_types[i].vendor, rdisk_drive_types[i].model, rdisk_drive_types[i].revision); } void @@ -120,7 +118,7 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) ui->setupUi(this); mo_disabled_icon = QIcon(":/settings/qt/icons/mo_disabled.ico"); - mo_icon = QIcon(":/settings/qt/icons/mo.ico"); + mo_icon = QIcon(":/settings/qt/icons/mo.ico"); Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); ui->comboBoxMOBus->model()->removeRows(3, ui->comboBoxMOBus->model()->rowCount() - 3); @@ -147,11 +145,11 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) ui->tableViewMO->setCurrentIndex(model->index(0, 0)); rdisk_disabled_icon = QIcon(":/settings/qt/icons/rdisk_disabled.ico"); - rdisk_icon = QIcon(":/settings/qt/icons/rdisk.ico"); + rdisk_icon = QIcon(":/settings/qt/icons/rdisk.ico"); Harddrives::populateRemovableBuses(ui->comboBoxRDiskBus->model()); if ((ui->comboBoxRDiskBus->model()->rowCount() - 3) > 0) - ui->comboBoxRDiskBus->model()->removeRows(3, ui->comboBoxRDiskBus->model()->rowCount() - 3); + ui->comboBoxRDiskBus->model()->removeRows(3, ui->comboBoxRDiskBus->model()->rowCount() - 3); model = ui->comboBoxRDiskType->model(); for (uint32_t i = 0; i < KNOWN_RDISK_DRIVE_TYPES; i++) { Models::AddEntry(model, rdiskDriveTypeName(i), i); @@ -245,7 +243,8 @@ SettingsOtherRemovable::onRDiskRowChanged(const QModelIndex ¤t) } void -SettingsOtherRemovable::reloadBusChannels_MO() { +SettingsOtherRemovable::reloadBusChannels_MO() +{ auto selected = ui->comboBoxMOChannel->currentIndex(); Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), ui->comboBoxMOBus->currentData().toInt(), Harddrives::busTrackClass); @@ -254,7 +253,8 @@ SettingsOtherRemovable::reloadBusChannels_MO() { } void -SettingsOtherRemovable::reloadBusChannels_RDisk() { +SettingsOtherRemovable::reloadBusChannels_RDisk() +{ auto selected = ui->comboBoxRDiskChannel->currentIndex(); Harddrives::populateBusChannels(ui->comboBoxRDiskChannel->model(), ui->comboBoxRDiskBus->currentData().toInt(), Harddrives::busTrackClass); @@ -290,12 +290,8 @@ 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()); + 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(), @@ -306,9 +302,7 @@ SettingsOtherRemovable::on_comboBoxMOBus_activated(int) 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()); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); emit moChannelChanged(); } @@ -316,12 +310,8 @@ void SettingsOtherRemovable::on_comboBoxRDiskBus_activated(int) { auto i = ui->tableViewRDisk->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, - Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, - Qt::UserRole + 1).toInt()); - ui->comboBoxRDiskChannel->setCurrentIndex(ui->comboBoxRDiskBus->currentData().toUInt() == RDISK_BUS_ATAPI ? - Harddrives::busTrackClass->next_free_ide_channel() : - Harddrives::busTrackClass->next_free_scsi_id()); + Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1).toInt()); + ui->comboBoxRDiskChannel->setCurrentIndex(ui->comboBoxRDiskBus->currentData().toUInt() == RDISK_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1); setRDiskBus(ui->tableViewRDisk->model(), ui->tableViewRDisk->selectionModel()->currentIndex(), @@ -332,18 +322,16 @@ SettingsOtherRemovable::on_comboBoxRDiskBus_activated(int) ui->comboBoxRDiskType->currentData().toUInt()); ui->tableViewRDisk->resizeColumnsToContents(); ui->tableViewRDisk->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, - Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, - Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1).toInt()); emit rdiskChannelChanged(); } void SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() { - const auto *item_model = qobject_cast(ui->comboBoxMOChannel->model()); - const auto index = ui->comboBoxMOChannel->currentIndex(); - auto *item = item_model->item(index); + const auto *item_model = qobject_cast(ui->comboBoxMOChannel->model()); + const auto index = ui->comboBoxMOChannel->currentIndex(); + auto *item = item_model->item(index); if (item) item->setEnabled(true); } @@ -351,9 +339,9 @@ SettingsOtherRemovable::enableCurrentlySelectedChannel_MO() void SettingsOtherRemovable::enableCurrentlySelectedChannel_RDisk() { - const auto *item_model = qobject_cast(ui->comboBoxRDiskChannel->model()); - const auto index = ui->comboBoxRDiskChannel->currentIndex(); - auto *item = item_model->item(index); + const auto *item_model = qobject_cast(ui->comboBoxRDiskChannel->model()); + const auto index = ui->comboBoxRDiskChannel->currentIndex(); + auto *item = item_model->item(index); if (item) item->setEnabled(true); } @@ -361,16 +349,12 @@ 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()); + 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()); + Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); emit moChannelChanged(); } @@ -378,15 +362,12 @@ void SettingsOtherRemovable::on_comboBoxRDiskChannel_activated(int) { auto i = ui->tableViewRDisk->selectionModel()->currentIndex().siblingAtColumn(0); - Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, - Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, - Qt::UserRole + 1).toInt()); + Harddrives::busTrackClass->device_track(0, DEV_RDISK, ui->tableViewRDisk->model()->data(i, Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1).toInt()); setRDiskBus(ui->tableViewRDisk->model(), - ui->tableViewRDisk->selectionModel()->currentIndex(), - ui->comboBoxRDiskBus->currentData().toUInt(), - ui->comboBoxRDiskChannel->currentData().toUInt()); - Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, - Qt::UserRole).toInt(), + ui->tableViewRDisk->selectionModel()->currentIndex(), + ui->comboBoxRDiskBus->currentData().toUInt(), + ui->comboBoxRDiskChannel->currentData().toUInt()); + Harddrives::busTrackClass->device_track(1, DEV_RDISK, ui->tableViewRDisk->model()->data(i, Qt::UserRole).toInt(), ui->tableViewRDisk->model()->data(i, Qt::UserRole + 1).toInt()); emit rdiskChannelChanged(); } diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index 2c7a4e80e36..794939589ab 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -38,6 +38,7 @@ private slots: private: Ui::SettingsOtherRemovable *ui; + void setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel); void setRDiskBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel); void enableCurrentlySelectedChannel_MO(); diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index eec89683972..b1155629dbd 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -53,7 +53,7 @@ SettingsPorts::save() auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); if (cbox != NULL) - lpt_ports[i].device = cbox->currentData().toInt(); + lpt_ports[i].device = cbox->currentData().toInt(); if (checkBox != NULL) lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } @@ -73,21 +73,20 @@ SettingsPorts::onCurrentMachineChanged(int machineId) { this->machineId = machineId; - int c = 0; + int c = 0; auto *lptEcpDmaModel = ui->comboBoxLptECPDMA->model(); auto removeRowsEcpDma = lptEcpDmaModel->rowCount(); - int has_jumpers = !!machine_has_jumpered_ecp_dma(machineId, DMA_ANY); + int has_jumpers = !!machine_has_jumpered_ecp_dma(machineId, DMA_ANY); - int selectedRow = -2; - int first = -2; + int selectedRow = -2; + int first = -2; for (int i = 0; i < 9; ++i) { - int j = machine_map_jumpered_ecp_dma(i); + int j = machine_map_jumpered_ecp_dma(i); - if ((has_jumpers && ((j == DMA_NONE) || !machine_has_jumpered_ecp_dma(machineId, j))) || - (!has_jumpers && (j != DMA_NONE))) + if ((has_jumpers && ((j == DMA_NONE) || !machine_has_jumpered_ecp_dma(machineId, j))) || (!has_jumpers && (j != DMA_NONE))) continue; if (first == -2) @@ -122,7 +121,7 @@ SettingsPorts::onCurrentMachineChanged(int machineId) c = 0; // LPT Device - QComboBox * cbox[PARALLEL_MAX] = { 0 }; + QComboBox *cbox[PARALLEL_MAX] = { 0 }; QAbstractItemModel *models[PARALLEL_MAX] = { 0 }; int removeRows_[PARALLEL_MAX] = { 0 }; int selectedRows[PARALLEL_MAX] = { 0 }; @@ -134,12 +133,12 @@ SettingsPorts::onCurrentMachineChanged(int machineId) } while (true) { - const char *lptName = lpt_device_get_name(c); + const char *lptName = lpt_device_get_name(c); if (lptName == nullptr) break; - const QString name = tr(lptName); + const QString name = tr(lptName); for (uint8_t i = 0; i < PARALLEL_MAX; ++i) { int row = Models::AddEntry(models[i], name, c); @@ -148,7 +147,7 @@ SettingsPorts::onCurrentMachineChanged(int machineId) selectedRows[i] = row - removeRows_[i]; } - c++; + c++; } for (uint8_t i = 0; i < PARALLEL_MAX; ++i) { diff --git a/src/qt/qt_settingsports.ui b/src/qt/qt_settingsports.ui index 9a853399555..6be0e3a8574 100644 --- a/src/qt/qt_settingsports.ui +++ b/src/qt/qt_settingsports.ui @@ -228,6 +228,12 @@ Serial port passthrough 1 + + + 0 + 0 + + @@ -242,6 +248,12 @@ Serial port passthrough 2 + + + 0 + 0 + + @@ -256,6 +268,12 @@ Serial port passthrough 3 + + + 0 + 0 + + @@ -270,6 +288,12 @@ Serial port passthrough 4 + + + 0 + 0 + + @@ -279,20 +303,7 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + Qt::Vertical diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index 38038f97f04..6307451a5b5 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -71,8 +71,8 @@ SettingsSound::onCurrentMachineChanged(const int machineId) { this->machineId = machineId; - int c; - int selectedRow; + int c; + int selectedRow; // Sound Cards QComboBox *cbox[SOUND_CARD_MAX] = { 0 }; @@ -119,10 +119,10 @@ SettingsSound::onCurrentMachineChanged(const int machineId) } // Midi Out - c = 0; - auto *model = ui->comboBoxMidiOut->model(); - auto removeRows = model->rowCount(); - selectedRow = 0; + c = 0; + auto *model = ui->comboBoxMidiOut->model(); + auto removeRows = model->rowCount(); + selectedRow = 0; while (true) { const QString name = DeviceConfig::DeviceName(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); @@ -210,8 +210,7 @@ SettingsSound::on_comboBoxSoundCard1_currentIndexChanged(int index) int sndCard = ui->comboBoxSoundCard1->currentData().toInt(); if (sndCard == SOUND_INTERNAL) - ui->pushButtonConfigureSoundCard1->setEnabled(machine_has_flags(machineId, MACHINE_SOUND) && - device_has_config(machine_get_snd_device(machineId))); + ui->pushButtonConfigureSoundCard1->setEnabled(machine_has_flags(machineId, MACHINE_SOUND) && device_has_config(machine_get_snd_device(machineId))); else ui->pushButtonConfigureSoundCard1->setEnabled(sound_card_has_config(sndCard)); } diff --git a/src/qt/qt_settingssound.ui b/src/qt/qt_settingssound.ui index 97ef7c3ff1b..f93c5d37449 100644 --- a/src/qt/qt_settingssound.ui +++ b/src/qt/qt_settingssound.ui @@ -46,7 +46,7 @@ - + Configure @@ -73,7 +73,7 @@ - + Configure @@ -100,7 +100,7 @@ - + Configure @@ -127,7 +127,7 @@ - + Configure @@ -154,7 +154,7 @@ - + Configure @@ -181,35 +181,35 @@ - + Configure - + Standalone MPU-401 - + Configure - + Use FLOAT32 sound - + @@ -238,7 +238,7 @@ - + Qt::Vertical diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 254aadc86ec..ede180d9f4a 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -51,8 +51,8 @@ SettingsStorageControllers::save() { /* Storage devices category */ for (uint8_t i = 0; i < HDC_MAX; ++i) { - QComboBox *cbox = findChild(QString("comboBoxHD%1").arg(i + 1)); - hdc_current[i] = cbox->currentData().toInt(); + QComboBox *cbox = findChild(QString("comboBoxHD%1").arg(i + 1)); + hdc_current[i] = cbox->currentData().toInt(); } for (uint8_t i = 0; i < SCSI_CARD_MAX; ++i) { QComboBox *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); @@ -140,10 +140,10 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) ui->comboBoxCDInterface->setCurrentIndex(selectedRow); // HD Controller - QComboBox * hd_cbox[HDC_MAX] = { 0 }; - QAbstractItemModel *hd_models[HDC_MAX] = { 0 }; - int hd_removeRows_[HDC_MAX] = { 0 }; - int hd_selectedRows[HDC_MAX] = { 0 }; + QComboBox *hd_cbox[HDC_MAX] = { 0 }; + QAbstractItemModel *hd_models[HDC_MAX] = { 0 }; + int hd_removeRows_[HDC_MAX] = { 0 }; + int hd_selectedRows[HDC_MAX] = { 0 }; for (uint8_t i = 0; i < HDC_MAX; ++i) { hd_cbox[i] = findChild(QString("comboBoxHD%1").arg(i + 1)); @@ -185,7 +185,7 @@ SettingsStorageControllers::onCurrentMachineChanged(int machineId) } // SCSI Card - QComboBox * cbox[SCSI_CARD_MAX] = { 0 }; + QComboBox *cbox[SCSI_CARD_MAX] = { 0 }; QAbstractItemModel *models[SCSI_CARD_MAX] = { 0 }; int removeRows_[SCSI_CARD_MAX] = { 0 }; int selectedRows[SCSI_CARD_MAX] = { 0 }; diff --git a/src/qt/qt_settingsstoragecontrollers.ui b/src/qt/qt_settingsstoragecontrollers.ui index 2d6fa9d326a..50ebbe7ef82 100644 --- a/src/qt/qt_settingsstoragecontrollers.ui +++ b/src/qt/qt_settingsstoragecontrollers.ui @@ -40,6 +40,12 @@ 30 + + + 0 + 0 + + @@ -61,6 +67,12 @@ 30 + + + 0 + 0 + + diff --git a/src/qt/qt_singlekeyseqedit.cpp b/src/qt/qt_singlekeyseqedit.cpp index f17d2164fef..feb8dc6d467 100644 --- a/src/qt/qt_singlekeyseqedit.cpp +++ b/src/qt/qt_singlekeyseqedit.cpp @@ -1,20 +1,25 @@ #include "qt_singlekeyseqedit.hpp" /* - This subclass of QKeySequenceEdit restricts the input to only a single - shortcut instead of an unlimited number with a fixed timeout. + This subclass of QKeySequenceEdit restricts the input to only a single + shortcut instead of an unlimited number with a fixed timeout. */ -singleKeySequenceEdit::singleKeySequenceEdit(QWidget *parent) : QKeySequenceEdit(parent) {} +singleKeySequenceEdit::singleKeySequenceEdit(QWidget *parent) + : QKeySequenceEdit(parent) +{ + // +} -void singleKeySequenceEdit::keyPressEvent(QKeyEvent *event) +void +singleKeySequenceEdit::keyPressEvent(QKeyEvent *event) { QKeySequenceEdit::keyPressEvent(event); if (this->keySequence().count() > 0) { QKeySequenceEdit::setKeySequence(this->keySequence()); - - // This could have unintended consequences since it will happen - // every single time the user presses a key. + + // This could have unintended consequences since it will happen + // every single time the user presses a key. emit editingFinished(); } } \ No newline at end of file diff --git a/src/qt/qt_singlekeyseqedit.hpp b/src/qt/qt_singlekeyseqedit.hpp index 43ebe70b205..5b5eb96bafa 100644 --- a/src/qt/qt_singlekeyseqedit.hpp +++ b/src/qt/qt_singlekeyseqedit.hpp @@ -4,8 +4,7 @@ #include #include -class singleKeySequenceEdit : public QKeySequenceEdit -{ +class singleKeySequenceEdit : public QKeySequenceEdit { Q_OBJECT public: singleKeySequenceEdit(QWidget *parent = nullptr); diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 16e331378f8..0a4492a3e50 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -30,7 +30,8 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) #ifdef __HAIKU__ : QWidget(parent) #else - : QWindow(parent->windowHandle()), m_backingStore(new QBackingStore(this)) + : QWindow(parent->windowHandle()) + , m_backingStore(new QBackingStore(this)) #endif { RendererCommon::parentWidget = parent; @@ -72,7 +73,7 @@ SoftwareRenderer::render() } void -SoftwareRenderer::exposeEvent(QExposeEvent* event) +SoftwareRenderer::exposeEvent(QExposeEvent *event) { render(); } @@ -81,7 +82,7 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { /* TODO: should look into deleteLater() */ - auto tval = this; + auto tval = this; if ((void *) tval == nullptr) return; auto origSource = source; diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index c9c2706cd92..e80410956b1 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -25,7 +25,7 @@ class SoftwareRenderer : void paintEvent(QPaintEvent *event) override; #endif - void exposeEvent(QExposeEvent* event) override; + void exposeEvent(QExposeEvent *event) override; std::vector> getBuffers() override; diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp index 33480d7c315..bd1c0252648 100644 --- a/src/qt/qt_styleoverride.cpp +++ b/src/qt/qt_styleoverride.cpp @@ -28,10 +28,10 @@ extern "C" { } #ifdef Q_OS_WINDOWS -#include -#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 -#endif +# include +# ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +# define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +# endif #endif int @@ -72,7 +72,7 @@ StyleOverride::polish(QWidget *widget) widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); #ifdef Q_OS_WINDOWS BOOL DarkMode = !util::isWindowsLightTheme(); - DwmSetWindowAttribute((HWND)widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID)&DarkMode, sizeof(DarkMode)); + DwmSetWindowAttribute((HWND) widget->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, (LPCVOID) &DarkMode, sizeof(DarkMode)); #endif } @@ -111,7 +111,6 @@ StyleOverride::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, color.setBlueF(avg); image.setPixelColor(x, y, color); - } } diff --git a/src/qt/qt_styleoverride.hpp b/src/qt/qt_styleoverride.hpp index 994271f1508..37d339e5e6d 100644 --- a/src/qt/qt_styleoverride.hpp +++ b/src/qt/qt_styleoverride.hpp @@ -18,7 +18,7 @@ class StyleOverride : public QProxyStyle { const QWidget *widget = nullptr, QStyleHintReturn *returnData = nullptr) const override; - void polish(QWidget *widget) override; + void polish(QWidget *widget) override; QPixmap generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &pixmap, const QStyleOption *option) const override; }; diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index cebc5a21662..59204de5613 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -153,10 +153,8 @@ plat_mouse_capture(int on) int ui_msgbox_header(int flags, void *header, void *message) { - const auto hdr = (flags & MBX_ANSI) ? QString(static_cast(header)) : - QString::fromWCharArray(static_cast(header)); - const auto msg = (flags & MBX_ANSI) ? QString(static_cast(message)) : - QString::fromWCharArray(static_cast(message)); + const auto hdr = (flags & MBX_ANSI) ? QString(static_cast(header)) : QString::fromWCharArray(static_cast(header)); + const auto msg = (flags & MBX_ANSI) ? QString(static_cast(message)) : QString::fromWCharArray(static_cast(message)); // any error in early init if (main_window == nullptr) { @@ -259,9 +257,9 @@ ui_sb_set_ready(int ready) void ui_sb_update_icon_wp(int tag, int state) { - const auto temp = static_cast(tag); - const int category = static_cast(temp & 0xfffffff0); - const int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; switch (category) { default: @@ -287,9 +285,9 @@ ui_sb_update_icon_wp(int tag, int state) void ui_sb_update_icon_state(int tag, int state) { - const auto temp = static_cast(tag); - const int category = static_cast(temp & 0xfffffff0); - const int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; switch (category) { default: @@ -329,9 +327,9 @@ ui_sb_update_icon_state(int tag, int state) void ui_sb_update_icon(int tag, int active) { - const auto temp = static_cast(tag); - const int category = static_cast(temp & 0xfffffff0); - const int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; switch (category) { default: @@ -365,9 +363,9 @@ ui_sb_update_icon(int tag, int active) void ui_sb_update_icon_write(int tag, int write) { - const auto temp = static_cast(tag); - const int category = static_cast(temp & 0xfffffff0); - const int item = tag & 0xf; + const auto temp = static_cast(tag); + const int category = static_cast(temp & 0xfffffff0); + const int item = tag & 0xf; switch (category) { default: @@ -397,5 +395,4 @@ ui_sb_update_icon_write(int tag, int write) break; } } - } diff --git a/src/qt/qt_updatecheck.cpp b/src/qt/qt_updatecheck.cpp index 4b9d1e4c524..cffb054b336 100644 --- a/src/qt/qt_updatecheck.cpp +++ b/src/qt/qt_updatecheck.cpp @@ -27,14 +27,14 @@ extern "C" { } UpdateCheck:: -UpdateCheck(const UpdateChannel channel, QObject *parent) : QObject(parent) + UpdateCheck(const UpdateChannel channel, QObject *parent) + : QObject(parent) { - updateChannel = channel; + updateChannel = channel; currentVersion = getCurrentVersion(channel); } -UpdateCheck::~ -UpdateCheck() +UpdateCheck::~UpdateCheck() = default; void @@ -56,35 +56,35 @@ UpdateCheck::checkForUpdates() void UpdateCheck::jenkinsDownloadComplete(const QString &filename, const QVariant &varData) { - auto generalError = tr("Unable to determine release information"); + auto generalError = tr("Unable to determine release information"); auto jenkinsReleaseListResult = parseJenkinsJson(filename); - auto latestVersion = 0; // NOLINT (Default value as a fallback) + auto latestVersion = 0; // NOLINT (Default value as a fallback) - if(!jenkinsReleaseListResult.has_value() || jenkinsReleaseListResult.value().isEmpty()) { + if (!jenkinsReleaseListResult.has_value() || jenkinsReleaseListResult.value().isEmpty()) { generalDownloadError(generalError); return; } const auto jenkinsReleaseList = jenkinsReleaseListResult.value(); - latestVersion = jenkinsReleaseListResult->first().buildNumber; + latestVersion = jenkinsReleaseListResult->first().buildNumber; // If we can't determine the local build (blank current version), always show an update as available. // Callers can adjust accordingly. // Otherwise, do a comparison with EMU_BUILD_NUM bool updateAvailable = false; - bool upToDate = true; - if(currentVersion.isEmpty() || EMU_BUILD_NUM < latestVersion) { + bool upToDate = true; + if (currentVersion.isEmpty() || EMU_BUILD_NUM < latestVersion) { updateAvailable = true; - upToDate = false; + upToDate = false; } const auto updateResult = UpdateResult { - .channel = updateChannel, + .channel = updateChannel, .updateAvailable = updateAvailable, - .upToDate = upToDate, - .currentVersion = currentVersion, - .latestVersion = QString::number(latestVersion), - .githubInfo = {}, - .jenkinsInfo = jenkinsReleaseList, + .upToDate = upToDate, + .currentVersion = currentVersion, + .latestVersion = QString::number(latestVersion), + .githubInfo = {}, + .jenkinsInfo = jenkinsReleaseList, }; emit updateCheckComplete(updateResult); @@ -101,8 +101,8 @@ UpdateCheck::githubDownloadComplete(const QString &filename, const QVariant &var { const auto generalError = tr("Unable to determine release information"); const auto githubReleaseListResult = parseGithubJson(filename); - QString latestVersion = "0.0"; - if(!githubReleaseListResult.has_value() || githubReleaseListResult.value().isEmpty()) { + QString latestVersion = "0.0"; + if (!githubReleaseListResult.has_value() || githubReleaseListResult.value().isEmpty()) { generalDownloadError(generalError); } auto githubReleaseList = githubReleaseListResult.value(); @@ -111,30 +111,29 @@ UpdateCheck::githubDownloadComplete(const QString &filename, const QVariant &var // Another option would be parsing the name field which is generally "86Box " but // either option requires a consistent naming scheme. latestVersion = githubReleaseList.first().tag_name.replace("v", ""); - for (const auto &release: githubReleaseList) { + for (const auto &release : githubReleaseList) { qDebug().noquote().nospace() << release.name << ": " << release.html_url << " (" << release.created_at << ")"; } // const auto updateDetails = new UpdateDetails(githubReleaseList, currentVersion); bool updateAvailable = false; - bool upToDate = true; - if(currentVersion.isEmpty() || (versionCompare(currentVersion, latestVersion) < 0)) { + bool upToDate = true; + if (currentVersion.isEmpty() || (versionCompare(currentVersion, latestVersion) < 0)) { updateAvailable = true; - upToDate = false; + upToDate = false; } const auto updateResult = UpdateResult { - .channel = updateChannel, + .channel = updateChannel, .updateAvailable = updateAvailable, - .upToDate = upToDate, - .currentVersion = currentVersion, - .latestVersion = latestVersion, - .githubInfo = githubReleaseList, - .jenkinsInfo = {}, + .upToDate = upToDate, + .currentVersion = currentVersion, + .latestVersion = latestVersion, + .githubInfo = githubReleaseList, + .jenkinsInfo = {}, }; emit updateCheckComplete(updateResult); - } QUrl @@ -148,7 +147,7 @@ QString UpdateCheck::getCurrentVersion(const UpdateChannel &updateChannel) { if (updateChannel == UpdateChannel::Stable) { - return {EMU_VERSION}; + return { EMU_VERSION }; } // If EMU_BUILD_NUM is anything other than the default of zero it was set by the build process if constexpr (EMU_BUILD_NUM != 0) { @@ -162,7 +161,7 @@ std::optional> UpdateCheck::parseJenkinsJson(const QString &filename) { QList releaseInfoList; - QFile json_file(filename); + QFile json_file(filename); if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Couldn't open the json file: error" << json_file.error(); return std::nullopt; @@ -186,15 +185,15 @@ UpdateCheck::parseJenkinsJson(const QString &filename) auto json_object = json_doc.object(); // The json contains multiple release - if(json_object.contains("builds") && json_object["builds"].isArray()) { + if (json_object.contains("builds") && json_object["builds"].isArray()) { QJsonArray builds = json_object["builds"].toArray(); - for (const auto &each_build: builds) { + for (const auto &each_build : builds) { if (auto build = parseJenkinsRelease(each_build.toObject()); build.has_value() && build.value().result == "SUCCESS") { releaseInfoList.append(build.value()); } } - } else if(json_object.contains("changeSets") && json_object["changeSets"].isArray()) { + } else if (json_object.contains("changeSets") && json_object["changeSets"].isArray()) { // The json contains only one release, as obtained by the lastSuccessfulBuild api if (const auto build = parseJenkinsRelease(json_object); build.has_value()) { releaseInfoList.append(build.value()); @@ -268,7 +267,7 @@ std::optional> UpdateCheck::parseGithubJson(const QString &filename) { QList releaseInfoList; - QFile json_file(filename); + QFile json_file(filename); if (!json_file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning("Couldn't open the json file: error %d", json_file.error()); return std::nullopt; @@ -291,7 +290,7 @@ UpdateCheck::parseGithubJson(const QString &filename) auto release_array = json_doc.array(); - for (const auto &each_release: release_array) { + for (const auto &each_release : release_array) { if (auto release = parseGithubRelease(each_release.toObject()); release.has_value()) { releaseInfoList.append(release.value()); } diff --git a/src/qt/qt_updatecheck.hpp b/src/qt/qt_updatecheck.hpp index 32732a9be2b..c2a4ed69077 100644 --- a/src/qt/qt_updatecheck.hpp +++ b/src/qt/qt_updatecheck.hpp @@ -31,16 +31,16 @@ class UpdateCheck final : public QObject { }; struct JenkinsChangeSetItem { - QString buildId; // sha hash - QString author; // github username - QString message; // commit message + QString buildId; // sha hash + QString author; // github username + QString message; // commit message QStringList affectedPaths; // list of files in the change }; struct JenkinsReleaseInfo { - int buildNumber = 0; - QString result; - qint64 timestamp = 0; + int buildNumber = 0; + QString result; + qint64 timestamp = 0; QList changeSetItems; }; @@ -55,19 +55,19 @@ class UpdateCheck final : public QObject { }; struct UpdateResult { - UpdateChannel channel; - bool updateAvailable = false; - bool upToDate = false; - QString currentVersion; - QString latestVersion; - QList githubInfo; + UpdateChannel channel; + bool updateAvailable = false; + bool upToDate = false; + QString currentVersion; + QString latestVersion; + QList githubInfo; QList jenkinsInfo; }; explicit UpdateCheck(UpdateChannel channel, QObject *parent = nullptr); ~UpdateCheck() override; - void checkForUpdates(); - static int versionCompare(const QString &version1, const QString &version2); + void checkForUpdates(); + static int versionCompare(const QString &version1, const QString &version2); [[nodiscard]] static QString getCurrentVersion(const UpdateChannel &updateChannel = UpdateChannel::Stable); signals: @@ -86,15 +86,14 @@ class UpdateCheck final : public QObject { static QUrl jenkinsLatestNReleasesUrl(const int &count); static std::optional> parseJenkinsJson(const QString &filename); - static std::optional parseJenkinsRelease(const QJsonObject &json); + static std::optional parseJenkinsRelease(const QJsonObject &json); static std::optional> parseGithubJson(const QString &filename); - static std::optional parseGithubRelease(const QJsonObject &json); - + static std::optional parseGithubRelease(const QJsonObject &json); private slots: - void jenkinsDownloadComplete(const QString &filename, const QVariant& varData); - void githubDownloadComplete(const QString &filename, const QVariant& varData); + void jenkinsDownloadComplete(const QString &filename, const QVariant &varData); + void githubDownloadComplete(const QString &filename, const QVariant &varData); void generalDownloadError(const QString &error); }; diff --git a/src/qt/qt_updatecheckdialog.cpp b/src/qt/qt_updatecheckdialog.cpp index 7400f40aeac..468cdb63ed1 100644 --- a/src/qt/qt_updatecheckdialog.cpp +++ b/src/qt/qt_updatecheckdialog.cpp @@ -24,11 +24,14 @@ extern "C" { } UpdateCheckDialog:: -UpdateCheckDialog(const UpdateCheck::UpdateChannel channel, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateCheckDialog), updateCheck(new UpdateCheck(channel)) + UpdateCheckDialog(const UpdateCheck::UpdateChannel channel, QWidget *parent) + : QDialog(parent) + , ui(new Ui::UpdateCheckDialog) + , updateCheck(new UpdateCheck(channel)) { ui->setupUi(this); ui->statusLabel->setHidden(true); - updateChannel = channel; + updateChannel = channel; currentVersion = UpdateCheck::getCurrentVersion(updateChannel); connect(updateCheck, &UpdateCheck::updateCheckError, [=](const QString &errorMsg) { generalDownloadError(errorMsg); @@ -40,8 +43,7 @@ UpdateCheckDialog(const UpdateCheck::UpdateChannel channel, QWidget *parent) : Q }); } -UpdateCheckDialog::~ -UpdateCheckDialog() +UpdateCheckDialog::~UpdateCheckDialog() = default; void diff --git a/src/qt/qt_updatedetails.cpp b/src/qt/qt_updatedetails.cpp index 386e33faea7..1d5b910d136 100644 --- a/src/qt/qt_updatedetails.cpp +++ b/src/qt/qt_updatedetails.cpp @@ -18,9 +18,10 @@ #include #include - UpdateDetails:: -UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDetails) + UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent) + : QDialog(parent) + , ui(new Ui::UpdateDetails) { ui->setupUi(this); ui->updateTitle->setText(tr("An update to 86Box is available!")); @@ -39,7 +40,7 @@ UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent) : const auto updateDetailsText = QString("%1 %2%3").arg(latestVersionText, currentVersionText.append(' '), tr("Would you like to visit the download page?")); ui->updateDetails->setText(updateDetailsText); - if(updateResult.channel == UpdateCheck::UpdateChannel::Stable) { + if (updateResult.channel == UpdateCheck::UpdateChannel::Stable) { ui->updateText->setMarkdown(githubUpdateToMarkdown(updateResult.githubInfo)); } else { ui->updateText->setMarkdown(jenkinsUpdateToMarkdown(updateResult.jenkinsInfo)); @@ -56,8 +57,7 @@ UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent) : ui->icon->setPixmap(logo); } -UpdateDetails::~ -UpdateDetails() +UpdateDetails::~UpdateDetails() = default; QString @@ -109,25 +109,25 @@ UpdateDetails::visitDownloadPage(const UpdateCheck::UpdateChannel &channel) case UpdateCheck::UpdateChannel::CI: QDesktopServices::openUrl(QUrl("https://86box.net/builds#" #ifdef Q_OS_WINDOWS - "win" + "win" #elif defined(Q_OS_MACOS) - "mac" + "mac" #elif defined(Q_OS_LINUX) - "lin" + "lin" #endif #if defined(__aarch64__) || defined(_M_ARM64) - "arm64" + "arm64" #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) - "64" + "64" #endif #ifdef USE_NEW_DYNAREC - "ndr" + "ndr" #else - "odr" + "odr" #endif - )); + )); break; } } diff --git a/src/qt/qt_updatedetails.hpp b/src/qt/qt_updatedetails.hpp index c11dd8f4338..28ee74b6037 100644 --- a/src/qt/qt_updatedetails.hpp +++ b/src/qt/qt_updatedetails.hpp @@ -28,13 +28,13 @@ class UpdateDetails final : public QDialog { public: explicit UpdateDetails(const UpdateCheck::UpdateResult &updateResult, QWidget *parent = nullptr); ~UpdateDetails() override; + private: Ui::UpdateDetails *ui; - static QString jenkinsUpdateToMarkdown(const QList &releaseInfoList); - static QString githubUpdateToMarkdown(const QList &releaseInfoList); + static QString jenkinsUpdateToMarkdown(const QList &releaseInfoList); + static QString githubUpdateToMarkdown(const QList &releaseInfoList); private slots: static void visitDownloadPage(const UpdateCheck::UpdateChannel &channel); }; - #endif // QT_UPDATEDETAILS_HPP diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index 02d33af9b24..ef2293343d9 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -63,7 +63,8 @@ screenOfWidget(QWidget *widget) #ifdef Q_OS_WINDOWS bool -isWindowsLightTheme(void) { +isWindowsLightTheme(void) +{ if (color_scheme != 0) { return (color_scheme == 1); } @@ -73,7 +74,7 @@ isWindowsLightTheme(void) { // The value is expected to be a REG_DWORD, which is a signed 32-bit little-endian auto buffer = std::vector(4); auto cbData = static_cast(buffer.size() * sizeof(char)); - auto res = RegGetValueW( + auto res = RegGetValueW( HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme", @@ -87,10 +88,7 @@ isWindowsLightTheme(void) { } // convert bytes written to our buffer to an int, assuming little-endian - auto i = int(buffer[3] << 24 | - buffer[2] << 16 | - buffer[1] << 8 | - buffer[0]); + auto i = int(buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]); return i == 1; } @@ -147,22 +145,24 @@ DlgFilter(QStringList extensions, bool last) return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); } - -QString currentUuid() +QString +currentUuid() { return generateUuid(QString(cfg_path)); } -QString generateUuid(const QString &path) +QString +generateUuid(const QString &path) { auto dirPath = QFileInfo(path).dir().canonicalPath(); - if(!dirPath.endsWith("/")) { + if (!dirPath.endsWith("/")) { dirPath.append("/"); } - return QUuid::createUuidV5(QUuid{}, dirPath).toString(QUuid::WithoutBraces); + return QUuid::createUuidV5(QUuid {}, dirPath).toString(QUuid::WithoutBraces); } -bool compareUuid() +bool +compareUuid() { // A uuid not set in the config file will have a zero length. // Any uuid that is lower than the minimum length will be considered invalid @@ -172,7 +172,7 @@ bool compareUuid() return true; } // Do not prompt on mismatch if the system does not have any configured NICs. Just update the uuid - if(!hasConfiguredNICs() && uuid != currentUuid()) { + if (!hasConfiguredNICs() && uuid != currentUuid()) { storeCurrentUuid(); return true; } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index a2ca4442574..ab93784c4b5 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -20,10 +20,10 @@ void setWin11RoundedCorners(WId hwnd, bool enable); #endif QString currentUuid(); QString generateUuid(const QString &path); -void storeCurrentUuid(); -bool compareUuid(); -void generateNewMacAdresses(); -bool hasConfiguredNICs(); +void storeCurrentUuid(); +bool compareUuid(); +void generateNewMacAdresses(); +bool hasConfiguredNICs(); }; #endif diff --git a/src/qt/qt_vmmanager_addmachine.cpp b/src/qt/qt_vmmanager_addmachine.cpp index 81bb47110fc..b8bed2fe5a5 100644 --- a/src/qt/qt_vmmanager_addmachine.cpp +++ b/src/qt/qt_vmmanager_addmachine.cpp @@ -30,7 +30,8 @@ extern "C" { // One for the main Wizard class and one for each page of the wizard VMManagerAddMachine:: -VMManagerAddMachine(QWidget *parent) : QWizard(parent) + VMManagerAddMachine(QWidget *parent) + : QWizard(parent) { setPage(Page_Intro, new IntroPage); setPage(Page_WithExistingConfig, new WithExistingConfigPage); @@ -64,7 +65,7 @@ VMManagerAddMachine(QWidget *parent) : QWizard(parent) } IntroPage:: -IntroPage(QWidget *parent) + IntroPage(QWidget *parent) { setTitle(tr("Introduction")); @@ -74,7 +75,7 @@ IntroPage(QWidget *parent) // topLabel = new QLabel(tr("This will help you add a new system to 86Box.\n\n Choose \"New configuration\" if you'd like to create a new machine.\n\nChoose \"Use existing configuration\" if you'd like to paste in an existing configuration from elsewhere.")); topLabel->setWordWrap(true); - newConfigRadioButton = new QRadioButton(tr("New configuration")); + newConfigRadioButton = new QRadioButton(tr("New configuration")); // auto newDescription = new QLabel(tr("Choose this option to start with a fresh configuration.")); existingConfigRadioButton = new QRadioButton(tr("Use existing configuration")); // auto existingDescription = new QLabel(tr("Use this option if you'd like to paste in the configuration file from an existing system.")); @@ -101,12 +102,12 @@ IntroPage::nextId() const } WithExistingConfigPage:: -WithExistingConfigPage(QWidget *parent) + WithExistingConfigPage(QWidget *parent) { setTitle(tr("Use existing configuration")); setSubTitle(tr("Paste the contents of the existing configuration file into the box below.")); - existingConfiguration = new QPlainTextEdit(); + existingConfiguration = new QPlainTextEdit(); const auto monospaceFont = new QFont(); #ifdef Q_OS_WINDOWS monospaceFont->setFamily("Consolas"); @@ -124,8 +125,8 @@ WithExistingConfigPage(QWidget *parent) const auto layout = new QVBoxLayout(); layout->addWidget(existingConfiguration); const auto loadFileButton = new QPushButton(); - const auto loadFileLabel = new QLabel(tr("Load configuration from file")); - const auto hLayout = new QHBoxLayout(); + const auto loadFileLabel = new QLabel(tr("Load configuration from file")); + const auto hLayout = new QHBoxLayout(); loadFileButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon)); loadFileButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); connect(loadFileButton, &QPushButton::clicked, this, &WithExistingConfigPage::chooseExistingConfigFile); @@ -138,10 +139,10 @@ WithExistingConfigPage(QWidget *parent) void WithExistingConfigPage::chooseExistingConfigFile() { - const auto startDirectory = QString(vmm_path); + const auto startDirectory = QString(vmm_path); const auto selectedConfigFile = QFileDialog::getOpenFileName(this, tr("Choose configuration file"), - startDirectory, - tr("86Box configuration files (86box.cfg)")); + startDirectory, + tr("86Box configuration files (86box.cfg)")); // Empty value means the dialog was canceled if (!selectedConfigFile.isEmpty()) { QFile configFile(selectedConfigFile); @@ -183,18 +184,18 @@ WithExistingConfigPage::isComplete() const } NameAndLocationPage:: -NameAndLocationPage(QWidget *parent) + NameAndLocationPage(QWidget *parent) { #ifdef CUSTOM_SYSTEM_LOCATION setTitle(tr("System name and location")); -#if defined(_WIN32) +# if defined(_WIN32) dirValidate = QRegularExpression(R"(^[^\\/:*?"<>|]+$)"); -#elif defined(__APPLE__) +# elif defined(__APPLE__) dirValidate = QRegularExpression(R"(^[^/:]+$)"); -#else +# else dirValidate = QRegularExpression(R"(^[^/]+$)"); -#endif +# endif setSubTitle(tr("Enter the name of the system and choose the location")); #else @@ -206,7 +207,7 @@ NameAndLocationPage(QWidget *parent) chooseDirectoryButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon)); const auto systemNameLabel = new QLabel(tr("System name:")); - systemName = new QLineEdit(); + systemName = new QLineEdit(); // Special event filter to override enter key systemName->installEventFilter(this); registerField("systemName*", systemName); @@ -214,7 +215,7 @@ NameAndLocationPage(QWidget *parent) #ifdef CUSTOM_SYSTEM_LOCATION const auto systemLocationLabel = new QLabel(tr("System location:")); - systemLocation = new QLineEdit(); + systemLocation = new QLineEdit(); systemLocation->setText(QDir::toNativeSeparators(vmm_path)); registerField("systemLocation*", systemLocation); systemLocationValidation = new QLabel(); @@ -222,7 +223,7 @@ NameAndLocationPage(QWidget *parent) #endif const auto displayNameLabel = new QLabel(tr("Display name (optional):")); - displayName = new QLineEdit(); + displayName = new QLineEdit(); // Special event filter to override enter key displayName->installEventFilter(this); registerField("displayName*", displayName); @@ -278,7 +279,7 @@ NameAndLocationPage::chooseDirectoryLocation() bool NameAndLocationPage::isComplete() const { - bool nameValid = false; + bool nameValid = false; #ifdef CUSTOM_SYSTEM_LOCATION bool locationValid = false; #endif @@ -319,10 +320,10 @@ NameAndLocationPage::eventFilter(QObject *watched, QEvent *event) // Override the enter key to hit the next wizard button // if the validator (isComplete) is satisfied if (event->type() == QEvent::KeyPress) { - const auto keyEvent = dynamic_cast(event); + const auto keyEvent = dynamic_cast(event); if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) { // Only advance if the validator is satisfied (isComplete) - if(const auto wizard = qobject_cast(this->wizard())) { + if (const auto wizard = qobject_cast(this->wizard())) { if (wizard->currentPage()->isComplete()) { wizard->next(); } @@ -335,7 +336,7 @@ NameAndLocationPage::eventFilter(QObject *watched, QEvent *event) } ConclusionPage:: -ConclusionPage(QWidget *parent) + ConclusionPage(QWidget *parent) { setTitle(tr("Complete")); @@ -344,20 +345,20 @@ ConclusionPage(QWidget *parent) topLabel = new QLabel(tr("The wizard will now launch the configuration for the new system.")); topLabel->setWordWrap(true); - const auto systemNameLabel = new QLabel(tr("System name:")); + const auto systemNameLabel = new QLabel(tr("System name:")); systemNameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - systemName = new QLabel(); + systemName = new QLabel(); systemName->setWordWrap(true); #ifdef CUSTOM_SYSTEM_LOCATION const auto systemLocationLabel = new QLabel(tr("System location:")); systemLocationLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - systemLocation = new QLabel(); + systemLocation = new QLabel(); systemLocation->setWordWrap(true); #endif - displayNameLabel = new QLabel(tr("Display name:")); + displayNameLabel = new QLabel(tr("Display name:")); displayNameLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); - displayName = new QLabel(); + displayName = new QLabel(); displayName->setWordWrap(true); const auto layout = new QGridLayout(); @@ -380,10 +381,10 @@ void ConclusionPage::initializePage() { #ifdef CUSTOM_SYSTEM_LOCATION - const auto finalPath = QDir::cleanPath(field("systemLocation").toString() + "/" + field("systemName").toString()); + const auto finalPath = QDir::cleanPath(field("systemLocation").toString() + "/" + field("systemName").toString()); const auto nativePath = QDir::toNativeSeparators(finalPath); #endif - const auto systemNameDisplay = field("systemName").toString(); + const auto systemNameDisplay = field("systemName").toString(); const auto displayNameDisplay = field("displayName").toString(); systemName->setText(systemNameDisplay); diff --git a/src/qt/qt_vmmanager_addmachine.hpp b/src/qt/qt_vmmanager_addmachine.hpp index 7a640a70d76..e2b7c213ef9 100644 --- a/src/qt/qt_vmmanager_addmachine.hpp +++ b/src/qt/qt_vmmanager_addmachine.hpp @@ -48,7 +48,7 @@ class IntroPage : public QWizardPage { [[nodiscard]] int nextId() const override; private: - QLabel *topLabel; + QLabel *topLabel; QRadioButton *newConfigRadioButton; QRadioButton *existingConfigRadioButton; }; @@ -61,17 +61,18 @@ class WithExistingConfigPage final : public QWizardPage { explicit WithExistingConfigPage(QWidget *parent = nullptr); // These extra functions are required to register QPlainTextEdit fields [[nodiscard]] QString configuration() const; - void setConfiguration(const QString &configuration); + void setConfiguration(const QString &configuration); signals: void configurationChanged(const QString &configuration); + private: QPlainTextEdit *existingConfiguration; private slots: - void chooseExistingConfigFile(); + void chooseExistingConfigFile(); + protected: - [[nodiscard]] int nextId() const override; + [[nodiscard]] int nextId() const override; [[nodiscard]] bool isComplete() const override; - }; class NameAndLocationPage final : public QWizardPage { @@ -80,6 +81,7 @@ class NameAndLocationPage final : public QWizardPage { public: explicit NameAndLocationPage(QWidget *parent = nullptr); [[nodiscard]] int nextId() const override; + private: QLineEdit *systemName; #ifdef CUSTOM_SYSTEM_LOCATION @@ -88,21 +90,21 @@ class NameAndLocationPage final : public QWizardPage { QLineEdit *displayName; QLabel *systemNameValidation; #ifdef CUSTOM_SYSTEM_LOCATION - QLabel *systemLocationValidation; + QLabel *systemLocationValidation; QRegularExpression dirValidate; private slots: void chooseDirectoryLocation(); #endif protected: [[nodiscard]] bool isComplete() const override; - bool eventFilter(QObject *watched, QEvent *event) override; - + bool eventFilter(QObject *watched, QEvent *event) override; }; class ConclusionPage final : public QWizardPage { Q_OBJECT public: explicit ConclusionPage(QWidget *parent = nullptr); + private: QLabel *topLabel; QLabel *systemName; @@ -111,6 +113,7 @@ class ConclusionPage final : public QWizardPage { #endif QLabel *displayNameLabel; QLabel *displayName; + protected: void initializePage() override; }; diff --git a/src/qt/qt_vmmanager_clientsocket.cpp b/src/qt/qt_vmmanager_clientsocket.cpp index c8e5cbefe0d..65db5db4a23 100644 --- a/src/qt/qt_vmmanager_clientsocket.cpp +++ b/src/qt/qt_vmmanager_clientsocket.cpp @@ -23,10 +23,10 @@ extern "C" { #include "86box/config.h" } -VMManagerClientSocket::VMManagerClientSocket(QObject* obj) : server_connected(false) +VMManagerClientSocket::VMManagerClientSocket(QObject *obj) + : server_connected(false) { socket = new QLocalSocket; - } void @@ -44,7 +44,7 @@ VMManagerClientSocket::dataReady() if (stream.commitTransaction()) { // first try to successfully read some data // need to also make sure it's valid json - QJsonParseError parse_error{}; + QJsonParseError parse_error {}; // try to create a document with the data received const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parse_error); if (parse_error.error == QJsonParseError::NoError) { @@ -63,7 +63,6 @@ VMManagerClientSocket::dataReady() break; } } - } bool @@ -77,7 +76,7 @@ VMManagerClientSocket::IPCConnect(const QString &server) socket->connectToServer(server_name); - if(!socket->isValid()) { + if (!socket->isValid()) { qInfo("Could not connect to server: %s", qPrintable(socket->errorString())); return false; } @@ -123,13 +122,13 @@ VMManagerClientSocket::sendMessageFull(const VMManagerProtocol::ClientMessage pr { QDataStream clientStream(socket); clientStream.setVersion(QDataStream::Qt_5_7); - auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Client); + auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Client); auto jsonMessage = packet->protocolClientMessage(protocol_message); if (!list.isEmpty()) { jsonMessage["list"] = QJsonArray::fromStringList(list); } // TODO: Add the logic for including objects - if(!json.isEmpty()) { + if (!json.isEmpty()) { jsonMessage["params"] = json; } clientStream << QJsonDocument(jsonMessage).toJson(QJsonDocument::Compact); @@ -228,7 +227,7 @@ VMManagerClientSocket::eventFilter(QObject *obj, QEvent *event) window_blocked = true; } else if (event->type() == QEvent::WindowUnblocked) { window_blocked = false; - running_state = dopause ? VMManagerProtocol::RunningState::Paused : VMManagerProtocol::RunningState::Running; + running_state = dopause ? VMManagerProtocol::RunningState::Paused : VMManagerProtocol::RunningState::Running; clientRunningStateChanged(running_state); } } @@ -248,7 +247,8 @@ VMManagerClientSocket::clientRunningStateChanged(VMManagerProtocol::RunningState { QJsonObject extra_object; if ((state == VMManagerProtocol::RunningState::Paused - || state == VMManagerProtocol::RunningState::Running) && window_blocked) { + || state == VMManagerProtocol::RunningState::Running) + && window_blocked) { state = (state == VMManagerProtocol::RunningState::Paused) ? VMManagerProtocol::RunningState::PausedWaiting : VMManagerProtocol::RunningState::RunningWaiting; } extra_object["status"] = static_cast(state); diff --git a/src/qt/qt_vmmanager_clientsocket.hpp b/src/qt/qt_vmmanager_clientsocket.hpp index 8e063a79e72..53a7d8f883f 100644 --- a/src/qt/qt_vmmanager_clientsocket.hpp +++ b/src/qt/qt_vmmanager_clientsocket.hpp @@ -25,7 +25,7 @@ class VMManagerClientSocket final : public QObject { Q_OBJECT public: - explicit VMManagerClientSocket(QObject* object = nullptr); + explicit VMManagerClientSocket(QObject *object = nullptr); bool IPCConnect(const QString &server); void sendWinIdMessage(WId id); @@ -45,13 +45,13 @@ public slots: void globalConfigurationChanged() const; private: - QString server_name; + QString server_name; QLocalSocket *socket; - bool server_connected; - bool window_blocked = false; - void connected() const; - void disconnected() const; - static void connectionError(QLocalSocket::LocalSocketError socketError); + bool server_connected; + bool window_blocked = false; + void connected() const; + void disconnected() const; + static void connectionError(QLocalSocket::LocalSocketError socketError); // Main convenience send function void sendMessage(VMManagerProtocol::ClientMessage protocol_message) const; @@ -67,7 +67,6 @@ public slots: protected: bool eventFilter(QObject *obj, QEvent *event) override; - }; #endif // QT_VMMANAGER_CLIENTSOCKET_HPP diff --git a/src/qt/qt_vmmanager_config.cpp b/src/qt/qt_vmmanager_config.cpp index 5690ea91aee..70fcdcc6c56 100644 --- a/src/qt/qt_vmmanager_config.cpp +++ b/src/qt/qt_vmmanager_config.cpp @@ -20,11 +20,11 @@ extern "C" { #include <86box/plat.h> } -VMManagerConfig::VMManagerConfig(const ConfigType type, const QString& section) +VMManagerConfig::VMManagerConfig(const ConfigType type, const QString §ion) { char BUF[256]; plat_get_global_config_dir(BUF, 255); - const auto configDir = QString(BUF); + const auto configDir = QString(BUF); const auto configFile = QDir::cleanPath(configDir + "/" + "vmm.ini"); config_type = type; @@ -34,17 +34,18 @@ VMManagerConfig::VMManagerConfig(const ConfigType type, const QString& section) settings->setIniCodec("UTF-8"); #endif settings->setFallbacksEnabled(false); - if(type == ConfigType::System && !section.isEmpty()) { + if (type == ConfigType::System && !section.isEmpty()) { settings->beginGroup(section); } } -VMManagerConfig::~VMManagerConfig() { +VMManagerConfig::~VMManagerConfig() +{ settings->endGroup(); } QString -VMManagerConfig::getStringValue(const QString& key) const +VMManagerConfig::getStringValue(const QString &key) const { const auto value = settings->value(key); // An invalid QVariant with toString will give a default QString value which is blank. @@ -73,4 +74,3 @@ VMManagerConfig::sync() const { settings->sync(); } - diff --git a/src/qt/qt_vmmanager_config.hpp b/src/qt/qt_vmmanager_config.hpp index 51ad3ecfeda..814b3c70f75 100644 --- a/src/qt/qt_vmmanager_config.hpp +++ b/src/qt/qt_vmmanager_config.hpp @@ -27,17 +27,17 @@ class VMManagerConfig : QObject { }; Q_ENUM(ConfigType); - explicit VMManagerConfig(ConfigType type, const QString& section = {}); + explicit VMManagerConfig(ConfigType type, const QString §ion = {}); ~VMManagerConfig() override; - [[nodiscard]] QString getStringValue(const QString& key) const; - void setStringValue(const QString& key, const QString& value) const; - void remove(const QString &key) const; + [[nodiscard]] QString getStringValue(const QString &key) const; + void setStringValue(const QString &key, const QString &value) const; + void remove(const QString &key) const; void sync() const; QSettings *settings; ConfigType config_type; - QString system_name; + QString system_name; }; #endif // QT_VMMANAGER_CONFIG_H \ No newline at end of file diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 2b36e396709..e0cabc53c67 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -22,21 +22,23 @@ #define TOOLBUTTON_STYLESHEET_LIGHT "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}" #ifdef Q_OS_WINDOWS -# define TOOLBUTTON_STYLESHEET_DARK "QToolButton {padding: 5px}" +# define TOOLBUTTON_STYLESHEET_DARK "QToolButton {padding: 5px}" # define SCREENSHOTBORDER_STYLESHEET_DARK "QLabel { border: 1px solid gray }" #else # define TOOLBUTTON_STYLESHEET_DARK "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(dark)} QToolButton:pressed {background: palette(mid)}" #endif -#define SCROLLAREA_STYLESHEET_LIGHT "QWidget {background-color: palette(light)} QScrollBar{ background-color: none }" +#define SCROLLAREA_STYLESHEET_LIGHT "QWidget {background-color: palette(light)} QScrollBar{ background-color: none }" #define SYSTEMLABEL_STYLESHEET_LIGHT "background-color: palette(midlight);" using namespace VMManager; -VMManagerDetails::VMManagerDetails(QWidget *parent) : - QWidget(parent), ui(new Ui::VMManagerDetails) { +VMManagerDetails::VMManagerDetails(QWidget *parent) + : QWidget(parent) + , ui(new Ui::VMManagerDetails) +{ ui->setupUi(this); - const auto leftColumnLayout = qobject_cast(ui->leftColumn->layout()); + const auto leftColumnLayout = qobject_cast(ui->leftColumn->layout()); // Each section here gets its own VMManagerDetailSection, named in the constructor. // When a system is selected in the list view it is updated through this object @@ -116,7 +118,7 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) : ui->ssNavTBHolder->setStyleSheet(toolButtonStyleSheet); pauseIcon = QIcon(":/menuicons/qt/icons/pause.ico"); - runIcon = QIcon(":/menuicons/qt/icons/run.ico"); + runIcon = QIcon(":/menuicons/qt/icons/run.ico"); // Experimenting startPauseButton = new QToolButton(); @@ -164,12 +166,14 @@ VMManagerDetails::VMManagerDetails(QWidget *parent) : sysconfig = new VMManagerSystem(); } -VMManagerDetails::~VMManagerDetails() { +VMManagerDetails::~VMManagerDetails() +{ delete ui; } void -VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) { +VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) +{ // Set the scrollarea background but also set the scroll bar to none. Otherwise it will also // set the scrollbar background to the same. @@ -202,9 +206,8 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) { connect(cadButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::cadButtonPressed); cadButton->setEnabled(true); - bool running = sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running || - sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::RunningWaiting; - if(running) { + bool running = sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running || sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::RunningWaiting; + if (running) { startPauseButton->setIcon(pauseIcon); connect(startPauseButton, &QToolButton::clicked, sysconfig, &VMManagerSystem::pauseButtonPressed); } else { @@ -218,9 +221,7 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) { updateScreenshots(passed_sysconfig); ui->systemLabel->setText(passed_sysconfig->displayName); - ui->statusLabel->setText(sysconfig->process->processId() == 0 ? - tr("Not running") : - QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId()))); + ui->statusLabel->setText(sysconfig->process->processId() == 0 ? tr("Not running") : QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId()))); ui->notesTextEdit->setPlainText(passed_sysconfig->notes); ui->notesTextEdit->setEnabled(true); @@ -237,7 +238,8 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) { } void -VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) { +VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) +{ // Each detail section here has its own VMManagerDetailSection. // When a system is selected in the list view it is updated here, through this object: // * First you clear it with VMManagerDetailSection::clear() @@ -252,7 +254,7 @@ VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) { // Video videoSection->clear(); videoSection->addSection("Video", passed_sysconfig->getDisplayValue(VMManager::Display::Name::Video)); - if(!passed_sysconfig->getDisplayValue(VMManager::Display::Name::Voodoo).isEmpty()) { + if (!passed_sysconfig->getDisplayValue(VMManager::Display::Name::Voodoo).isEmpty()) { videoSection->addSection("Voodoo", passed_sysconfig->getDisplayValue(VMManager::Display::Name::Voodoo)); } @@ -303,7 +305,8 @@ VMManagerDetails::updateConfig(VMManagerSystem *passed_sysconfig) { } void -VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) { +VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) +{ // Disable screenshot navigation buttons by default ui->screenshotNext->setEnabled(false); ui->screenshotPrevious->setEnabled(false); @@ -315,7 +318,7 @@ VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) { if (!screenshots.empty()) { ui->screenshot->setFrameStyle(QFrame::NoFrame); ui->screenshot->setEnabled(true); - if(screenshots.size() > 1) { + if (screenshots.size() > 1) { ui->screenshotNext->setEnabled(true); ui->screenshotPrevious->setEnabled(true); ui->screenshotNextTB->setEnabled(true); @@ -324,7 +327,7 @@ VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) { #ifdef Q_OS_WINDOWS ui->screenshot->setStyleSheet(""); #endif - if(QFileInfo::exists(screenshots.last().filePath())) { + if (QFileInfo::exists(screenshots.last().filePath())) { screenshotIndex = screenshots.size() - 1; const QPixmap pic(screenshots.at(screenshotIndex).filePath()); ui->screenshot->setPixmap(pic.scaled(240, 160, Qt::KeepAspectRatio, Qt::SmoothTransformation)); @@ -351,18 +354,17 @@ VMManagerDetails::updateScreenshots(VMManagerSystem *passed_sysconfig) { } void -VMManagerDetails::updateProcessStatus() { - const bool running = sysconfig->process->state() == QProcess::ProcessState::Running; - QString status_text = running ? - QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId())) : - tr("Not running"); +VMManagerDetails::updateProcessStatus() +{ + const bool running = sysconfig->process->state() == QProcess::ProcessState::Running; + QString status_text = running ? QString("%1: PID %2").arg(tr("Running"), QString::number(sysconfig->process->processId())) : tr("Not running"); status_text.append(sysconfig->window_obscured ? QString(" (%1)").arg(tr("Waiting")) : ""); ui->statusLabel->setText(status_text); resetButton->setEnabled(running); stopButton->setEnabled(running); cadButton->setEnabled(running); - if(running) { - if(sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running) { + if (running) { + if (sysconfig->getProcessStatus() == VMManagerSystem::ProcessStatus::Running) { startPauseButton->setIcon(pauseIcon); startPauseButton->setToolTip(tr("Pause")); } else { @@ -404,7 +406,7 @@ VMManagerDetails::updateWindowStatus() void VMManagerDetails::updateStyle() { - QString toolButtonStyleSheet; + QString toolButtonStyleSheet; const bool lightMode = util::isWindowsLightTheme(); if (lightMode) { toolButtonStyleSheet = TOOLBUTTON_STYLESHEET_LIGHT; @@ -472,10 +474,9 @@ VMManagerDetails::eventFilter(QObject *watched, QEvent *event) { if (watched->isWidgetType() && event->type() == QEvent::FocusOut) { // Make sure it's the textedit - if (const auto *textEdit = qobject_cast(watched); textEdit) { + if (const auto *textEdit = qobject_cast(watched); textEdit) { saveNotes(); } } return QWidget::eventFilter(watched, event); } - diff --git a/src/qt/qt_vmmanager_details.hpp b/src/qt/qt_vmmanager_details.hpp index 3ef868f0330..ec71d4cd8e8 100644 --- a/src/qt/qt_vmmanager_details.hpp +++ b/src/qt/qt_vmmanager_details.hpp @@ -20,10 +20,11 @@ // #include "qt_vmmanager_details_section.hpp" #include "qt_vmmanager_detailsection.hpp" - QT_BEGIN_NAMESPACE -//namespace Ui { class VMManagerDetails; class CollapseButton;} -namespace Ui { class VMManagerDetails;} +// namespace Ui { class VMManagerDetails; class CollapseButton;} +namespace Ui { +class VMManagerDetails; +} QT_END_NAMESPACE class VMManagerDetails : public QWidget { @@ -44,7 +45,7 @@ class VMManagerDetails : public QWidget { void updateStyle(); #endif -// CollapseButton *systemCollapseButton; + // CollapseButton *systemCollapseButton; #ifdef Q_OS_WINDOWS signals: @@ -53,7 +54,7 @@ class VMManagerDetails : public QWidget { private: Ui::VMManagerDetails *ui; - VMManagerSystem *sysconfig; + VMManagerSystem *sysconfig; VMManagerDetailSection *systemSection; VMManagerDetailSection *videoSection; @@ -78,9 +79,9 @@ class VMManagerDetails : public QWidget { QIcon pauseIcon; QIcon runIcon; - void updateConfig(VMManagerSystem *passed_sysconfig); - void updateScreenshots(VMManagerSystem *passed_sysconfig); - static QWidget* createHorizontalLine(int leftSpacing = 25, int rightSpacing = 25); + void updateConfig(VMManagerSystem *passed_sysconfig); + void updateScreenshots(VMManagerSystem *passed_sysconfig); + static QWidget *createHorizontalLine(int leftSpacing = 25, int rightSpacing = 25); // QVBoxLayout *detailsLayout; private slots: void saveNotes() const; @@ -90,12 +91,14 @@ private slots: protected: bool eventFilter(QObject *watched, QEvent *event) override; -// CollapseButton *systemCollapseButton; -// QFrame *systemFrame; -// CollapseButton *displayCollapseButton; -// QFrame *displayFrame; -// CollapseButton *storageCollapseButton; -// QFrame *storageFrame; +#if 0 + CollapseButton *systemCollapseButton; + QFrame *systemFrame; + CollapseButton *displayCollapseButton; + QFrame *displayFrame; + CollapseButton *storageCollapseButton; + QFrame *storageFrame; +#endif }; -#endif //QT_VMMANAGER_DETAILS_H +#endif // QT_VMMANAGER_DETAILS_H diff --git a/src/qt/qt_vmmanager_detailsection.cpp b/src/qt/qt_vmmanager_detailsection.cpp index ffd8668b4da..0b19f77cd10 100644 --- a/src/qt/qt_vmmanager_detailsection.cpp +++ b/src/qt/qt_vmmanager_detailsection.cpp @@ -20,7 +20,7 @@ #define HEADER_STYLESHEET_LIGHT "background-color: palette(midlight);" #ifdef Q_OS_WINDOWS -# define HEADER_STYLESHEET_DARK "background-color: #616161;" +# define HEADER_STYLESHEET_DARK "background-color: #616161;" # define BACKGROUND_STYLESHEET_DARK "background-color: #272727;" #else # define HEADER_STYLESHEET_DARK "background-color: palette(mid);" @@ -30,7 +30,7 @@ const QString VMManagerDetailSection::sectionSeparator = ";"; using namespace VMManager; VMManagerDetailSection:: -VMManagerDetailSection(const QString §ionName) + VMManagerDetailSection(const QString §ionName) : mainLayout(new QVBoxLayout()) , buttonLayout(new QHBoxLayout()) , frame(new QFrame()) @@ -80,7 +80,8 @@ VMManagerDetailSection(const QString §ionName) } VMManagerDetailSection:: -VMManagerDetailSection(const QVariant &varSectionName) : ui(new Ui::DetailSection) + VMManagerDetailSection(const QVariant &varSectionName) + : ui(new Ui::DetailSection) { const auto sectionName = varSectionName.toString(); @@ -100,7 +101,7 @@ VMManagerDetailSection(const QVariant &varSectionName) : ui(new Ui::DetailSectio const auto buttonWidget = new QWidget(this); - mainLayout = new QVBoxLayout(); + mainLayout = new QVBoxLayout(); buttonLayout = new QHBoxLayout(); buttonWidget->setLayout(buttonLayout); @@ -130,7 +131,7 @@ VMManagerDetailSection(const QVariant &varSectionName) : ui(new Ui::DetailSectio } VMManagerDetailSection::~VMManagerDetailSection() -= default; + = default; void VMManagerDetailSection::setSectionName(const QString &name) @@ -144,7 +145,7 @@ VMManagerDetailSection::setSectionName(const QString &name) void VMManagerDetailSection::addSection(const QString &name, const QString &value, VMManager::Display::Name displayField) { - const auto new_section = DetailSection { name, value}; + const auto new_section = DetailSection { name, value }; sections.push_back(new_section); } @@ -158,14 +159,14 @@ VMManagerDetailSection::setupMainLayout() void VMManagerDetailSection::setSections() { - int row = 0; + int row = 0; bool empty = true; - for (const auto& section : sections) { + for (const auto §ion : sections) { QStringList sectionsToAdd = section.value.split(sectionSeparator); - QLabel *labelKey = nullptr; + QLabel *labelKey = nullptr; - for (const auto& line : sectionsToAdd) { + for (const auto &line : sectionsToAdd) { if (line.isEmpty()) { // Don't bother adding entries if the values are blank continue; @@ -203,10 +204,10 @@ VMManagerDetailSection::clear() setVisible(false); // Clear everything out - if(frameGridLayout) { - while(frameGridLayout->count()) { - QLayoutItem * cur_item = frameGridLayout->takeAt(0); - if(cur_item->widget()) + if (frameGridLayout) { + while (frameGridLayout->count()) { + QLayoutItem *cur_item = frameGridLayout->takeAt(0); + if (cur_item->widget()) delete cur_item->widget(); delete cur_item; } @@ -242,15 +243,15 @@ VMManagerDetailSection::getMargins(const MarginSection section) switch (section) { case MarginSection::ToolButton: #if defined(Q_OS_WINDOWS) or defined(Q_OS_LINUX) - return {10, 0, 5, 0}; + return { 10, 0, 5, 0 }; #else - return {0, 0, 5, 0}; + return { 0, 0, 5, 0 }; #endif case MarginSection::DisplayGrid: #if defined(Q_OS_WINDOWS) or defined(Q_OS_LINUX) - return {10, 0, 0, 10}; + return { 10, 0, 0, 10 }; #else - return {0, 0, 0, 10}; + return { 0, 0, 0, 10 }; #endif default: return {}; @@ -259,7 +260,10 @@ VMManagerDetailSection::getMargins(const MarginSection section) // CollapseButton Class -CollapseButton::CollapseButton(QWidget *parent) : QToolButton(parent), content_(nullptr) { +CollapseButton::CollapseButton(QWidget *parent) + : QToolButton(parent) + , content_(nullptr) +{ setCheckable(true); setStyleSheet("background:none; border:none;"); setIconSize(QSize(8, 8)); @@ -267,16 +271,20 @@ CollapseButton::CollapseButton(QWidget *parent) : QToolButton(parent), content_( setToolButtonStyle(Qt::ToolButtonTextBesideIcon); connect(this, &QToolButton::toggled, [=](const bool checked) { setArrowType(checked ? Qt::ArrowType::DownArrow : Qt::ArrowType::RightArrow); - content_ != nullptr && checked ? showContent() : hideContent(); + content_ != nullptr &&checked ? showContent() : hideContent(); }); setChecked(true); } -void CollapseButton::setButtonText(const QString &text) { +void +CollapseButton::setButtonText(const QString &text) +{ setText(" " + text); } -void CollapseButton::setContent(QWidget *content) { +void +CollapseButton::setContent(QWidget *content) +{ assert(content != nullptr); content_ = content; const auto animation_ = new QPropertyAnimation(content_, "maximumHeight"); // QObject with auto delete @@ -292,12 +300,16 @@ void CollapseButton::setContent(QWidget *content) { } } -void CollapseButton::hideContent() { +void +CollapseButton::hideContent() +{ animator_.setDirection(QAbstractAnimation::Backward); animator_.start(); } -void CollapseButton::showContent() { +void +CollapseButton::showContent() +{ animator_.setDirection(QAbstractAnimation::Forward); animator_.start(); } diff --git a/src/qt/qt_vmmanager_detailsection.hpp b/src/qt/qt_vmmanager_detailsection.hpp index bca24527539..71a3c992e82 100644 --- a/src/qt/qt_vmmanager_detailsection.hpp +++ b/src/qt/qt_vmmanager_detailsection.hpp @@ -24,7 +24,9 @@ #include "qt_vmmanager_system.hpp" QT_BEGIN_NAMESPACE -namespace Ui { class DetailSection; } +namespace Ui { +class DetailSection; +} QT_END_NAMESPACE class CollapseButton final : public QToolButton { @@ -42,8 +44,8 @@ class CollapseButton final : public QToolButton { void showContent(); private: - QWidget *content_; - QString text_; + QWidget *content_; + QString text_; QParallelAnimationGroup animator_; }; @@ -61,13 +63,13 @@ class VMManagerDetailSection final : public QWidget { void setSections(); void clear(); - QLabel *tableLabel; + QLabel *tableLabel; CollapseButton *collapseButton; -// QGridLayout *buttonGridLayout; + // QGridLayout *buttonGridLayout; QGridLayout *frameGridLayout; QVBoxLayout *mainLayout; QHBoxLayout *buttonLayout; - QFrame *frame; + QFrame *frame; static const QString sectionSeparator; @@ -96,8 +98,7 @@ public slots: }; QVector sections; - Ui::DetailSection *ui; - + Ui::DetailSection *ui; }; #endif // QT_VMMANAGER_DETAILSECTION_H diff --git a/src/qt/qt_vmmanager_listviewdelegate.cpp b/src/qt/qt_vmmanager_listviewdelegate.cpp index 67fb80bb7b9..88d123ce90a 100644 --- a/src/qt/qt_vmmanager_listviewdelegate.cpp +++ b/src/qt/qt_vmmanager_listviewdelegate.cpp @@ -1,17 +1,17 @@ /* -* 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. -* -* 86Box VM manager list view delegate module -* -* Authors: cold-brewed -* -* Copyright 2024 cold-brewed -*/ + * 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. + * + * 86Box VM manager list view delegate module + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ #include #include "qt_util.hpp" @@ -22,25 +22,27 @@ // from https://stackoverflow.com/questions/53105343/is-it-possible-to-add-a-custom-widget-into-a-qlistview VMManagerListViewDelegate::VMManagerListViewDelegate(QObject *parent) - : QStyledItemDelegate(parent), - m_ptr(new VMManagerListViewDelegateStyle) + : QStyledItemDelegate(parent) + , m_ptr(new VMManagerListViewDelegateStyle) { default_icon = QIcon(":/settings/qt/icons/86Box-gray.ico"); - stop_icon = QApplication::style()->standardIcon(QStyle::SP_MediaStop); + stop_icon = QApplication::style()->standardIcon(QStyle::SP_MediaStop); running_icon = QIcon(":/menuicons/qt/icons/run.ico"); stopped_icon = QIcon(":/menuicons/qt/icons/acpi_shutdown.ico"); - paused_icon = QIcon(":/menuicons/qt/icons/pause.ico"); + paused_icon = QIcon(":/menuicons/qt/icons/pause.ico"); unknown_icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion); highlight_color = QColor("#616161"); - bg_color = QColor("#272727"); + bg_color = QColor("#272727"); } VMManagerListViewDelegate::~VMManagerListViewDelegate() -= default; + = default; -void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const { +void +VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ bool windows_light_mode = true; #ifdef Q_OS_WINDOWS windows_light_mode = util::isWindowsLightTheme(); @@ -51,16 +53,16 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI // opt.rect = opt.rect.adjusted(0, 0, 0, 20); const QRect &rect(opt.rect); const QRect &contentRect(rect.adjusted(m_ptr->margins.left(), - m_ptr->margins.top(), - -m_ptr->margins.right(), - -m_ptr->margins.bottom())); + m_ptr->margins.top(), + -m_ptr->margins.right(), + -m_ptr->margins.bottom())); // The status icon represents the current state of the vm. Initially set to a default state. auto process_variant = index.data(VMManagerModel::Roles::ProcessStatus); - auto process_status = process_variant.value(); + auto process_status = process_variant.value(); // The main icon, configurable. Falls back to default if it cannot be loaded. auto customIcon = index.data(VMManagerModel::Roles::Icon).toString(); - opt.icon = default_icon; + opt.icon = default_icon; if (!customIcon.isEmpty()) { const auto customPixmap = QPixmap(customIcon); if (!customPixmap.isNull()) @@ -69,7 +71,7 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI // Set the status icon based on the process status QIcon status_icon; - switch(process_status) { + switch (process_status) { case VMManagerSystem::ProcessStatus::Running: status_icon = running_icon; break; @@ -85,12 +87,11 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI status_icon = unknown_icon; } - // Used to determine if the horizontal separator should be drawn - const bool lastIndex = (index.model()->rowCount() - 1) == index.row(); - const bool hasIcon = !opt.icon.isNull(); - const int bottomEdge = rect.bottom(); - QFont f(opt.font); + const bool lastIndex = (index.model()->rowCount() - 1) == index.row(); + const bool hasIcon = !opt.icon.isNull(); + const int bottomEdge = rect.bottom(); + QFont f(opt.font); f.setPointSizeF(m_ptr->statusFontPointSize(opt.font)); @@ -102,11 +103,11 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI // Draw the background if (opt.state & QStyle::State_Selected) { // When selected, only draw the highlighted part until the horizontal separator - int offset = 2; + int offset = 2; auto highlightRect = rect.adjusted(0, 0, 0, -offset); painter->fillRect(highlightRect, windows_light_mode ? palette.highlight().color() : highlight_color); // Then fill the remainder with the normal color - auto regularRect = rect.adjusted(0, rect.height()-offset, 0, 0); + auto regularRect = rect.adjusted(0, rect.height() - offset, 0, 0); painter->fillRect(regularRect, windows_light_mode ? palette.light().color() : bg_color); } else { // Otherwise just draw the background color as usual @@ -129,16 +130,16 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI QRect systemNameRect(m_ptr->systemNameBox(opt, index)); systemNameRect.moveTo(m_ptr->margins.left() + m_ptr->iconSize.width() - + m_ptr->spacingHorizontal, contentRect.top()); + + m_ptr->spacingHorizontal, + contentRect.top()); // If desired, font can be changed here -// painter->setFont(f); + // painter->setFont(f); painter->setFont(opt.font); painter->setPen(palette.text().color()); painter->drawText(systemNameRect, Qt::TextSingleLine, opt.text); // Draw status icon - painter->drawPixmap(systemNameRect.left(), systemNameRect.bottom() - + m_ptr->spacingVertical, + painter->drawPixmap(systemNameRect.left(), systemNameRect.bottom() + m_ptr->spacingVertical, status_icon.pixmap(m_ptr->smallIconSize)); // This rectangle is around the status icon @@ -150,53 +151,58 @@ void VMManagerListViewDelegate::paint(QPainter *painter, const QStyleOptionViewI // Draw status text QRect statusRect(m_ptr->statusBox(opt, index)); - int extraaa = 2; + int extraaa = 2; statusRect.moveTo(systemNameRect.left() + m_ptr->margins.left() + m_ptr->smallIconSize.width(), - systemNameRect.bottom() + m_ptr->spacingVertical + extraaa + (m_ptr->smallIconSize.height() - systemNameRect.height() )); + systemNameRect.bottom() + m_ptr->spacingVertical + extraaa + (m_ptr->smallIconSize.height() - systemNameRect.height())); -// painter->setFont(opt.font); + // painter->setFont(opt.font); painter->setFont(f); painter->setPen(palette.windowText().color()); painter->drawText(statusRect, Qt::TextSingleLine, index.data(VMManagerModel::Roles::ProcessStatusString).toString()); painter->restore(); - } -QMargins VMManagerListViewDelegate::contentsMargins() const +QMargins +VMManagerListViewDelegate::contentsMargins() const { return m_ptr->margins; } -void VMManagerListViewDelegate::setContentsMargins(const int left, const int top, const int right, const int bottom) const +void +VMManagerListViewDelegate::setContentsMargins(const int left, const int top, const int right, const int bottom) const { m_ptr->margins = QMargins(left, top, right, bottom); } -int VMManagerListViewDelegate::horizontalSpacing() const +int +VMManagerListViewDelegate::horizontalSpacing() const { return m_ptr->spacingHorizontal; } -void VMManagerListViewDelegate::setHorizontalSpacing(const int spacing) const +void +VMManagerListViewDelegate::setHorizontalSpacing(const int spacing) const { m_ptr->spacingHorizontal = spacing; } -int VMManagerListViewDelegate::verticalSpacing() const +int +VMManagerListViewDelegate::verticalSpacing() const { return m_ptr->spacingVertical; } -void VMManagerListViewDelegate::setVerticalSpacing(const int spacing) const +void +VMManagerListViewDelegate::setVerticalSpacing(const int spacing) const { m_ptr->spacingVertical = spacing; } - -QSize VMManagerListViewDelegate::sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const +QSize +VMManagerListViewDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const { QStyleOptionViewItem opt(option); initStyleOption(&opt, index); @@ -204,45 +210,48 @@ QSize VMManagerListViewDelegate::sizeHint(const QStyleOptionViewItem &option, const int textHeight = m_ptr->systemNameBox(opt, index).height() + m_ptr->spacingVertical + m_ptr->statusBox(opt, index).height(); const int iconHeight = m_ptr->iconSize.height(); - const int h = textHeight > iconHeight ? textHeight : iconHeight; + const int h = textHeight > iconHeight ? textHeight : iconHeight; // return the same width // for height, add margins on top and bottom *plus* either the text or icon height, whichever is greater // Note: text height is the combined value of the system name and the status just below the name - return {opt.rect.width(), m_ptr->margins.top() + h - + m_ptr->margins.bottom()}; + return { opt.rect.width(), m_ptr->margins.top() + h + m_ptr->margins.bottom() }; } -VMManagerListViewDelegateStyle::VMManagerListViewDelegateStyle() : - iconSize(32, 32), - smallIconSize(16, 16), +VMManagerListViewDelegateStyle::VMManagerListViewDelegateStyle() + : iconSize(32, 32) + , smallIconSize(16, 16) + , // bottom gets a little more than the top because of the custom separator - margins(4, 10, 8, 12), + margins(4, 10, 8, 12) + , // Spacing between icon and text - spacingHorizontal(8), - spacingVertical(4) + spacingHorizontal(8) + , spacingVertical(4) { // } -QRect VMManagerListViewDelegateStyle::statusBox(const QStyleOptionViewItem &option, - const QModelIndex &index) const +QRect +VMManagerListViewDelegateStyle::statusBox(const QStyleOptionViewItem &option, + const QModelIndex &index) const { QFont f(option.font); f.setPointSizeF(statusFontPointSize(option.font)); - return QFontMetrics(f).boundingRect(index.data(VMManagerModel::Roles::ProcessStatusString).toString()) - .adjusted(0, 0, 1, 1); + return QFontMetrics(f).boundingRect(index.data(VMManagerModel::Roles::ProcessStatusString).toString()).adjusted(0, 0, 1, 1); } -qreal VMManagerListViewDelegateStyle::statusFontPointSize(const QFont &f) const +qreal +VMManagerListViewDelegateStyle::statusFontPointSize(const QFont &f) const { - return 0.75*f.pointSize(); -// return 1*f.pointSize(); + return 0.75 * f.pointSize(); + // return 1*f.pointSize(); } -QRect VMManagerListViewDelegateStyle::systemNameBox(const QStyleOptionViewItem &option, const QModelIndex &index) const +QRect +VMManagerListViewDelegateStyle::systemNameBox(const QStyleOptionViewItem &option, const QModelIndex &index) const { return option.fontMetrics.boundingRect(option.text).adjusted(0, 0, 1, 1); } diff --git a/src/qt/qt_vmmanager_listviewdelegate.hpp b/src/qt/qt_vmmanager_listviewdelegate.hpp index a561c89d20e..db86824d40a 100644 --- a/src/qt/qt_vmmanager_listviewdelegate.hpp +++ b/src/qt/qt_vmmanager_listviewdelegate.hpp @@ -19,20 +19,19 @@ #include #include "qt_vmmanager_system.hpp" -class VMManagerListViewDelegateStyle -{ +class VMManagerListViewDelegateStyle { VMManagerListViewDelegateStyle(); [[nodiscard]] inline QRect systemNameBox(const QStyleOptionViewItem &option, - const QModelIndex &index) const; + const QModelIndex &index) const; [[nodiscard]] inline qreal statusFontPointSize(const QFont &f) const; [[nodiscard]] inline QRect statusBox(const QStyleOptionViewItem &option, const QModelIndex &index) const; - QSize iconSize; - QSize smallIconSize; + QSize iconSize; + QSize smallIconSize; QMargins margins; - int spacingHorizontal; - int spacingVertical; + int spacingHorizontal; + int spacingVertical; friend class VMManagerListViewDelegate; }; @@ -46,18 +45,19 @@ class VMManagerListViewDelegate final : public QStyledItemDelegate { using QStyledItemDelegate::QStyledItemDelegate; [[nodiscard]] QMargins contentsMargins() const; - void setContentsMargins(int left, int top, int right, int bottom) const; + void setContentsMargins(int left, int top, int right, int bottom) const; [[nodiscard]] int horizontalSpacing() const; - void setHorizontalSpacing(int spacing) const; + void setHorizontalSpacing(int spacing) const; [[nodiscard]] int verticalSpacing() const; - void setVerticalSpacing(int spacing) const; + void setVerticalSpacing(int spacing) const; - void paint(QPainter *painter, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; [[nodiscard]] QSize sizeHint(const QStyleOptionViewItem &option, - const QModelIndex &index) const override; + const QModelIndex &index) const override; + private: VMManagerListViewDelegateStyle *m_ptr; diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 5bc936268a9..54e0c619fae 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -33,41 +33,33 @@ #include "qt_vmmanager_model.hpp" #include "qt_vmmanager_addmachine.hpp" -extern VMManagerMainWindow* vmm_main_window; +extern VMManagerMainWindow *vmm_main_window; // https://stackoverflow.com/a/36460740 -bool copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory) +bool +copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory) { QDir originDirectory(sourceDir); - if (! originDirectory.exists()) - { + if (!originDirectory.exists()) return false; - } QDir destinationDirectory(destinationDir); - if(destinationDirectory.exists() && !overWriteDirectory) - { + if (destinationDirectory.exists() && !overWriteDirectory) return false; - } - else if(destinationDirectory.exists() && overWriteDirectory) - { + else if (destinationDirectory.exists() && overWriteDirectory) destinationDirectory.removeRecursively(); - } originDirectory.mkpath(destinationDir); - foreach (QString directoryName, originDirectory.entryList(QDir::Dirs | \ - QDir::NoDotAndDotDot)) - { + foreach (QString directoryName, originDirectory.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { QString destinationPath = destinationDir + "/" + directoryName; originDirectory.mkpath(destinationPath); copyPath(sourceDir + "/" + directoryName, destinationPath, overWriteDirectory); } - foreach (QString fileName, originDirectory.entryList(QDir::Files)) - { + foreach (QString fileName, originDirectory.entryList(QDir::Files)) { QFile::copy(sourceDir + "/" + fileName, destinationDir + "/" + fileName); } @@ -75,21 +67,22 @@ bool copyPath(QString sourceDir, QString destinationDir, bool overWriteDirectory QDir finalDestination(destinationDir); finalDestination.refresh(); - if(finalDestination.exists()) - { + if (finalDestination.exists()) return true; - } return false; } -VMManagerMain::VMManagerMain(QWidget *parent) : - QWidget(parent), ui(new Ui::VMManagerMain), selected_sysconfig(new VMManagerSystem) { +VMManagerMain::VMManagerMain(QWidget *parent) + : QWidget(parent) + , ui(new Ui::VMManagerMain) + , selected_sysconfig(new VMManagerSystem) +{ ui->setupUi(this); // Set up the main listView ui->listView->setItemDelegate(new VMManagerListViewDelegate); - vm_model = new VMManagerModel; + vm_model = new VMManagerModel; proxy_model = new StringListProxyModel(this); proxy_model->setSourceModel(vm_model); ui->listView->setModel(proxy_model); @@ -157,16 +150,15 @@ VMManagerMain::VMManagerMain(QWidget *parent) : contextMenu.addAction(&nameChangeAction); // Use a lambda to call a function so indexAt can be passed connect(&nameChangeAction, &QAction::triggered, ui->listView, [this, indexAt] { - updateDisplayName(indexAt); + updateDisplayName(indexAt); }); nameChangeAction.setEnabled(!selected_sysconfig->window_obscured); - QAction setSystemIcon(tr("Set &icon...")); contextMenu.addAction(&setSystemIcon); connect(&setSystemIcon, &QAction::triggered, [this] { IconSelectionDialog dialog(":/systemicons/"); - if(dialog.exec() == QDialog::Accepted) { + if (dialog.exec() == QDialog::Accepted) { const QString iconName = dialog.getSelectedIconName(); // A Blank iconName will cause setIcon to reset to the default selected_sysconfig->setIcon(iconName); @@ -180,28 +172,28 @@ VMManagerMain::VMManagerMain(QWidget *parent) : contextMenu.addAction(&cloneMachine); connect(&cloneMachine, &QAction::triggered, [this] { QDialog dialog = QDialog(this); - auto layout = new QVBoxLayout(&dialog); + auto layout = new QVBoxLayout(&dialog); layout->setSizeConstraint(QLayout::SetFixedSize); layout->addWidget(new QLabel(tr("Virtual machine \"%1\" (%2) will be cloned into:").arg(selected_sysconfig->displayName, selected_sysconfig->config_dir))); - QLineEdit* edit = new QLineEdit(&dialog); + QLineEdit *edit = new QLineEdit(&dialog); layout->addWidget(edit); - QLabel* errLabel = new QLabel(&dialog); + QLabel *errLabel = new QLabel(&dialog); layout->addWidget(errLabel); errLabel->setVisible(false); - QDialogButtonBox* buttonBox = new QDialogButtonBox(&dialog); + QDialogButtonBox *buttonBox = new QDialogButtonBox(&dialog); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); buttonBox->button(QDialogButtonBox::Ok)->setDisabled(true); connect(buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); layout->addWidget(buttonBox); - connect(edit, &QLineEdit::textChanged, this, [errLabel, buttonBox] (const QString& text) { + connect(edit, &QLineEdit::textChanged, this, [errLabel, buttonBox](const QString &text) { bool isSpaceOnly = true; #ifdef Q_OS_WINDOWS const char illegalChars[] = "<>:\"|?*\\/"; #else const char illegalChars[] = "\\/"; #endif - for (const auto& curChar : text) { + for (const auto &curChar : text) { for (size_t i = 0; i < sizeof(illegalChars) - 1; i++) { if (illegalChars[i] == curChar) { goto illegal_chars; @@ -236,9 +228,9 @@ VMManagerMain::VMManagerMain(QWidget *parent) : }); if (dialog.exec() > 0) { - std::atomic_bool finished{false}; + std::atomic_bool finished { false }; std::atomic_bool errCode; - auto vmDir = QDir(vmm_path).canonicalPath(); + auto vmDir = QDir(vmm_path).canonicalPath(); vmDir.append("/"); vmDir.append(edit->text()); vmDir.append("/"); @@ -248,7 +240,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : return; } - QProgressDialog* progDialog = new QProgressDialog(this); + QProgressDialog *progDialog = new QProgressDialog(this); progDialog->setMaximum(0); progDialog->setMinimum(0); progDialog->setWindowFlags(progDialog->windowFlags() & ~Qt::WindowCloseButtonHint); @@ -266,7 +258,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : QString dstPath = vmDir; std::thread copyThread([&finished, srcPath, dstPath, &errCode] { - errCode = copyPath(srcPath, dstPath, true); + errCode = copyPath(srcPath, dstPath, true); finished = true; }); while (!finished) { @@ -346,7 +338,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : QDir dir(configDir); if (!dir.exists()) dir.mkpath("."); - + QDesktopServices::openUrl(QUrl(QString("file:///") + dir.canonicalPath())); } }); @@ -358,7 +350,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : QDir dir(printerDir); if (!dir.exists()) dir.mkpath("."); - + QDesktopServices::openUrl(QUrl(QString("file:///") + dir.canonicalPath())); } }); @@ -370,7 +362,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : QDir dir(screenshotsDir); if (!dir.exists()) dir.mkpath("."); - + QDesktopServices::openUrl(QUrl(QString("file:///") + dir.canonicalPath())); } }); @@ -395,7 +387,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : } }); - connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [] () { + connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, []() { vmm_main_window->updateSettings(); }); @@ -416,7 +408,7 @@ VMManagerMain::VMManagerMain(QWidget *parent) : // Load and apply settings loadSettings(); - ui->splitter->setSizes({ui->detailsArea->width(), (ui->listView->minimumWidth() * 2)}); + ui->splitter->setSizes({ ui->detailsArea->width(), (ui->listView->minimumWidth() * 2) }); // Set up search bar connect(ui->searchBar, &QLineEdit::textChanged, this, &VMManagerMain::searchSystems); @@ -439,14 +431,14 @@ VMManagerMain::VMManagerMain(QWidget *parent) : #if EMU_BUILD_NUM != 0 // Start update check after a slight delay QTimer::singleShot(1000, this, [this] { - if(updateCheck) { - backgroundUpdateCheckStart(); - } + if (updateCheck) + backgroundUpdateCheckStart(); }); #endif } -VMManagerMain::~VMManagerMain() { +VMManagerMain::~VMManagerMain() +{ delete ui; delete vm_model; } @@ -459,11 +451,10 @@ VMManagerMain::updateGlobalSettings() void VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, - const QModelIndex &previous) + const QModelIndex &previous) { - if(!current.isValid()) { + if (!current.isValid()) return; - } /* hack to prevent strange segfaults when adding a machine after removing all machines previously */ @@ -472,7 +463,7 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, selected_sysconfig->config_signal_connected = false; } const auto mapped_index = proxy_model->mapToSource(current); - selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); + selected_sysconfig = vm_model->getConfigObjectForIndex(mapped_index); vm_details->updateData(selected_sysconfig); if (selected_sysconfig->config_signal_connected == false) { connect(selected_sysconfig, &VMManagerSystem::configurationChanged, this, &VMManagerMain::onConfigUpdated); @@ -481,60 +472,59 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, // Emit that the selection changed, include with the process state emit selectionChanged(current, selected_sysconfig->process->state()); - } void -VMManagerMain::settingsButtonPressed() { - if(!currentSelectionIsValid()) { +VMManagerMain::settingsButtonPressed() +{ + if (!currentSelectionIsValid()) return; - } + selected_sysconfig->launchSettings(); } void VMManagerMain::startButtonPressed() const { - if(!currentSelectionIsValid()) { + if (!currentSelectionIsValid()) return; - } + selected_sysconfig->startButtonPressed(); } void VMManagerMain::restartButtonPressed() const { - if(!currentSelectionIsValid()) { + if (!currentSelectionIsValid()) return; - } - selected_sysconfig->restartButtonPressed(); + selected_sysconfig->restartButtonPressed(); } void VMManagerMain::pauseButtonPressed() const { - if(!currentSelectionIsValid()) { + if (!currentSelectionIsValid()) return; - } + selected_sysconfig->pauseButtonPressed(); } void VMManagerMain::shutdownRequestButtonPressed() const { - if (!currentSelectionIsValid()) { + if (!currentSelectionIsValid()) return; - } + selected_sysconfig->shutdownRequestButtonPressed(); } void VMManagerMain::shutdownForceButtonPressed() const { - if (!currentSelectionIsValid()) { + if (!currentSelectionIsValid()) return; - } + selected_sysconfig->shutdownForceButtonPressed(); } @@ -543,10 +533,10 @@ void VMManagerMain::refresh() { const auto current_index = ui->listView->currentIndex(); - emit selectionChanged(current_index, selected_sysconfig->process->state()); + emit selectionChanged(current_index, selected_sysconfig->process->state()); // if(!selected_sysconfig->config_file.path().isEmpty()) { - if(!selected_sysconfig->isValid()) { + if (!selected_sysconfig->isValid()) { // what was happening here? } } @@ -621,7 +611,7 @@ VMManagerMain::searchSystems(const QString &text) const { // Escape the search text string unless regular expression searching is enabled. // When escaped, the search string functions as a plain text match. - const auto searchText = regexSearch ? text : QRegularExpression::escape(text); + const auto searchText = regexSearch ? text : QRegularExpression::escape(text); const QRegularExpression regex(searchText, QRegularExpression::CaseInsensitiveOption); if (!regex.isValid()) { qDebug() << "Skipping, invalid regex"; @@ -640,11 +630,11 @@ VMManagerMain::newMachineWizard() { const auto wizard = new VMManagerAddMachine(this); if (wizard->exec() == QDialog::Accepted) { - const auto newName = wizard->field("systemName").toString(); + const auto newName = wizard->field("systemName").toString(); #ifdef CUSTOM_SYSTEM_LOCATION - const auto systemDir = wizard->field("systemLocation").toString(); + const auto systemDir = wizard->field("systemLocation").toString(); #else - const auto systemDir = QDir(vmm_path).path(); + const auto systemDir = QDir(vmm_path).path(); #endif const auto existingConfiguration = wizard->field("existingConfiguration").toString(); const auto displayName = wizard->field("displayName").toString(); @@ -693,8 +683,7 @@ VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QStri if (exitCode != 0 || exitStatus != QProcess::NormalExit) { qInfo().nospace().noquote() << "Abnormal program termination while creating new system: exit code " << exitCode << ", exit status " << exitStatus; qInfo() << "Not adding system due to errors"; - QString errMsg = tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg( - (!displayName.isEmpty() ? displayName : name), QString::number(exitCode)); + QString errMsg = tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg((!displayName.isEmpty() ? displayName : name), QString::number(exitCode)); QMessageBox::critical(this, tr("Error adding system"), QString("%1\n\n%2").arg(errMsg, tr("The system will not be added."))); fail = true; @@ -731,7 +720,6 @@ VMManagerMain::addNewSystem(const QString &name, const QString &dir, const QStri }); } - void VMManagerMain::deleteSystem(VMManagerSystem *sysconfig) { @@ -804,8 +792,8 @@ VMManagerMain::modelDataChange() auto modelStats = vm_model->getProcessStats(); QStringList stats; for (auto it = modelStats.constBegin(); it != modelStats.constEnd(); ++it) { - const auto &key = it.key(); - QString text = ""; + const auto &key = it.key(); + QString text = ""; switch (key) { case VMManagerSystem::ProcessStatus::Running: text = tr("%n running", "", modelStats[key]); @@ -820,7 +808,7 @@ VMManagerMain::modelDataChange() default: break; } - if(!text.isEmpty()) + if (!text.isEmpty()) stats.append(text); } auto states = stats.join(", "); @@ -831,16 +819,14 @@ void VMManagerMain::onPreferencesUpdated() { // Only reload values that we care about - const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); const auto oldRegexSearch = regexSearch; - regexSearch = config->getStringValue("regex_search").toInt(); - if (oldRegexSearch != regexSearch) { + regexSearch = config->getStringValue("regex_search").toInt(); + if (oldRegexSearch != regexSearch) ui->searchBar->clear(); - } - if (vm_model) { + if (vm_model) vm_model->sendGlobalConfigurationChanged(); - } } void @@ -877,9 +863,9 @@ void VMManagerMain::backgroundUpdateCheckStart() const { auto updateChannel = UpdateCheck::UpdateChannel::CI; -#ifdef RELEASE_BUILD +# ifdef RELEASE_BUILD updateChannel = UpdateCheck::UpdateChannel::Stable; -#endif +# endif const auto updateCheck = new UpdateCheck(updateChannel); connect(updateCheck, &UpdateCheck::updateCheckComplete, this, &VMManagerMain::backgroundUpdateCheckComplete); connect(updateCheck, &UpdateCheck::updateCheckError, this, &VMManagerMain::backgroundUpdateCheckError); @@ -891,9 +877,9 @@ VMManagerMain::backgroundUpdateCheckComplete(const UpdateCheck::UpdateResult &re { qDebug() << "Check complete: update available?" << result.updateAvailable; if (result.updateAvailable) { - auto type = result.channel == UpdateCheck::UpdateChannel::CI ? tr("build") : tr("version"); + auto type = result.channel == UpdateCheck::UpdateChannel::CI ? tr("build") : tr("version"); const auto updateMessage = tr("An update to 86Box is available: %1 %2").arg(type, result.latestVersion); - emit updateStatusLeft(updateMessage); + emit updateStatusLeft(updateMessage); } } @@ -910,7 +896,7 @@ VMManagerMain::showTextFileContents(const QString &title, const QString &path) { // Make sure we can open the file const auto fi = QFileInfo(path); - if(!fi.exists()) { + if (!fi.exists()) { qWarning("Requested file does not exist: %s", path.toUtf8().constData()); return; } @@ -927,7 +913,7 @@ VMManagerMain::showTextFileContents(const QString &title, const QString &path) textDisplayDialog->setMinimumSize(QSize(540, 360)); textDisplayDialog->setWindowTitle(QString("%1 - %2").arg(title, fi.fileName())); - const auto textEdit = new QPlainTextEdit(); + const auto textEdit = new QPlainTextEdit(); const auto monospaceFont = new QFont(); #ifdef Q_OS_WINDOWS monospaceFont->setFamily("Consolas"); diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index 07d1ff0c19d..b08939d1c23 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -32,7 +32,9 @@ extern "C" { #endif QT_BEGIN_NAMESPACE -namespace Ui { class VMManagerMain; } +namespace Ui { +class VMManagerMain; +} QT_END_NAMESPACE class VMManagerMain final : public QWidget { @@ -90,24 +92,24 @@ public slots: private: Ui::VMManagerMain *ui; - VMManagerModel *vm_model; - VMManagerDetails *vm_details; - VMManagerSystem *selected_sysconfig; + VMManagerModel *vm_model; + VMManagerDetails *vm_details; + VMManagerSystem *selected_sysconfig; // VMManagerConfig *config; QSortFilterProxyModel *proxy_model; #if EMU_BUILD_NUM != 0 - bool updateCheck = false; + bool updateCheck = false; #endif - bool regexSearch = false; + bool regexSearch = false; // void updateSelection(const QItemSelection &selected, // const QItemSelection &deselected); - void currentSelectionChanged(const QModelIndex ¤t, - const QModelIndex &previous); - void refresh(); - void updateDisplayName(const QModelIndex &index); - void loadSettings(); - [[nodiscard]] bool currentSelectionIsValid() const; + void currentSelectionChanged(const QModelIndex ¤t, + const QModelIndex &previous); + void refresh(); + void updateDisplayName(const QModelIndex &index); + void loadSettings(); + [[nodiscard]] bool currentSelectionIsValid() const; [[nodiscard]] QString machineCountString(QString states = "") const; #if EMU_BUILD_NUM != 0 void backgroundUpdateCheckStart() const; @@ -129,7 +131,10 @@ class IconSelectionDialog final : public QDialog { Q_OBJECT public: - explicit IconSelectionDialog(QString assetPath, QWidget *parent = nullptr) : QDialog(parent), listWidget(new QListWidget) { + explicit IconSelectionDialog(QString assetPath, QWidget *parent = nullptr) + : QDialog(parent) + , listWidget(new QListWidget) + { // Set the list widget to icon mode listWidget->setViewMode(QListWidget::IconMode); setFixedSize(QSize(540, 360)); @@ -143,7 +148,7 @@ class IconSelectionDialog final : public QDialog { setWindowTitle(tr("Select an icon")); // Loop on all files and add them as items (icons) in QListWidget - for(const QString& iconName : iconsDir.entryList()) { + for (const QString &iconName : iconsDir.entryList()) { const auto item = new QListWidgetItem(QIcon(assetPath + iconName), iconName); // Set the UserRole to the resource bundle path item->setData(Qt::UserRole, assetPath + iconName); @@ -153,7 +158,7 @@ class IconSelectionDialog final : public QDialog { // Dialog buttons const auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Reset); // Use the reset button for resetting the icon to the default - const QPushButton* resetButton = buttonBox->button(QDialogButtonBox::Reset); + const QPushButton *resetButton = buttonBox->button(QDialogButtonBox::Reset); // Connect the buttons signals connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); @@ -171,8 +176,9 @@ class IconSelectionDialog final : public QDialog { layout->addWidget(buttonBox); } - public slots: - [[nodiscard]] QString getSelectedIconName() const { +public slots: + [[nodiscard]] QString getSelectedIconName() const + { if (listWidget->currentIndex().isValid()) { return listWidget->currentItem()->data(Qt::UserRole).toString(); } @@ -181,7 +187,7 @@ class IconSelectionDialog final : public QDialog { } private: - QListWidget* listWidget; + QListWidget *listWidget; }; -#endif //QT_VMMANAGER_MAIN_H +#endif // QT_VMMANAGER_MAIN_H diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 864a2b17ae3..0e44e6a8ca9 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -30,17 +30,16 @@ #include #include -extern "C" -{ +extern "C" { extern void config_load_global(); extern void config_save_global(); } -VMManagerMainWindow* vmm_main_window = nullptr; -extern WindowsDarkModeFilter* vmm_dark_mode_filter; +VMManagerMainWindow *vmm_main_window = nullptr; +extern WindowsDarkModeFilter *vmm_dark_mode_filter; VMManagerMainWindow:: -VMManagerMainWindow(QWidget *parent) + VMManagerMainWindow(QWidget *parent) : ui(new Ui::VMManagerMainWindow) , vmm(new VMManagerMain(this)) , statusLeft(new QLabel) @@ -63,14 +62,14 @@ VMManagerMainWindow(QWidget *parent) connect(ui->actionHard_Reset, &QAction::triggered, vmm, &VMManagerMain::restartButtonPressed); connect(ui->actionForce_Shutdown, &QAction::triggered, vmm, &VMManagerMain::shutdownForceButtonPressed); - // Set up menu actions - // (Disable this if the EMU_BUILD_NUM == 0) - #if EMU_BUILD_NUM == 0 - ui->actionCheck_for_updates->setVisible(false); - #else - connect(ui->actionCheck_for_updates, &QAction::triggered, this, &VMManagerMainWindow::checkForUpdatesTriggered); - #endif - +// Set up menu actions +// (Disable this if the EMU_BUILD_NUM == 0) +#if EMU_BUILD_NUM == 0 + ui->actionCheck_for_updates->setVisible(false); +#else + connect(ui->actionCheck_for_updates, &QAction::triggered, this, &VMManagerMainWindow::checkForUpdatesTriggered); +#endif + // TODO: Remove all of this (all the way to END REMOVE) once certain the search will no longer be in the toolbar. // BEGIN REMOVE // Everything is still setup here for it but it is all hidden. None of it will be @@ -90,7 +89,7 @@ VMManagerMainWindow(QWidget *parent) searchBar->setClearButtonEnabled(true); // Spacer to make the search go all the way to the right const auto spacer = new QWidget(); - spacer->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred); + spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); ui->toolBar->addWidget(spacer); ui->toolBar->addWidget(searchBar); // Connect signal for search @@ -127,7 +126,7 @@ VMManagerMainWindow(QWidget *parent) connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated); #ifdef Q_OS_WINDOWS connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated); - connect(this, &VMManagerMainWindow::preferencesUpdated, [] () { vmm_dark_mode_filter->reselectDarkMode(); }); + connect(this, &VMManagerMainWindow::preferencesUpdated, []() { vmm_dark_mode_filter->reselectDarkMode(); }); #endif { @@ -136,7 +135,7 @@ VMManagerMainWindow(QWidget *parent) QString coords = config->getStringValue("window_coordinates"); if (!coords.isEmpty()) { QStringList list = coords.split(','); - for (auto& cur : list) { + for (auto &cur : list) { cur = cur.trimmed(); } QRect geom; @@ -155,7 +154,7 @@ VMManagerMainWindow(QWidget *parent) QString splitter = config->getStringValue("window_splitter"); if (!splitter.isEmpty()) { QStringList list = splitter.split(','); - for (auto& cur : list) { + for (auto &cur : list) { cur = cur.trimmed(); } QList paneSizes; @@ -173,8 +172,7 @@ VMManagerMainWindow(QWidget *parent) } } -VMManagerMainWindow::~ -VMManagerMainWindow() +VMManagerMainWindow::~VMManagerMainWindow() = default; void @@ -224,7 +222,7 @@ void VMManagerMainWindow::saveSettings() const { const auto currentSelection = vmm->getCurrentSelection(); - const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); config->setStringValue("last_selection", currentSelection); if (!!config->getStringValue("window_remember").toInt()) { config->setStringValue("window_coordinates", QString::asprintf("%i, %i, %i, %i", this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height())); @@ -249,7 +247,6 @@ VMManagerMainWindow::updateLanguage() emit languageUpdated(); } - #ifdef Q_OS_WINDOWS void VMManagerMainWindow::updateDarkMode() diff --git a/src/qt/qt_vmmanager_mainwindow.hpp b/src/qt/qt_vmmanager_mainwindow.hpp index 055e61808d1..c0e06f551bb 100644 --- a/src/qt/qt_vmmanager_mainwindow.hpp +++ b/src/qt/qt_vmmanager_mainwindow.hpp @@ -25,8 +25,7 @@ namespace Ui { class VMManagerMainWindow; } -class VMManagerMainWindow final : public QMainWindow -{ +class VMManagerMainWindow final : public QMainWindow { Q_OBJECT public: explicit VMManagerMainWindow(QWidget *parent = nullptr); @@ -41,10 +40,12 @@ class VMManagerMainWindow final : public QMainWindow private: Ui::VMManagerMainWindow *ui; + VMManagerMain *vmm; - void saveSettings() const; - QLabel *statusLeft; - QLabel *statusRight; + void saveSettings() const; + QLabel *statusLeft; + QLabel *statusRight; + public slots: void setStatusLeft(const QString &text) const; void setStatusRight(const QString &text) const; diff --git a/src/qt/qt_vmmanager_model.cpp b/src/qt/qt_vmmanager_model.cpp index bd66862fdb6..8c631a2f2d3 100644 --- a/src/qt/qt_vmmanager_model.cpp +++ b/src/qt/qt_vmmanager_model.cpp @@ -15,28 +15,32 @@ #include #include "qt_vmmanager_model.hpp" -VMManagerModel::VMManagerModel() { +VMManagerModel::VMManagerModel() +{ auto machines_vec = VMManagerSystem::scanForConfigs(); - for ( const auto& each_config : machines_vec) { + for (const auto &each_config : machines_vec) { machines.append(each_config); connect(each_config, &VMManagerSystem::itemDataChanged, this, &VMManagerModel::modelDataChanged); connect(each_config, &VMManagerSystem::globalConfigurationChanged, this, &VMManagerModel::globalConfigurationChanged); } } -VMManagerModel::~VMManagerModel() { - for ( auto machine : machines) { +VMManagerModel::~VMManagerModel() +{ + for (auto machine : machines) { delete machine; } } int -VMManagerModel::rowCount(const QModelIndex &parent) const { +VMManagerModel::rowCount(const QModelIndex &parent) const +{ return machines.size(); } QVariant -VMManagerModel::data(const QModelIndex &index, int role) const { +VMManagerModel::data(const QModelIndex &index, int role) const +{ if (!index.isValid()) return {}; @@ -76,7 +80,8 @@ VMManagerModel::data(const QModelIndex &index, int role) const { } QVariant -VMManagerModel::headerData(int section, Qt::Orientation orientation, int role) const { +VMManagerModel::headerData(int section, Qt::Orientation orientation, int role) const +{ if (role != Qt::DisplayRole) return {}; @@ -93,7 +98,7 @@ VMManagerModel::getConfigObjectForIndex(const QModelIndex &index) const return machines.at(index.row()); } void -VMManagerModel::reload(QWidget* parent) +VMManagerModel::reload(QWidget *parent) { // Scan for configs auto machines_vec = VMManagerSystem::scanForConfigs(parent); @@ -112,16 +117,17 @@ VMManagerModel::reload(QWidget* parent) } void -VMManagerModel::refreshConfigs() { - for ( const auto& each_config : machines) +VMManagerModel::refreshConfigs() +{ + for (const auto &each_config : machines) each_config->reloadConfig(); } QModelIndex -VMManagerModel::getIndexForConfigFile(const QFileInfo& config_file) +VMManagerModel::getIndexForConfigFile(const QFileInfo &config_file) { int object_index = 0; - for (const auto& config_object: machines) { + for (const auto &config_object : machines) { if (config_object->config_file == config_file) { return this->index(object_index); } @@ -155,7 +161,7 @@ void VMManagerModel::modelDataChanged() { // Inform the model - emit dataChanged(this->index(0), this->index(machines.size()-1)); + emit dataChanged(this->index(0), this->index(machines.size() - 1)); // Inform any interested observers emit systemDataChanged(); } @@ -170,7 +176,7 @@ QMap VMManagerModel::getProcessStats() { QMap stats; - for (const auto& system: machines) { + for (const auto &system : machines) { stats[system->getProcessStatus()] += 1; } return stats; @@ -179,7 +185,7 @@ VMManagerModel::getProcessStats() void VMManagerModel::sendGlobalConfigurationChanged() { - for (auto& system: machines) { + for (auto &system : machines) { if (system->getProcessStatus() != VMManagerSystem::ProcessStatus::Stopped) { system->sendGlobalConfigurationChanged(); } @@ -190,7 +196,7 @@ int VMManagerModel::getActiveMachineCount() { int running = 0; - for (const auto& system: machines) { + for (const auto &system : machines) { if (system->getProcessStatus() != VMManagerSystem::ProcessStatus::Stopped) running++; } diff --git a/src/qt/qt_vmmanager_model.hpp b/src/qt/qt_vmmanager_model.hpp index 4e57dfd95a9..289892d9159 100644 --- a/src/qt/qt_vmmanager_model.hpp +++ b/src/qt/qt_vmmanager_model.hpp @@ -42,29 +42,29 @@ class VMManagerModel final : public QAbstractListModel { Icon }; - [[nodiscard]] int rowCount(const QModelIndex &parent) const override; + [[nodiscard]] int rowCount(const QModelIndex &parent) const override; [[nodiscard]] QVariant data(const QModelIndex &index, int role) const override; [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, - int role) const override; - void addConfigToModel(VMManagerSystem *system_config); - void removeConfigFromModel(VMManagerSystem *system_config); - - [[nodiscard]] VMManagerSystem * getConfigObjectForIndex(const QModelIndex &index) const; - QModelIndex getIndexForConfigFile(const QFileInfo& config_file); - void reload(QWidget* parent = nullptr); - void updateDisplayName(const QModelIndex &index, const QString &newDisplayName); + int role) const override; + void addConfigToModel(VMManagerSystem *system_config); + void removeConfigFromModel(VMManagerSystem *system_config); + + [[nodiscard]] VMManagerSystem *getConfigObjectForIndex(const QModelIndex &index) const; + QModelIndex getIndexForConfigFile(const QFileInfo &config_file); + void reload(QWidget *parent = nullptr); + void updateDisplayName(const QModelIndex &index, const QString &newDisplayName); QMap getProcessStats(); - int getActiveMachineCount(); - void refreshConfigs(); - void sendGlobalConfigurationChanged(); + int getActiveMachineCount(); + void refreshConfigs(); + void sendGlobalConfigurationChanged(); + signals: void systemDataChanged(); void globalConfigurationChanged(); private: QVector machines; - void modelDataChanged(); - + void modelDataChanged(); }; // Note: Custom QSortFilterProxyModel is included here instead of its own file as @@ -72,10 +72,14 @@ class VMManagerModel final : public QAbstractListModel { class StringListProxyModel final : public QSortFilterProxyModel { public: - explicit StringListProxyModel(QObject *parent = nullptr) : QSortFilterProxyModel(parent) {} + explicit StringListProxyModel(QObject *parent = nullptr) + : QSortFilterProxyModel(parent) + { + } protected: - [[nodiscard]] bool filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const override { + [[nodiscard]] bool filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const override + { const QModelIndex index = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent); QStringList stringList = sourceModel()->data(index, VMManagerModel::Roles::SearchList).toStringList(); @@ -89,4 +93,4 @@ class StringListProxyModel final : public QSortFilterProxyModel { } }; -#endif //QT_VMMANAGER_MODEL_H +#endif // QT_VMMANAGER_MODEL_H diff --git a/src/qt/qt_vmmanager_preferences.cpp b/src/qt/qt_vmmanager_preferences.cpp index d13fd8cdd45..eb4f20d3362 100644 --- a/src/qt/qt_vmmanager_preferences.cpp +++ b/src/qt/qt_vmmanager_preferences.cpp @@ -22,8 +22,8 @@ #include "ui_qt_vmmanager_preferences.h" #ifdef Q_OS_WINDOWS -#include "qt_vmmanager_windarkmodefilter.hpp" -extern WindowsDarkModeFilter* vmm_dark_mode_filter; +# include "qt_vmmanager_windarkmodefilter.hpp" +extern WindowsDarkModeFilter *vmm_dark_mode_filter; #endif extern "C" { @@ -33,18 +33,19 @@ extern "C" { } VMManagerPreferences:: -VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences) + VMManagerPreferences(QWidget *parent) + : ui(new Ui::VMManagerPreferences) { ui->setupUi(this); ui->dirSelectButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon)); connect(ui->dirSelectButton, &QPushButton::clicked, this, &VMManagerPreferences::chooseDirectoryLocation); - const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); + const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); const auto configSystemDir = QString(vmm_path_cfg); - if(!configSystemDir.isEmpty()) { + if (!configSystemDir.isEmpty()) { // Prefer this one ui->systemDirectory->setText(QDir::toNativeSeparators(configSystemDir)); - } else if(!QString(vmm_path).isEmpty()) { + } else if (!QString(vmm_path).isEmpty()) { // If specified on command line ui->systemDirectory->setText(QDir::toNativeSeparators(QDir(vmm_path).path())); } @@ -79,8 +80,7 @@ VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences) #endif } -VMManagerPreferences::~ -VMManagerPreferences() +VMManagerPreferences::~VMManagerPreferences() = default; // Bad copy pasta from machine add @@ -104,7 +104,7 @@ VMManagerPreferences::accept() const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); strncpy(vmm_path_cfg, QDir::cleanPath(ui->systemDirectory->text()).toUtf8().constData(), sizeof(vmm_path_cfg) - 1); - lang_id = ui->comboBoxLanguage->currentData().toInt(); + lang_id = ui->comboBoxLanguage->currentData().toInt(); color_scheme = (ui->radioButtonSystem->isChecked()) ? 0 : (ui->radioButtonLight->isChecked() ? 1 : 2); config_save_global(); diff --git a/src/qt/qt_vmmanager_preferences.hpp b/src/qt/qt_vmmanager_preferences.hpp index ee5cf1fe8c6..4215eb76892 100644 --- a/src/qt/qt_vmmanager_preferences.hpp +++ b/src/qt/qt_vmmanager_preferences.hpp @@ -1,29 +1,29 @@ /* -* 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 for 86Box VM manager preferences module -* -* Authors: cold-brewed -* -* Copyright 2024 cold-brewed -*/ + * 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 for 86Box VM manager preferences module + * + * Authors: cold-brewed + * + * Copyright 2024 cold-brewed + */ #ifndef VMMANAGER_PREFERENCES_H #define VMMANAGER_PREFERENCES_H #include QT_BEGIN_NAMESPACE -namespace Ui { class VMManagerPreferences; } +namespace Ui { +class VMManagerPreferences; +} QT_END_NAMESPACE - -class VMManagerPreferences final : public QDialog -{ +class VMManagerPreferences final : public QDialog { Q_OBJECT public: explicit VMManagerPreferences(QWidget *parent = nullptr); @@ -31,14 +31,14 @@ class VMManagerPreferences final : public QDialog private: Ui::VMManagerPreferences *ui; - QString settingsFile; + QString settingsFile; private slots: void chooseDirectoryLocation(); void on_pushButtonLanguage_released(); + protected: void accept() override; void reject() override; - }; #endif // VMMANAGER_PREFERENCES_H diff --git a/src/qt/qt_vmmanager_preferences.ui b/src/qt/qt_vmmanager_preferences.ui index 7f7b94fa410..7206b79bfd9 100644 --- a/src/qt/qt_vmmanager_preferences.ui +++ b/src/qt/qt_vmmanager_preferences.ui @@ -15,10 +15,10 @@ - QLayout::SizeConstraint::SetFixedSize + QLayout::SetFixedSize - + System Directory: @@ -146,7 +146,7 @@ - Qt::Orientation::Vertical + Qt::Vertical @@ -159,10 +159,10 @@ - Qt::Orientation::Horizontal + Qt::Horizontal - QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok + QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/src/qt/qt_vmmanager_protocol.cpp b/src/qt/qt_vmmanager_protocol.cpp index 3091b0254d2..a389c96de86 100644 --- a/src/qt/qt_vmmanager_protocol.cpp +++ b/src/qt/qt_vmmanager_protocol.cpp @@ -22,12 +22,12 @@ VMManagerProtocol::VMManagerProtocol(VMManagerProtocol::Sender sender) } VMManagerProtocol::~VMManagerProtocol() -= default; + = default; QJsonObject VMManagerProtocol::protocolManagerMessage(VMManagerProtocol::ManagerMessage message_type) { - auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Manager); + auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Manager); json_message["message"] = managerMessageTypeToString(message_type); return json_message; } @@ -35,7 +35,7 @@ VMManagerProtocol::protocolManagerMessage(VMManagerProtocol::ManagerMessage mess QJsonObject VMManagerProtocol::protocolClientMessage(VMManagerProtocol::ClientMessage message_type) { - auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Client); + auto json_message = constructDefaultObject(VMManagerProtocol::Sender::Client); json_message["message"] = clientMessageTypeToString(message_type); return json_message; } @@ -58,16 +58,16 @@ QJsonObject VMManagerProtocol::constructDefaultObject(VMManagerProtocol::Sender type) { QJsonObject json_message; - QString sender_type = ( type == VMManagerProtocol::Sender::Client ) ? "Client" : "VMManager"; - json_message["type"] = QString(sender_type); + QString sender_type = (type == VMManagerProtocol::Sender::Client) ? "Client" : "VMManager"; + json_message["type"] = QString(sender_type); json_message["version"] = QStringLiteral(EMU_VERSION); return json_message; } bool -VMManagerProtocol::hasRequiredFields(const QJsonObject& json_document) +VMManagerProtocol::hasRequiredFields(const QJsonObject &json_document) { - for (const auto& field : ProtocolRequiredFields) { + for (const auto &field : ProtocolRequiredFields) { if (!json_document.contains(field)) { qDebug("Received json missing field \"%s\"", qPrintable(field)); return false; @@ -83,21 +83,21 @@ VMManagerProtocol::getClientMessageType(const QJsonObject &json_document) // required values. QString message_type = json_document.value("message").toString(); // Can't use switch with strings, manual compare - if (message_type == "Status") { + if (message_type == "Status") return VMManagerProtocol::ClientMessage::Status; - } else if (message_type == "WindowBlocked") { + else if (message_type == "WindowBlocked") return VMManagerProtocol::ClientMessage::WindowBlocked; - } else if (message_type == "WindowUnblocked") { + else if (message_type == "WindowUnblocked") return VMManagerProtocol::ClientMessage::WindowUnblocked; - } else if (message_type == "RunningStateChanged") { + else if (message_type == "RunningStateChanged") return VMManagerProtocol::ClientMessage::RunningStateChanged; - } else if (message_type == "ConfigurationChanged") { + else if (message_type == "ConfigurationChanged") return VMManagerProtocol::ClientMessage::ConfigurationChanged; - } else if (message_type == "WinIdMessage") { + else if (message_type == "WinIdMessage") return VMManagerProtocol::ClientMessage::WinIdMessage; - } else if (message_type == "GlobalConfigurationChanged") { + else if (message_type == "GlobalConfigurationChanged") return VMManagerProtocol::ClientMessage::GlobalConfigurationChanged; - } + return VMManagerProtocol::ClientMessage::UnknownMessage; } @@ -108,23 +108,29 @@ VMManagerProtocol::getManagerMessageType(const QJsonObject &json_document) // required values. QString message_type = json_document.value("message").toString(); // Can't use switch with strings, manual compare - if (message_type == "RequestStatus") { + if (message_type == "RequestStatus") return VMManagerProtocol::ManagerMessage::RequestStatus; - } else if (message_type == "Pause") { + else if (message_type == "Pause") return VMManagerProtocol::ManagerMessage::Pause; - } if (message_type == "CtrlAltDel") { + + if (message_type == "CtrlAltDel") return VMManagerProtocol::ManagerMessage::CtrlAltDel; - } if (message_type == "ShowSettings") { + + if (message_type == "ShowSettings") return VMManagerProtocol::ManagerMessage::ShowSettings; - } if (message_type == "ResetVM") { + + if (message_type == "ResetVM") return VMManagerProtocol::ManagerMessage::ResetVM; - } if (message_type == "RequestShutdown") { + + if (message_type == "RequestShutdown") return VMManagerProtocol::ManagerMessage::RequestShutdown; - } if (message_type == "ForceShutdown") { + + if (message_type == "ForceShutdown") return VMManagerProtocol::ManagerMessage::ForceShutdown; - } if (message_type == "GlobalConfigurationChanged") { + + if (message_type == "GlobalConfigurationChanged") return VMManagerProtocol::ManagerMessage::GlobalConfigurationChanged; - } + return VMManagerProtocol::ManagerMessage::UnknownMessage; } @@ -134,8 +140,8 @@ VMManagerProtocol::getParams(const QJsonObject &json_document) // FIXME: This key ("params") is hardcoded here. Make a hash which maps these // required values. auto params_object = json_document.value("params"); - if (params_object.type() != QJsonValue::Object) { + if (params_object.type() != QJsonValue::Object) return {}; - } + return params_object.toObject(); } diff --git a/src/qt/qt_vmmanager_serversocket.cpp b/src/qt/qt_vmmanager_serversocket.cpp index 36234feec44..877a8a9623c 100644 --- a/src/qt/qt_vmmanager_serversocket.cpp +++ b/src/qt/qt_vmmanager_serversocket.cpp @@ -22,11 +22,11 @@ VMManagerServerSocket::VMManagerServerSocket(const QFileInfo &config_path, const ServerType type) { - server_type = type; - config_file = config_path; + server_type = type; + config_file = config_path; serverIsRunning = false; - socket = nullptr; - server = new QLocalServer; + socket = nullptr; + server = new QLocalServer; setupVars(); } @@ -36,7 +36,8 @@ VMManagerServerSocket::~VMManagerServerSocket() } bool -VMManagerServerSocket::startServer() { +VMManagerServerSocket::startServer() +{ // Remove socket file (if it exists) in order to start a new one qInfo("Socket path is %s", qPrintable(socket_path.filePath())); @@ -60,10 +61,11 @@ VMManagerServerSocket::startServer() { } void -VMManagerServerSocket::serverConnectionReceived() { +VMManagerServerSocket::serverConnectionReceived() +{ qDebug("Connection received on %s", qPrintable(socket_path.fileName())); socket = server->nextPendingConnection(); - if(!socket) { + if (!socket) { qInfo("Invalid socket when trying to receive the connection"); return; } @@ -72,14 +74,15 @@ VMManagerServerSocket::serverConnectionReceived() { } void -VMManagerServerSocket::serverReceivedMessage() { +VMManagerServerSocket::serverReceivedMessage() +{ // Handle legacy socket connections first. These connections only receive // information on window status - if(server_type == VMManagerServerSocket::ServerType::Legacy) { - QByteArray tempString = socket->read(1); - int window_obscured = tempString.toInt(); - emit windowStatusChanged(window_obscured); + if (server_type == VMManagerServerSocket::ServerType::Legacy) { + QByteArray tempString = socket->read(1); + int window_obscured = tempString.toInt(); + emit windowStatusChanged(window_obscured); return; } @@ -93,7 +96,7 @@ VMManagerServerSocket::serverReceivedMessage() { // Try to read the data stream >> jsonData; if (stream.commitTransaction()) { - QJsonParseError parse_error{}; + QJsonParseError parse_error {}; // Validate the received data to make sure it's valid json const QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parse_error); if (parse_error.error == QJsonParseError::NoError) { @@ -115,8 +118,9 @@ VMManagerServerSocket::serverReceivedMessage() { } void -VMManagerServerSocket::serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList& arguments) const { - if(!socket) { +VMManagerServerSocket::serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList &arguments) const +{ + if (!socket) { qInfo("Cannot send message: Invalid socket"); return; } @@ -124,7 +128,7 @@ VMManagerServerSocket::serverSendMessage(VMManagerProtocol::ManagerMessage proto // Regular connection QDataStream stream(socket); stream.setVersion(QDataStream::Qt_5_7); - auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Manager); + auto packet = new VMManagerProtocol(VMManagerProtocol::Sender::Manager); auto jsonMessage = packet->protocolManagerMessage(protocol_message); stream << QJsonDocument(jsonMessage).toJson(QJsonDocument::Compact); } @@ -145,7 +149,7 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json) qDebug() << json; return; } -// qDebug().noquote() << Q_FUNC_INFO << json; + // qDebug().noquote() << Q_FUNC_INFO << json; QJsonObject params_object; auto message_type = VMManagerProtocol::getClientMessageType(json); @@ -155,7 +159,7 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json) params_object = VMManagerProtocol::getParams(json); if (!params_object.isEmpty()) { // valid object - if(params_object.value("params").type() == QJsonValue::Double) { + if (params_object.value("params").type() == QJsonValue::Double) { emit winIdReceived(params_object.value("params").toVariant().toULongLong()); } } @@ -176,7 +180,7 @@ VMManagerServerSocket::jsonReceived(const QJsonObject &json) params_object = VMManagerProtocol::getParams(json); if (!params_object.isEmpty()) { // valid object - if(params_object.value("status").type() == QJsonValue::Double) { + if (params_object.value("status").type() == QJsonValue::Double) { // has status key, value is an int (qt assigns it as Double) emit runningStatusChanged(static_cast(params_object.value("status").toInt())); } diff --git a/src/qt/qt_vmmanager_serversocket.hpp b/src/qt/qt_vmmanager_serversocket.hpp index 87baa102793..71d0a124e3d 100644 --- a/src/qt/qt_vmmanager_serversocket.hpp +++ b/src/qt/qt_vmmanager_serversocket.hpp @@ -24,17 +24,17 @@ // This macro helps give us the required `qHash()` function in order to use the // enum as a hash key -#define QHASH_FOR_CLASS_ENUM(T) \ -inline uint qHash(const T &t, uint seed) { \ - return ::qHash(static_cast::type>(t), seed); \ -} +#define QHASH_FOR_CLASS_ENUM(T) \ + inline uint qHash(const T &t, uint seed) \ + { \ + return ::qHash(static_cast::type>(t), seed); \ + } class VMManagerServerSocket : public QWidget { Q_OBJECT public: - enum class ServerType { Standard, Legacy, @@ -53,16 +53,16 @@ class VMManagerServerSocket : public QWidget { QLocalServer *server; QLocalSocket *socket; ServerType server_type; - bool serverIsRunning; + bool serverIsRunning; // Server functions - bool startServer(); - void serverConnectionReceived(); - void serverReceivedMessage(); - void serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList& arguments = QStringList()) const; + bool startServer(); + void serverConnectionReceived(); + void serverReceivedMessage(); + void serverSendMessage(VMManagerProtocol::ManagerMessage protocol_message, const QStringList &arguments = QStringList()) const; static void serverDisconnected(); - void jsonReceived(const QJsonObject &json); - QString getSocketPath() const; + void jsonReceived(const QJsonObject &json); + QString getSocketPath() const; static QString serverTypeToString(ServerType server_type_lookup); @@ -75,8 +75,6 @@ class VMManagerServerSocket : public QWidget { void configurationChanged(); void globalConfigurationChanged(); void winIdReceived(WId id); - - }; #endif // QT_VMMANAGER_SERVERSOCKET_H diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index d3dfa28661a..5038732d101 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -31,7 +31,7 @@ #include "qt_vmmanager_detailsection.hpp" #ifdef Q_OS_WINDOWS -#include +# include #endif extern "C" { @@ -43,8 +43,8 @@ extern "C" { #include <86box/plat.h> #include <86box/sound.h> #include -#include <86box/thread.h> // required for network.h -#include <86box/timer.h> // required for network.h and fdd.h +#include <86box/thread.h> // required for network.h +#include <86box/timer.h> // required for network.h and fdd.h #include <86box/cdrom.h> #include <86box/cdrom_interface.h> #include <86box/scsi.h> @@ -67,7 +67,8 @@ extern "C" { using namespace VMManager; -VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) { +VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) +{ // The 86Box configuration file config_file = QFileInfo(sysconfig_file); @@ -76,7 +77,7 @@ VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) { config_name = config_file.dir().dirName(); // The full path of the directory that contains the 86box configuration file config_dir = shortened_dir = config_file.dir().absolutePath(); - process_status = ProcessStatus::Stopped; + process_status = ProcessStatus::Stopped; // In the configuration file the UUID is used as a unique value uuid = util::generateUuid(sysconfig_file); // That unique value is used to map the information to each individual system. @@ -99,12 +100,12 @@ VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) { find86BoxBinary(); platform = QApplication::platformName(); - process = new QProcess(); + process = new QProcess(); connect(process, &QProcess::stateChanged, this, &VMManagerSystem::processStatusChanged); // Server type for this instance (Standard should always be used instead of Legacy) socket_server_type = VMManagerServerSocket::ServerType::Standard; - socket_server = new VMManagerServerSocket(config_file, socket_server_type); + socket_server = new VMManagerServerSocket(config_file, socket_server_type); // NOTE: When unique names or UUIDs are written to the individual VM config file, use that // here instead of the auto-generated unique_name @@ -112,15 +113,16 @@ VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) { saveSettings(); } -VMManagerSystem::~VMManagerSystem() { +VMManagerSystem::~VMManagerSystem() +{ delete socket_server; } QVector -VMManagerSystem::scanForConfigs(QWidget* parent, const QString &searchPath) +VMManagerSystem::scanForConfigs(QWidget *parent, const QString &searchPath) { QProgressDialog progDialog(parent); - unsigned int found = 0; + unsigned int found = 0; progDialog.setCancelButton(nullptr); progDialog.setWindowTitle(tr("Searching for VMs...")); progDialog.setMinimumDuration(0); @@ -134,17 +136,17 @@ VMManagerSystem::scanForConfigs(QWidget* parent, const QString &searchPath) scanTimer.start(); QVector system_configs; - const auto config_file_name = QString(CONFIG_FILE); - const QStringList filters = {config_file_name}; - QStringList matches; - QString search_directory; + const auto config_file_name = QString(CONFIG_FILE); + const QStringList filters = { config_file_name }; + QStringList matches; + QString search_directory; - search_directory = searchPath.isEmpty()? vmm_path : searchPath; + search_directory = searchPath.isEmpty() ? vmm_path : searchPath; - if(!QDir(search_directory).exists()) { - //qWarning() << "Path" << search_directory << "does not exist. Cannot continue"; + if (!QDir(search_directory).exists()) { + // qWarning() << "Path" << search_directory << "does not exist. Cannot continue"; QDir(search_directory).mkpath("."); - //return {}; + // return {}; } QDirIterator dir_iterator(search_directory, filters, QDir::Files, QDirIterator::Subdirectories); @@ -157,12 +159,12 @@ VMManagerSystem::scanForConfigs(QWidget* parent, const QString &searchPath) found++; progDialog.setLabelText(tr("Found %1").arg(QString::number(found))); QApplication::processEvents(); - QString filename = dir_iterator.next(); + QString filename = dir_iterator.next(); matches.append(filename); } const auto scanElapsed = timer.elapsed(); - qDebug().noquote().nospace() << "Found " << matches.size() << " configs in " << search_directory <<". Scan took " << scanElapsed << " ms"; + qDebug().noquote().nospace() << "Found " << matches.size() << " configs in " << search_directory << ". Scan took " << scanElapsed << " ms"; timer.restart(); // foreach (QFileInfo hit, matches) { @@ -197,14 +199,15 @@ VMManagerSystem::generateTemporaryFilename() } QFileInfoList -VMManagerSystem::getScreenshots() { +VMManagerSystem::getScreenshots() +{ // Don't bother unless the directory exists - if(!screenshot_directory.exists()) { + if (!screenshot_directory.exists()) { return {}; } - auto screen_scan_dir = QDir(screenshot_directory.path(), "Monitor_1*", QDir::SortFlag::LocaleAware | QDir::SortFlag::IgnoreCase, QDir::Files); + auto screen_scan_dir = QDir(screenshot_directory.path(), "Monitor_1*", QDir::SortFlag::LocaleAware | QDir::SortFlag::IgnoreCase, QDir::Files); auto screenshot_files = screen_scan_dir.entryInfoList(); return screenshot_files; } @@ -214,9 +217,9 @@ VMManagerSystem::loadSettings() { // First, load the information from the 86box.cfg QSettings settings(config_file.filePath(), QSettings::IniFormat); - if (settings.status() != QSettings::NoError) { + if (settings.status() != QSettings::NoError) qWarning() << "Error loading" << config_file.path() << " status:" << settings.status(); - } + // qInfo() << "Loaded "<< config_file.filePath() << "status:" << settings.status(); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) @@ -239,14 +242,14 @@ VMManagerSystem::loadSettings() // QSettings will interpret lines with commas as QStringList. // Check for it and join them back to a string. #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - if (settings.value(key_name).typeId() == QMetaType::QStringList) { + if (settings.value(key_name).typeId() == QMetaType::QStringList) #else - if (settings.value(key_name).type() == QVariant::StringList) { + if (settings.value(key_name).type() == QVariant::StringList) #endif setting_value = settings.value(key_name).toStringList().join(", "); - } else { + else setting_value = settings.value(key_name).toString(); - } + config_hash[group_name][key_name] = setting_value; } settings.endGroup(); @@ -255,49 +258,46 @@ VMManagerSystem::loadSettings() // Next, load the information from the vmm config for this system // Display name auto loadedDisplayName = config_settings->getStringValue("display_name"); - if (!loadedDisplayName.isEmpty()) { + if (!loadedDisplayName.isEmpty()) displayName = loadedDisplayName; - } else { + else displayName = config_name; - } + // Notes auto loadedNotes = config_settings->getStringValue("notes"); - if (!loadedNotes.isEmpty()) { + if (!loadedNotes.isEmpty()) notes = loadedNotes; - } + // Timestamp auto loadedTimestamp = config_settings->getStringValue("timestamp"); if (!loadedTimestamp.isEmpty()) { // Make sure it is valid - if (auto newTimestamp = QDateTime::fromString(loadedTimestamp, Qt::ISODate); newTimestamp.isValid()) { + if (auto newTimestamp = QDateTime::fromString(loadedTimestamp, Qt::ISODate); newTimestamp.isValid()) lastUsedTimestamp = newTimestamp; - } } // Icon auto loadedIcon = config_settings->getStringValue("icon"); - if (!loadedIcon.isEmpty()) { + if (!loadedIcon.isEmpty()) icon = loadedIcon; - } } void VMManagerSystem::saveSettings() { - if(!isValid()) { + if (!isValid()) return; - } + config_settings->setStringValue("system_name", config_name); config_settings->setStringValue("config_file", config_file.canonicalFilePath()); config_settings->setStringValue("config_dir", config_file.canonicalPath()); - if (displayName != config_name) { + if (displayName != config_name) config_settings->setStringValue("display_name", displayName); - } else { + else config_settings->remove("display_name"); - } config_settings->setStringValue("notes", notes); - if(lastUsedTimestamp.isValid()) { + if (lastUsedTimestamp.isValid()) config_settings->setStringValue("timestamp", lastUsedTimestamp.toString(Qt::ISODate)); - } + config_settings->setStringValue("icon", icon); generateSearchTerms(); } @@ -308,10 +308,9 @@ VMManagerSystem::generateSearchTerms() for (const auto &config_key : config_hash.keys()) { // searchTerms.append(config_hash[config_key].values()); // brute force temporarily don't add paths - for(const auto &value: config_hash[config_key].values()) { - if(!value.startsWith("/")) { + for (const auto &value : config_hash[config_key].values()) { + if (!value.startsWith("/")) searchTerms.append(value); - } } } searchTerms.append(display_table.values()); @@ -328,7 +327,8 @@ VMManagerSystem::updateTimestamp() } QString -VMManagerSystem::getAll(const QString& category) const { +VMManagerSystem::getAll(const QString &category) const +{ auto value = config_hash[category].keys().join(", "); return value; } @@ -343,11 +343,11 @@ void VMManagerSystem::setDisplayName(const QString &newDisplayName) { // If blank, reset to the default - if (newDisplayName.isEmpty()) { + if (newDisplayName.isEmpty()) displayName = config_name; - } else { + else displayName = newDisplayName; - } + saveSettings(); } void @@ -375,32 +375,36 @@ VMManagerSystem::processId() const } QHash -VMManagerSystem::getCategory(const QString &category) const { +VMManagerSystem::getCategory(const QString &category) const +{ return config_hash[category]; } void -VMManagerSystem::find86BoxBinary() { +VMManagerSystem::find86BoxBinary() +{ // We'll use our own self to launch the VMs main_binary = QFileInfo(QCoreApplication::applicationFilePath()); } bool -VMManagerSystem::has86BoxBinary() { +VMManagerSystem::has86BoxBinary() +{ return main_binary.exists(); } void -VMManagerSystem::launchMainProcess() { +VMManagerSystem::launchMainProcess() +{ - if(!has86BoxBinary()) { + if (!has86BoxBinary()) { qWarning("No binary found! returning"); return; } // start the server first to get the socket name if (!serverIsRunning) { - if(!startServer()) { + if (!startServer()) { // FIXME: Better error handling qInfo("Failed to start VM Manager server"); return; @@ -410,13 +414,13 @@ VMManagerSystem::launchMainProcess() { if (process->processId() != 0) { #ifdef Q_OS_WINDOWS if (this->id) { - SetForegroundWindow((HWND)this->id); + SetForegroundWindow((HWND) this->id); } #endif return; } setProcessEnvVars(); - QString program = main_binary.filePath(); + QString program = main_binary.filePath(); QStringList args; args << "--vmpath" << config_dir; args << "--vmname" << displayName; @@ -437,31 +441,33 @@ VMManagerSystem::launchMainProcess() { updateTimestamp(); connect(process, QOverload::of(&QProcess::finished), - [=](const int exitCode, const QProcess::ExitStatus exitStatus){ - if (exitCode != 0 || exitStatus != QProcess::NormalExit) { - qInfo().nospace().noquote() << "Abnormal program termination while launching main process: exit code " << exitCode << ", exit status " << exitStatus; - QMessageBox::critical(this, tr("Virtual machine crash"), - tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg(displayName, QString::number(exitCode))); - return; - } - }); + [=](const int exitCode, const QProcess::ExitStatus exitStatus) { + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qInfo().nospace().noquote() << "Abnormal program termination while launching main process: exit code " << exitCode << ", exit status " << exitStatus; + QMessageBox::critical(this, tr("Virtual machine crash"), + tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg(displayName, QString::number(exitCode))); + return; + } + }); } void -VMManagerSystem::startButtonPressed() { +VMManagerSystem::startButtonPressed() +{ launchMainProcess(); } void -VMManagerSystem::launchSettings() { - if(!has86BoxBinary()) { +VMManagerSystem::launchSettings() +{ + if (!has86BoxBinary()) { qWarning("No binary found! returning"); return; } // start the server first to get the socket name if (!serverIsRunning) { - if(!startServer()) { + if (!startServer()) { // FIXME: Better error handling qInfo("Failed to start VM Manager server"); return; @@ -472,7 +478,7 @@ VMManagerSystem::launchSettings() { if (process->processId() != 0) { #ifdef Q_OS_WINDOWS if (this->id) { - SetForegroundWindow((HWND)this->id); + SetForegroundWindow((HWND) this->id); } #endif socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ShowSettings); @@ -481,8 +487,8 @@ VMManagerSystem::launchSettings() { // Otherwise, launch the system with the settings parameter setProcessEnvVars(); - window_obscured = true; - QString program = main_binary.filePath(); + window_obscured = true; + QString program = main_binary.filePath(); QStringList open_command_args; QStringList args; args << "--vmpath" << config_dir << "--settings"; @@ -496,20 +502,21 @@ VMManagerSystem::launchSettings() { process->start(); connect(process, QOverload::of(&QProcess::finished), - [=](const int exitCode, const QProcess::ExitStatus exitStatus){ - if (exitCode != 0 || exitStatus != QProcess::NormalExit) { - qInfo().nospace().noquote() << "Abnormal program termination while launching settings: exit code " << exitCode << ", exit status " << exitStatus; - QMessageBox::critical(this, tr("Virtual machine crash"), - tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg(displayName, QString("%1 (0x%2)").arg(QString::number(exitCode), QString::number(exitCode, 16)))); - return; - } + [=](const int exitCode, const QProcess::ExitStatus exitStatus) { + if (exitCode != 0 || exitStatus != QProcess::NormalExit) { + qInfo().nospace().noquote() << "Abnormal program termination while launching settings: exit code " << exitCode << ", exit status " << exitStatus; + QMessageBox::critical(this, tr("Virtual machine crash"), + tr("The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2.").arg(displayName, QString("%1 (0x%2)").arg(QString::number(exitCode), QString::number(exitCode, 16)))); + return; + } - configurationChangeReceived(); - }); + configurationChangeReceived(); + }); } void -VMManagerSystem::setupPaths() { +VMManagerSystem::setupPaths() +{ // application_temp_directory.setPath(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); // standard_temp_directory.setPath(QStandardPaths::writableLocation(QStandardPaths::TempLocation)); // QString temp_subdir = QApplication::applicationName(); @@ -529,7 +536,8 @@ VMManagerSystem::setupPaths() { } void -VMManagerSystem::setupVars() { +VMManagerSystem::setupVars() +{ unique_name = QCryptographicHash::hash(config_file.path().toUtf8().constData(), QCryptographicHash::Algorithm::Sha256).toHex().right(9); // unique_name = "aaaaaa"; // Set up the display vars @@ -554,16 +562,16 @@ VMManagerSystem::setupVars() { // } // qDebug() << "Generated UUID:" << uuid; // qDebug() << "Config file UUID:" << config_uuid; - auto machine_name = QString(); - int i = 0; - int ram_granularity = 0; + auto machine_name = QString(); + int i = 0; + int ram_granularity = 0; // Machine for (int ci = 0; ci < machine_count(); ++ci) { if (machine_available(ci)) { - if (machines[ci].internal_name == machine_config["machine"]) { - machine_name = machines[ci].name; - ram_granularity = machines[ci].ram.step; - } + if (machines[ci].internal_name == machine_config["machine"]) { + machine_name = machines[ci].name; + ram_granularity = machines[ci].ram.step; + } } } display_table[VMManager::Display::Name::Machine] = machine_name; @@ -572,7 +580,7 @@ VMManagerSystem::setupVars() { QString cpu_name = "Unknown"; while (cpu_families[i].package != 0) { if (cpu_families[i].internal_name == machine_config["cpu_family"]) { - int j = 0; + int j = 0; cpu_name = QString("%1 %2").arg(cpu_families[i].manufacturer, cpu_families[i].name); while (cpu_families[i].cpus[j].cpu_type != 0) { if (cpu_families[i].cpus[j].rspeed == machine_config["cpu_speed"].toUInt()) { @@ -598,27 +606,27 @@ VMManagerSystem::setupVars() { } i++; } -// int speed_display = machine_config["cpu_speed"].toInt() / 1000000; -// cpu_name.append(QString::number(speed_display).prepend(" / ")); -// cpu_name.append(QCoreApplication::translate("", "MHz").prepend(' ')); + // int speed_display = machine_config["cpu_speed"].toInt() / 1000000; + // cpu_name.append(QString::number(speed_display).prepend(" / ")); + // cpu_name.append(QCoreApplication::translate("", "MHz").prepend(' ')); display_table[VMManager::Display::Name::CPU] = cpu_name; // Memory - int divisor = (ram_granularity < 1024) ? 1 : 1024; + int divisor = (ram_granularity < 1024) ? 1 : 1024; QString display_unit = (divisor == 1) ? "KB" : "MB"; - auto mem_display = QString::number(machine_config["mem_size"].toInt() / divisor); + auto mem_display = QString::number(machine_config["mem_size"].toInt() / divisor); mem_display.append(QCoreApplication::translate("", display_unit.toUtf8().constData()).prepend(' ')); display_table[VMManager::Display::Name::Memory] = mem_display; // Video card - int video_int = video_get_video_from_internal_name(video_config["gfxcard"].toUtf8().data()); - const device_t* video_dev = video_card_getdevice(video_int); + int video_int = video_get_video_from_internal_name(video_config["gfxcard"].toUtf8().data()); + const device_t *video_dev = video_card_getdevice(video_int); display_table[VMManager::Display::Name::Video] = DeviceConfig::DeviceName(video_dev, video_get_internal_name(video_int), 1); // Secondary video if (video_config.contains("gfxcard_2")) { - int video2_int = video_get_video_from_internal_name(video_config["gfxcard_2"].toUtf8().data()); - const device_t* video2_dev = video_card_getdevice(video2_int); + int video2_int = video_get_video_from_internal_name(video_config["gfxcard_2"].toUtf8().data()); + const device_t *video2_dev = video_card_getdevice(video2_int); display_table[VMManager::Display::Name::Video].append(DeviceConfig::DeviceName(video2_dev, video_get_internal_name(video2_int), 1).prepend(VMManagerDetailSection::sectionSeparator)); } @@ -636,7 +644,7 @@ VMManagerSystem::setupVars() { char temp[512]; device_get_name(&voodoo_device, 0, temp); auto voodoo_config = getCategory(QString(temp)); - int voodoo_type = voodoo_config["type"].toInt(); + int voodoo_type = voodoo_config["type"].toInt(); switch (voodoo_type) { case 0: default: @@ -658,57 +666,57 @@ VMManagerSystem::setupVars() { // Drives // First the number of disks QMap disks; - for(const auto& key: disk_config.keys()) { + for (const auto &key : disk_config.keys()) { // Assuming the format hdd_NN_* QStringList pieces = key.split('_'); - QString disk = QString("%1_%2").arg(pieces.at(0), pieces.at(1)); - if(!disk.isEmpty()) { + QString disk = QString("%1_%2").arg(pieces.at(0), pieces.at(1)); + if (!disk.isEmpty()) { disks[disk] = 1; } } // Next, the types QHash bus_types; - for (const auto& key: disks.keys()) { + for (const auto &key : disks.keys()) { auto disk_parameter_key = QString("%1_parameters").arg(key); - QStringList pieces = disk_config[disk_parameter_key].split(","); - QString bus_type = pieces.value(pieces.length() - 1).trimmed(); - bus_types[bus_type] = 1; + QStringList pieces = disk_config[disk_parameter_key].split(","); + QString bus_type = pieces.value(pieces.length() - 1).trimmed(); + bus_types[bus_type] = 1; } QString disks_display = tr("%n disk(s)", "", disks.count()); if (disks.count()) { disks_display.append(" / ").append(bus_types.keys().join(", ").toUpper()); } -// display_table[VMManager::Display::Name::Disks] = disks_display; + // display_table[VMManager::Display::Name::Disks] = disks_display; // Drives QString new_disk_display; - for (const auto& key: disks.keys()) { - auto disk_parameter_key = QString("%1_parameters").arg(key); + for (const auto &key : disks.keys()) { + auto disk_parameter_key = QString("%1_parameters").arg(key); // Converting a string to an int back to a string to remove the zero (e.g. 01 to 1) - auto disk_number = QString::number(key.split("_").last().toInt()); - QStringList pieces = disk_config[disk_parameter_key].split(","); - QString sectors = pieces.value(0).trimmed(); - QString heads = pieces.value(1).trimmed(); - QString cylinders = pieces.value(2).trimmed(); - QString bus_type = pieces.value(pieces.length() - 1).trimmed(); + auto disk_number = QString::number(key.split("_").last().toInt()); + QStringList pieces = disk_config[disk_parameter_key].split(","); + QString sectors = pieces.value(0).trimmed(); + QString heads = pieces.value(1).trimmed(); + QString cylinders = pieces.value(2).trimmed(); + QString bus_type = pieces.value(pieces.length() - 1).trimmed(); // Add separator for each subsequent value, skipping the first - if(!new_disk_display.isEmpty()) { + if (!new_disk_display.isEmpty()) { new_disk_display.append(QString("%1").arg(VMManagerDetailSection::sectionSeparator)); } - int diskSizeRaw = (cylinders.toInt() * heads.toInt() * sectors.toInt()) >> 11; + int diskSizeRaw = (cylinders.toInt() * heads.toInt() * sectors.toInt()) >> 11; QString diskSizeFinal; QString unit = tr("MiB"); - if(diskSizeRaw > 1000) { - unit = tr("GiB"); + if (diskSizeRaw > 1000) { + unit = tr("GiB"); diskSizeFinal = QString::number(diskSizeRaw * 1.0 / 1000, 'f', 1); } else { diskSizeFinal = QString::number(diskSizeRaw); } // Only prefix each disk when there are multiple disks - QString diskNumberDisplay = disks.count() > 1 ? tr("Disk %1: ").arg(disk_number) : ""; + QString diskNumberDisplay = disks.count() > 1 ? tr("Disk %1:").arg(disk_number).append(" ") : ""; new_disk_display.append(QString("%1%2 %3 (%4)").arg(diskNumberDisplay, diskSizeFinal, unit, bus_type.toUpper())); } - if(new_disk_display.isEmpty()) { + if (new_disk_display.isEmpty()) { new_disk_display = tr("No disks"); } display_table[VMManager::Display::Name::Disks] = new_disk_display; @@ -724,38 +732,37 @@ VMManagerSystem::setupVars() { static auto floppy_match = QRegularExpression("fdd_\\d\\d_type", QRegularExpression::CaseInsensitiveOption); static auto cdrom_match = QRegularExpression("cdrom_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: floppy_cdrom_config.keys()) { - if(key.contains(floppy_match)) { + for (const auto &key : floppy_cdrom_config.keys()) { + if (key.contains(floppy_match)) { // auto device_number = key.split("_").at(1); auto floppy_internal_name = QString(floppy_cdrom_config[key]); // Not interested in the nones - if(floppy_internal_name == "none") { + if (floppy_internal_name == "none") continue; - } + auto floppy_type = fdd_get_from_internal_name(floppy_internal_name.toUtf8().data()); - if(auto fddName = QString(fdd_getname(floppy_type)); !fddName.isEmpty()) { + if (auto fddName = QString(fdd_getname(floppy_type)); !fddName.isEmpty()) floppyDevices.append(fddName); - } } - if(key.contains(cdrom_match)) { - auto device_number = key.split("_").at(1); + if (key.contains(cdrom_match)) { + auto device_number = key.split("_").at(1); auto cdrom_parameters = QString(floppy_cdrom_config[key]); - auto cdrom_bus = cdrom_parameters.split(",").at(1).trimmed().toUpper(); + auto cdrom_bus = cdrom_parameters.split(",").at(1).trimmed().toUpper(); - auto cdrom_type_key = QString("cdrom_%1_type").arg(device_number); + auto cdrom_type_key = QString("cdrom_%1_type").arg(device_number); auto cdrom_internal_name = QString(floppy_cdrom_config[cdrom_type_key]); if (cdrom_internal_name.isEmpty()) cdrom_internal_name = "86cd"; auto cdrom_type = cdrom_get_from_internal_name(cdrom_internal_name.toUtf8().data()); auto cdrom_speed_key = QString("cdrom_%1_speed").arg(device_number); - auto cdrom_speed = QString(floppy_cdrom_config[cdrom_speed_key]); + auto cdrom_speed = QString(floppy_cdrom_config[cdrom_speed_key]); if (cdrom_speed.isEmpty()) cdrom_speed = "8"; if ((cdrom_bus != "NONE") && (cdrom_type != -1)) { cdrom_speed = QString("%1x ").arg(cdrom_speed); - cdrom_bus = QString(" (%1)").arg(cdrom_bus); + cdrom_bus = QString(" (%1)").arg(cdrom_bus); cdromDevices.append(QString("%1%2 %3 %4%5").arg(cdrom_speed, cdrom_drive_types[cdrom_type].vendor, cdrom_drive_types[cdrom_type].model, cdrom_drive_types[cdrom_type].revision, cdrom_bus)); } } @@ -770,29 +777,29 @@ VMManagerSystem::setupVars() { static auto rdisk_match = QRegularExpression("rdisk_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); static auto zip_match = QRegularExpression("zip_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); // Legacy ZIP drive entries static auto mo_match = QRegularExpression("mo_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: rdisk_mo_config.keys()) { - if(key.contains(rdisk_match) || key.contains(zip_match)) { - auto device_number = key.split("_").at(1); + for (const auto &key : rdisk_mo_config.keys()) { + if (key.contains(rdisk_match) || key.contains(zip_match)) { + auto device_number = key.split("_").at(1); auto rdisk_parameters = QString(rdisk_mo_config[key]); - auto rdisk_type = rdisk_parameters.split(",").at(0).toInt(); + auto rdisk_type = rdisk_parameters.split(",").at(0).toInt(); if (key.contains(zip_match)) rdisk_type++; - auto rdisk_bus = rdisk_parameters.split(",").at(1).trimmed().toUpper(); + auto rdisk_bus = rdisk_parameters.split(",").at(1).trimmed().toUpper(); - if((rdisk_type >= 0) && (rdisk_type < KNOWN_RDISK_DRIVE_TYPES)) { - if(!rdisk_bus.isEmpty()) + if ((rdisk_type >= 0) && (rdisk_type < KNOWN_RDISK_DRIVE_TYPES)) { + if (!rdisk_bus.isEmpty()) rdisk_bus = QString(" (%1)").arg(rdisk_bus); rdiskDevices.append(QString("%1 %2%3").arg(rdisk_drive_types[rdisk_type].vendor, rdisk_drive_types[rdisk_type].model, rdisk_bus)); } } - if(key.contains(mo_match)) { + if (key.contains(mo_match)) { auto device_number = key.split("_").at(1); auto mo_parameters = QString(rdisk_mo_config[key]); - auto mo_type = mo_parameters.split(",").at(0).toInt(); - auto mo_bus = mo_parameters.split(",").at(1).trimmed().toUpper(); + auto mo_type = mo_parameters.split(",").at(0).toInt(); + auto mo_bus = mo_parameters.split(",").at(1).trimmed().toUpper(); - if((mo_type >= 0) && (mo_type < KNOWN_MO_DRIVE_TYPES)) { - if(!mo_bus.isEmpty()) + if ((mo_type >= 0) && (mo_type < KNOWN_MO_DRIVE_TYPES)) { + if (!mo_bus.isEmpty()) mo_bus = QString(" (%1)").arg(mo_bus); moDevices.append(QString("%1 %2%3").arg(mo_drive_types[mo_type].vendor, mo_drive_types[mo_type].model, mo_bus)); } @@ -802,18 +809,17 @@ VMManagerSystem::setupVars() { display_table[VMManager::Display::Name::RDisk] = rdiskDevices.join(VMManagerDetailSection::sectionSeparator); display_table[VMManager::Display::Name::MO] = moDevices.join(VMManagerDetailSection::sectionSeparator); - // SCSI controllers QStringList scsiControllers; static auto scsi_match = QRegularExpression("scsicard_\\d", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: storage_config.keys()) { - if(key.contains(scsi_match)) { - auto device_number = key.split("_").at(1); + for (const auto &key : storage_config.keys()) { + if (key.contains(scsi_match)) { + auto device_number = key.split("_").at(1); auto scsi_internal_name = QString(storage_config[key]); - auto scsi_id = scsi_card_get_from_internal_name(scsi_internal_name.toUtf8().data()); - auto scsi_device = scsi_card_getdevice(scsi_id); - auto scsi_name = DeviceConfig::DeviceName(scsi_device, scsi_card_get_internal_name(scsi_id), 1); - if(!scsi_name.isEmpty()) { + auto scsi_id = scsi_card_get_from_internal_name(scsi_internal_name.toUtf8().data()); + auto scsi_device = scsi_card_getdevice(scsi_id); + auto scsi_name = DeviceConfig::DeviceName(scsi_device, scsi_card_get_internal_name(scsi_id), 1); + if (!scsi_name.isEmpty()) { scsiControllers.append(scsi_name); } } @@ -824,37 +830,35 @@ VMManagerSystem::setupVars() { QStringList storageControllers; static auto fdc_match = QRegularExpression("fdc(_\\d)?", QRegularExpression::CaseInsensitiveOption); // futureproofing static auto hdc_match = QRegularExpression("hdc(_\\d)?", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: storage_config.keys()) { - if(key.contains(fdc_match)) { + for (const auto &key : storage_config.keys()) { + if (key.contains(fdc_match)) { QString device_number; if (!key.contains('_')) device_number = "1"; else // futureproofing - device_number = key.split("_").at(1); + device_number = key.split("_").at(1); auto fdc_internal_name = QString(storage_config[key]); if (!fdc_internal_name.isEmpty() && (fdc_internal_name != "none") && (fdc_internal_name != "internal")) { - auto fdc_id = fdc_card_get_from_internal_name(fdc_internal_name.toUtf8().data()); + auto fdc_id = fdc_card_get_from_internal_name(fdc_internal_name.toUtf8().data()); auto fdc_device = fdc_card_getdevice(fdc_id); - auto fdc_name = DeviceConfig::DeviceName(fdc_device, fdc_card_get_internal_name(fdc_id), 1); - if(!fdc_name.isEmpty()) { + auto fdc_name = DeviceConfig::DeviceName(fdc_device, fdc_card_get_internal_name(fdc_id), 1); + if (!fdc_name.isEmpty()) storageControllers.append(fdc_name); - } } } - if(key.contains(hdc_match)) { + if (key.contains(hdc_match)) { QString device_number; if (!key.contains('_')) // legacy hdc entry device_number = "1"; else - device_number = key.split("_").at(1); + device_number = key.split("_").at(1); auto hdc_internal_name = QString(storage_config[key]); if (!hdc_internal_name.isEmpty() && (hdc_internal_name != "none") && (hdc_internal_name != "internal")) { - auto hdc_id = hdc_get_from_internal_name(hdc_internal_name.toUtf8().data()); + auto hdc_id = hdc_get_from_internal_name(hdc_internal_name.toUtf8().data()); auto hdc_device = hdc_get_device(hdc_id); - auto hdc_name = DeviceConfig::DeviceName(hdc_device, hdc_get_internal_name(hdc_id), 1); - if(!hdc_name.isEmpty()) { + auto hdc_name = DeviceConfig::DeviceName(hdc_device, hdc_get_internal_name(hdc_id), 1); + if (!hdc_name.isEmpty()) storageControllers.append(hdc_name); - } } } } @@ -863,7 +867,7 @@ VMManagerSystem::setupVars() { if (storage_config.contains("cdrom_interface")) { auto cdrom_intf_internal_name = storage_config["cdrom_interface"]; if (!cdrom_intf_internal_name.isEmpty() && (cdrom_intf_internal_name != "none") && (cdrom_intf_internal_name != "internal")) { - auto cdrom_intf_dev = cdrom_interface_get_from_internal_name(cdrom_intf_internal_name.toUtf8().data()); + auto cdrom_intf_dev = cdrom_interface_get_from_internal_name(cdrom_intf_internal_name.toUtf8().data()); auto cdrom_intf_dev_name = DeviceConfig::DeviceName(cdrom_interface_get_device(cdrom_intf_dev), cdrom_interface_get_internal_name(cdrom_intf_dev), 1); storageControllers.append(cdrom_intf_dev_name); } @@ -882,26 +886,25 @@ VMManagerSystem::setupVars() { // Audio QStringList sndCards; static auto sndcard_match = QRegularExpression("sndcard\\d?", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: audio_config.keys()) { - if(key.contains(sndcard_match)) { + for (const auto &key : audio_config.keys()) { + if (key.contains(sndcard_match)) { auto device_number = key.right(1); - if(device_number == "d") // card #1 has no number + if (device_number == "d") // card #1 has no number device_number = "1"; auto audio_internal_name = QString(audio_config[key]); - auto audio_id = sound_card_get_from_internal_name(audio_internal_name.toUtf8().data()); - auto audio_device = sound_card_getdevice(audio_id); - auto audio_name = DeviceConfig::DeviceName(audio_device, sound_card_get_internal_name(audio_id), 1); - if(!audio_name.isEmpty()) { + auto audio_id = sound_card_get_from_internal_name(audio_internal_name.toUtf8().data()); + auto audio_device = sound_card_getdevice(audio_id); + auto audio_name = DeviceConfig::DeviceName(audio_device, sound_card_get_internal_name(audio_id), 1); + if (!audio_name.isEmpty()) sndCards.append(audio_name); - } } } - if(audio_config.contains("mpu401_standalone")) { + if (audio_config.contains("mpu401_standalone")) { sndCards.append(tr("Standalone MPU-401")); } - if(sndCards.isEmpty()) { + if (sndCards.isEmpty()) sndCards.append(tr("None")); - } + display_table[VMManager::Display::Name::Audio] = sndCards.join(VMManagerDetailSection::sectionSeparator); // MIDI @@ -909,10 +912,9 @@ VMManagerSystem::setupVars() { if (audio_config.contains("midi_device")) { auto midi_out_device = QString(audio_config["midi_device"]); auto midi_device_int = midi_out_device_get_from_internal_name(midi_out_device.toUtf8().data()); - auto midi_out = midi_out_device_getdevice(midi_device_int); - if(auto midiDevName = QString(midi_out->name); !midiDevName.isEmpty()) { + auto midi_out = midi_out_device_getdevice(midi_device_int); + if (auto midiDevName = QString(midi_out->name); !midiDevName.isEmpty()) midiOutDev = midiDevName; - } } display_table[VMManager::Display::Name::MidiOut] = midiOutDev; @@ -923,15 +925,15 @@ VMManagerSystem::setupVars() { // Network QStringList nicList; static auto nic_match = QRegularExpression("net_\\d\\d_card", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: network_config.keys()) { - if(key.contains(nic_match)) { - auto device_number = key.split("_").at(1); + for (const auto &key : network_config.keys()) { + if (key.contains(nic_match)) { + auto device_number = key.split("_").at(1); auto nic_internal_name = QString(network_config[key]); - auto nic_id = network_card_get_from_internal_name(nic_internal_name.toUtf8().data()); - auto nic = network_card_getdevice(nic_id); - auto nic_name = DeviceConfig::DeviceName(nic, network_card_get_internal_name(nic_id), 1); - auto net_type_key = QString("net_%1_net_type").arg(device_number); - auto net_type = network_config[net_type_key]; + auto nic_id = network_card_get_from_internal_name(nic_internal_name.toUtf8().data()); + auto nic = network_card_getdevice(nic_id); + auto nic_name = DeviceConfig::DeviceName(nic, network_card_get_internal_name(nic_id), 1); + auto net_type_key = QString("net_%1_net_type").arg(device_number); + auto net_type = network_config[net_type_key]; if (!net_type.isEmpty()) { if (net_type == "slirp") net_type = "SLiRP"; @@ -944,57 +946,54 @@ VMManagerSystem::setupVars() { else net_type = net_type.toUpper(); nicList.append(nic_name + " (" + net_type + ")"); - } else { + } else nicList.append(nic_name); - } - } } - if(nicList.isEmpty()) { + if (nicList.isEmpty()) nicList.append(tr("None")); - } + display_table[VMManager::Display::Name::NIC] = nicList.join(VMManagerDetailSection::sectionSeparator); // Input (Keyboard) if (input_config.contains("keyboard_type")) { - auto keyboard_internal_name = input_config["keyboard_type"]; - auto keyboard_dev = keyboard_get_from_internal_name(keyboard_internal_name.toUtf8().data()); - auto keyboard_dev_name = DeviceConfig::DeviceName(keyboard_get_device(keyboard_dev), keyboard_get_internal_name(keyboard_dev), 0); + auto keyboard_internal_name = input_config["keyboard_type"]; + auto keyboard_dev = keyboard_get_from_internal_name(keyboard_internal_name.toUtf8().data()); + auto keyboard_dev_name = DeviceConfig::DeviceName(keyboard_get_device(keyboard_dev), keyboard_get_internal_name(keyboard_dev), 0); display_table[VMManager::Display::Name::Keyboard] = keyboard_dev_name; } // Input (Mouse) - auto mouse_internal_name = input_config["mouse_type"]; - auto mouse_dev = mouse_get_from_internal_name(mouse_internal_name.toUtf8().data()); - auto mouse_dev_name = DeviceConfig::DeviceName(mouse_get_device(mouse_dev), mouse_get_internal_name(mouse_dev), 0); + auto mouse_internal_name = input_config["mouse_type"]; + auto mouse_dev = mouse_get_from_internal_name(mouse_internal_name.toUtf8().data()); + auto mouse_dev_name = DeviceConfig::DeviceName(mouse_get_device(mouse_dev), mouse_get_internal_name(mouse_dev), 0); display_table[VMManager::Display::Name::Mouse] = mouse_dev_name; // Input (joystick) QString joystickDevice; - if(input_config.contains("joystick_type")) { + if (input_config.contains("joystick_type")) { auto joystick_internal = QString(input_config["joystick_type"]); - auto joystick_dev = joystick_get_from_internal_name(joystick_internal.toUtf8().data()); - if (auto joystickName = tr(joystick_get_name(joystick_dev)); !joystickName.isEmpty()) { + auto joystick_dev = joystick_get_from_internal_name(joystick_internal.toUtf8().data()); + if (auto joystickName = tr(joystick_get_name(joystick_dev)); !joystickName.isEmpty()) joystickDevice = joystickName; - } } display_table[VMManager::Display::Name::Joystick] = joystickDevice; // # Ports // Serial // By default serial 1 and 2 are enabled unless otherwise specified - static auto serial_match = QRegularExpression("serial\\d_enabled", QRegularExpression::CaseInsensitiveOption); - QList serial_enabled = {true, true, false, false, false, false, false, false}; + static auto serial_match = QRegularExpression("serial\\d_enabled", QRegularExpression::CaseInsensitiveOption); + QList serial_enabled = { true, true, false, false, false, false, false, false }; // Parallel // By default lpt 1 is enabled unless otherwise specified - static auto lpt_match = QRegularExpression("lpt\\d_enabled", QRegularExpression::CaseInsensitiveOption); - QList lpt_enabled = {true, false, false, false}; - for (const auto &key: ports_config.keys()) { + static auto lpt_match = QRegularExpression("lpt\\d_enabled", QRegularExpression::CaseInsensitiveOption); + QList lpt_enabled = { true, false, false, false }; + for (const auto &key : ports_config.keys()) { if (key.contains(serial_match)) { if (auto serial_dev = key.split("_").at(0); !serial_dev.isEmpty()) { auto serial_num = serial_dev.at(serial_dev.size() - 1); // qDebug() << "serial is set" << key << ":" << ports_config[key]; - if(serial_num.isDigit() && serial_num.digitValue() >= 1 && serial_num.digitValue() <= 4) { + if (serial_num.isDigit() && serial_num.digitValue() >= 1 && serial_num.digitValue() <= 4) { // Already verified that it is a digit with isDigit() serial_enabled[serial_num.digitValue() - 1] = ports_config[key].toInt() == 1; } @@ -1004,16 +1003,15 @@ VMManagerSystem::setupVars() { if (auto lpt_dev = key.split("_").at(0); !lpt_dev.isEmpty()) { auto lpt_num = lpt_dev.at(lpt_dev.size() - 1); // qDebug() << "lpt is set" << key << ":" << ports_config[key]; - if (lpt_num.isDigit() && lpt_num.digitValue() >= 1 && lpt_num.digitValue() <= 4) { + if (lpt_num.isDigit() && lpt_num.digitValue() >= 1 && lpt_num.digitValue() <= 4) lpt_enabled[lpt_num.digitValue() - 1] = ports_config[key].toInt() == 1; - } } } } // qDebug() << "ports final" << serial_enabled << lpt_enabled; QStringList serialFinal; QStringList lptFinal; - int portIndex = 0; + int portIndex = 0; while (true) { if (serial_enabled[portIndex]) serialFinal.append(QString("COM%1").arg(portIndex + 1)); @@ -1021,17 +1019,17 @@ VMManagerSystem::setupVars() { if (portIndex == SERIAL_MAX) break; } - portIndex = 0; + portIndex = 0; bool hasLptDevices = false; while (true) { if (lpt_enabled[portIndex]) { - auto lpt_device_key = QString("lpt%1_device").arg(portIndex + 1); + auto lpt_device_key = QString("lpt%1_device").arg(portIndex + 1); QString lpt_device_name = ""; if (ports_config.contains(lpt_device_key)) { auto lpt_internal_name = QString(ports_config[lpt_device_key]); - auto lpt_id = lpt_device_get_from_internal_name(lpt_internal_name.toUtf8().data()); - lpt_device_name = " (" + tr(lpt_device_get_name(lpt_id)) + ")"; - hasLptDevices = true; + auto lpt_id = lpt_device_get_from_internal_name(lpt_internal_name.toUtf8().data()); + lpt_device_name = " (" + tr(lpt_device_get_name(lpt_id)) + ")"; + hasLptDevices = true; } lptFinal.append(QString("LPT%1%2").arg(portIndex + 1).arg(lpt_device_name)); } @@ -1039,31 +1037,30 @@ VMManagerSystem::setupVars() { if (portIndex == PARALLEL_MAX) break; } - display_table[VMManager::Display::Name::Serial] = (serialFinal.empty() ? tr("None") : serialFinal.join(", ")); - display_table[VMManager::Display::Name::Parallel] = (lptFinal.empty() ? tr("None") : lptFinal.join((hasLptDevices ? VMManagerDetailSection::sectionSeparator : ", "))); + display_table[VMManager::Display::Name::Serial] = (serialFinal.empty() ? tr("None") : serialFinal.join(", ")); + display_table[VMManager::Display::Name::Parallel] = (lptFinal.empty() ? tr("None") : lptFinal.join((hasLptDevices ? VMManagerDetailSection::sectionSeparator : ", "))); // ISA RTC QString isartc_dev_name = ""; if (other_config.contains("isartc_type")) { auto isartc_internal_name = other_config["isartc_type"]; - auto isartc_dev = isartc_get_from_internal_name(isartc_internal_name.toUtf8().data()); - isartc_dev_name = DeviceConfig::DeviceName(isartc_get_device(isartc_dev), isartc_get_internal_name(isartc_dev), 0); + auto isartc_dev = isartc_get_from_internal_name(isartc_internal_name.toUtf8().data()); + isartc_dev_name = DeviceConfig::DeviceName(isartc_get_device(isartc_dev), isartc_get_internal_name(isartc_dev), 0); } display_table[VMManager::Display::Name::IsaRtc] = isartc_dev_name; // ISA RAM QStringList IsaMemCards; static auto isamem_match = QRegularExpression("isamem\\d_type", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: other_config.keys()) { - if(key.contains(isamem_match)) { - auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); + for (const auto &key : other_config.keys()) { + if (key.contains(isamem_match)) { + auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); auto isamem_internal_name = QString(other_config[key]); - auto isamem_id = isamem_get_from_internal_name(isamem_internal_name.toUtf8().data()); - auto isamem_device = isamem_get_device(isamem_id); - auto isamem_name = DeviceConfig::DeviceName(isamem_device, isamem_get_internal_name(isamem_id), 0); - if(!isamem_name.isEmpty()) { + auto isamem_id = isamem_get_from_internal_name(isamem_internal_name.toUtf8().data()); + auto isamem_device = isamem_get_device(isamem_id); + auto isamem_name = DeviceConfig::DeviceName(isamem_device, isamem_get_internal_name(isamem_id), 0); + if (!isamem_name.isEmpty()) IsaMemCards.append(isamem_name); - } } } display_table[VMManager::Display::Name::IsaMem] = IsaMemCards.join(VMManagerDetailSection::sectionSeparator); @@ -1071,23 +1068,23 @@ VMManagerSystem::setupVars() { // ISA ROM QStringList IsaRomCards; static auto isarom_match = QRegularExpression("isarom\\d_type", QRegularExpression::CaseInsensitiveOption); - for(const auto& key: other_config.keys()) { - if(key.contains(isarom_match)) { - auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); + for (const auto &key : other_config.keys()) { + if (key.contains(isarom_match)) { + auto device_number = QString("%1").arg(key.split("_").at(0).right(1).toInt() + 1); auto isarom_internal_name = QString(other_config[key]); - auto isarom_id = isarom_get_from_internal_name(isarom_internal_name.toUtf8().data()); - auto isarom_device = isarom_get_device(isarom_id); - auto isarom_name = DeviceConfig::DeviceName(isarom_device, isarom_get_internal_name(isarom_id), 0); - if(!isarom_name.isEmpty()) { + auto isarom_id = isarom_get_from_internal_name(isarom_internal_name.toUtf8().data()); + auto isarom_device = isarom_get_device(isarom_id); + auto isarom_name = DeviceConfig::DeviceName(isarom_device, isarom_get_internal_name(isarom_id), 0); + if (!isarom_name.isEmpty()) IsaRomCards.append(isarom_name); - } } } display_table[VMManager::Display::Name::IsaRom] = IsaRomCards.join(VMManagerDetailSection::sectionSeparator); } bool -VMManagerSystem::startServer() { +VMManagerSystem::startServer() +{ if (socket_server->startServer()) { serverIsRunning = true; connect(socket_server, &VMManagerServerSocket::dataReceived, this, &VMManagerSystem::dataReceived); @@ -1095,29 +1092,30 @@ VMManagerSystem::startServer() { connect(socket_server, &VMManagerServerSocket::runningStatusChanged, this, &VMManagerSystem::runningStatusChangeReceived); connect(socket_server, &VMManagerServerSocket::configurationChanged, this, &VMManagerSystem::configurationChangeReceived); connect(socket_server, &VMManagerServerSocket::globalConfigurationChanged, this, &VMManagerSystem::globalConfigurationChanged); - connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this] (WId id) { this->id = id; }); + connect(socket_server, &VMManagerServerSocket::winIdReceived, this, [this](WId id) { this->id = id; }); return true; - } else { + } else return false; - } } void -VMManagerSystem::setProcessEnvVars() { - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - QString env_var_name = (socket_server_type == VMManagerServerSocket::ServerType::Standard) ? "VMM_86BOX_SOCKET" : "86BOX_MANAGER_SOCKET"; +VMManagerSystem::setProcessEnvVars() +{ + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + QString env_var_name = (socket_server_type == VMManagerServerSocket::ServerType::Standard) ? "VMM_86BOX_SOCKET" : "86BOX_MANAGER_SOCKET"; env.insert(env_var_name, socket_server->getSocketPath()); process->setProcessEnvironment(env); } void -VMManagerSystem::restartButtonPressed() { +VMManagerSystem::restartButtonPressed() +{ socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::ResetVM); - } void -VMManagerSystem::pauseButtonPressed() { +VMManagerSystem::pauseButtonPressed() +{ socket_server->serverSendMessage(VMManagerProtocol::ManagerMessage::Pause); } void @@ -1167,11 +1165,10 @@ VMManagerSystem::processStatusChanged() { // set to running if the process is running and the state is stopped if (process->state() == QProcess::ProcessState::Running) { - if (process_status == VMManagerSystem::ProcessStatus::Stopped) { + if (process_status == VMManagerSystem::ProcessStatus::Stopped) process_status = VMManagerSystem::ProcessStatus::Running; - } } else if (process->state() == QProcess::ProcessState::NotRunning) { - process_status = VMManagerSystem::ProcessStatus::Stopped; + process_status = VMManagerSystem::ProcessStatus::Stopped; window_obscured = false; } emit itemDataChanged(); @@ -1185,21 +1182,21 @@ VMManagerSystem::statusRefresh() QString VMManagerSystem::processStatusToString(VMManagerSystem::ProcessStatus status) { -// QMetaEnum qme = QMetaEnum::fromType(); -// return qme.valueToKey(static_cast(status)); - switch (status) { - case VMManagerSystem::ProcessStatus::Stopped: - return tr("Powered Off"); - case VMManagerSystem::ProcessStatus::Running: - return tr("Running"); - case VMManagerSystem::ProcessStatus::Paused: - return tr("Paused"); - case VMManagerSystem::ProcessStatus::PausedWaiting: - case VMManagerSystem::ProcessStatus::RunningWaiting: - return QString("%1 (%2)").arg(tr("Paused"), tr("Waiting")); - default: - return tr("Unknown Status"); - } + // QMetaEnum qme = QMetaEnum::fromType(); + // return qme.valueToKey(static_cast(status)); + switch (status) { + case VMManagerSystem::ProcessStatus::Stopped: + return tr("Powered Off"); + case VMManagerSystem::ProcessStatus::Running: + return tr("Running"); + case VMManagerSystem::ProcessStatus::Paused: + return tr("Paused"); + case VMManagerSystem::ProcessStatus::PausedWaiting: + case VMManagerSystem::ProcessStatus::RunningWaiting: + return QString("%1 (%2)").arg(tr("Paused"), tr("Waiting")); + default: + return tr("Unknown Status"); + } } QString @@ -1217,20 +1214,20 @@ VMManagerSystem::getProcessStatus() const void VMManagerSystem::runningStatusChangeReceived(VMManagerProtocol::RunningState state) { - if(state == VMManagerProtocol::RunningState::Running) { - process_status = VMManagerSystem::ProcessStatus::Running; + if (state == VMManagerProtocol::RunningState::Running) { + process_status = VMManagerSystem::ProcessStatus::Running; window_obscured = false; windowStatusChanged(); - } else if(state == VMManagerProtocol::RunningState::Paused) { - process_status = VMManagerSystem::ProcessStatus::Paused; + } else if (state == VMManagerProtocol::RunningState::Paused) { + process_status = VMManagerSystem::ProcessStatus::Paused; window_obscured = false; windowStatusChanged(); - } else if(state == VMManagerProtocol::RunningState::RunningWaiting) { - process_status = VMManagerSystem::ProcessStatus::RunningWaiting; + } else if (state == VMManagerProtocol::RunningState::RunningWaiting) { + process_status = VMManagerSystem::ProcessStatus::RunningWaiting; window_obscured = true; windowStatusChanged(); - } else if(state == VMManagerProtocol::RunningState::PausedWaiting) { - process_status = VMManagerSystem::ProcessStatus::PausedWaiting; + } else if (state == VMManagerProtocol::RunningState::PausedWaiting) { + process_status = VMManagerSystem::ProcessStatus::PausedWaiting; window_obscured = true; windowStatusChanged(); } else { diff --git a/src/qt/qt_vmmanager_system.hpp b/src/qt/qt_vmmanager_system.hpp index af6b30016df..96c794df3f3 100644 --- a/src/qt/qt_vmmanager_system.hpp +++ b/src/qt/qt_vmmanager_system.hpp @@ -26,43 +26,44 @@ // This macro helps give us the required `qHash()` function in order to use the // enum as a hash key -#define QHASH_FOR_CLASS_ENUM(T) \ -inline uint qHash(const T &t, uint seed) { \ - return ::qHash(static_cast::type>(t), seed); \ -} +#define QHASH_FOR_CLASS_ENUM(T) \ + inline uint qHash(const T &t, uint seed) \ + { \ + return ::qHash(static_cast::type>(t), seed); \ + } namespace VMManager { Q_NAMESPACE namespace Display { -Q_NAMESPACE -enum class Name { - Machine, - CPU, - Memory, - Video, - Disks, - Floppy, - CD, - RDisk, - MO, - SCSIController, - StorageController, - MidiOut, - Joystick, - Serial, - Parallel, - Audio, - Voodoo, - NIC, - Keyboard, - Mouse, - IsaRtc, - IsaMem, - IsaRom, - Unknown -}; -Q_ENUM_NS(Name) -QHASH_FOR_CLASS_ENUM(Name) + Q_NAMESPACE + enum class Name { + Machine, + CPU, + Memory, + Video, + Disks, + Floppy, + CD, + RDisk, + MO, + SCSIController, + StorageController, + MidiOut, + Joystick, + Serial, + Parallel, + Audio, + Voodoo, + NIC, + Keyboard, + Mouse, + IsaRtc, + IsaMem, + IsaRom, + Unknown + }; + Q_ENUM_NS(Name) + QHASH_FOR_CLASS_ENUM(Name) } } @@ -70,10 +71,9 @@ class VMManagerSystem : public QWidget { Q_OBJECT typedef QHash display_table_t; - typedef QHash > config_hash_t; + typedef QHash> config_hash_t; public: - enum class ProcessStatus { Stopped, Running, @@ -87,12 +87,15 @@ class VMManagerSystem : public QWidget { explicit VMManagerSystem(const QString &sysconfig_file); // Default constructor will generate a temporary filename as the config file // but it will not be valid (isValid() will return false) - VMManagerSystem() : VMManagerSystem(generateTemporaryFilename()) {} + VMManagerSystem() + : VMManagerSystem(generateTemporaryFilename()) + { + } ~VMManagerSystem() override; - static QVector scanForConfigs(QWidget* parent = nullptr, const QString &searchPath = {}); - static QString generateTemporaryFilename(); + static QVector scanForConfigs(QWidget *parent = nullptr, const QString &searchPath = {}); + static QString generateTemporaryFilename(); QFileInfo config_file; QString config_name; @@ -106,15 +109,15 @@ class VMManagerSystem : public QWidget { config_hash_t config_hash; - [[nodiscard]] QString getAll(const QString& category) const; - [[nodiscard]] QHash getCategory(const QString& category) const; - [[nodiscard]] QHash > getConfigHash() const; + [[nodiscard]] QString getAll(const QString &category) const; + [[nodiscard]] QHash getCategory(const QString &category) const; + [[nodiscard]] QHash> getConfigHash() const; - void setDisplayName(const QString& newDisplayName); - void setNotes(const QString& newNotes); + void setDisplayName(const QString &newDisplayName); + void setNotes(const QString &newNotes); - [[nodiscard]] bool isValid() const; - [[nodiscard]] bool isProcessRunning() const; + [[nodiscard]] bool isValid() const; + [[nodiscard]] bool isProcessRunning() const; [[nodiscard]] qint64 processId() const; public slots: void launchMainProcess(); @@ -127,16 +130,17 @@ public slots: void cadButtonPressed(); void reloadConfig(); void sendGlobalConfigurationChanged(); + public: QDateTime timestamp(); - void setIcon(const QString &newIcon); + void setIcon(const QString &newIcon); QProcess *process = new QProcess(); bool window_obscured; bool config_signal_connected = false; - QString getDisplayValue(VMManager::Display::Name key); + QString getDisplayValue(VMManager::Display::Name key); QFileInfoList getScreenshots(); inline bool operator==(const VMManagerSystem &rhs) const @@ -145,9 +149,9 @@ public slots: } static QString - processStatusToString(VMManagerSystem::ProcessStatus status) ; - ProcessStatus process_status; - [[nodiscard]] QString getProcessStatusString() const; + processStatusToString(VMManagerSystem::ProcessStatus status); + ProcessStatus process_status; + [[nodiscard]] QString getProcessStatusString() const; [[nodiscard]] ProcessStatus getProcessStatus() const; signals: @@ -166,15 +170,15 @@ public slots: display_table_t display_table; QFileInfo main_binary; - QString platform; + QString platform; // QDir application_temp_directory; // QDir standard_temp_directory; // QDir app_data_directory; QDir screenshot_directory; - QString unique_name; - QDateTime lastUsedTimestamp; + QString unique_name; + QDateTime lastUsedTimestamp; VMManagerServerSocket *socket_server; VMManagerServerSocket::ServerType socket_server_type; @@ -201,4 +205,4 @@ public slots: void statusRefresh(); }; -#endif //QT_VMMANAGER_SYSTEM_H +#endif // QT_VMMANAGER_SYSTEM_H diff --git a/src/qt/qt_vmmanager_windarkmodefilter.cpp b/src/qt/qt_vmmanager_windarkmodefilter.cpp index 4cba78b50c7..ac1fb4fae23 100644 --- a/src/qt/qt_vmmanager_windarkmodefilter.cpp +++ b/src/qt/qt_vmmanager_windarkmodefilter.cpp @@ -25,7 +25,7 @@ #include #include #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +# define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #endif #include <86box/86box.h> @@ -68,7 +68,8 @@ WindowsDarkModeFilter::reselectDarkMode() } window->updateDarkMode(); - if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () { + if (NewDarkMode != OldDarkMode) + QTimer::singleShot(1000, [this]() { BOOL DarkMode = NewDarkMode; DwmSetWindowAttribute((HWND) window->winId(), DWMWA_USE_IMMERSIVE_DARK_MODE, @@ -90,11 +91,8 @@ WindowsDarkModeFilter::nativeEventFilter(const QByteArray &eventType, void *mess MSG *msg = static_cast(message); if ((msg != nullptr) && (msg->message == WM_SETTINGCHANGE)) { - if ((((void *) msg->lParam) != nullptr) && - (wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0) && - color_scheme == 0) { + if ((((void *) msg->lParam) != nullptr) && (wcscmp(L"ImmersiveColorSet", (wchar_t *) msg->lParam) == 0) && color_scheme == 0) reselectDarkMode(); - } } } diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index 2306661ec98..be588a8d2a0 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -502,16 +502,16 @@ VulkanRenderer2::initResources() VK_VERTEX_INPUT_RATE_VERTEX }; VkVertexInputAttributeDescription vertexAttrDesc[] = { - {// position + { // position 0, // location 0, // binding VK_FORMAT_R32G32B32_SFLOAT, - 0 }, + 0 }, { // texcoord 1, 0, VK_FORMAT_R32G32_SFLOAT, - 3 * sizeof(float)} + 3 * sizeof(float) } }; VkPipelineVertexInputStateCreateInfo vertexInputInfo; @@ -556,8 +556,8 @@ VulkanRenderer2::initResources() // Set up descriptor set and its layout. VkDescriptorPoolSize descPoolSizes[2] = { - {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount)}, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount)} + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount) }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount) } }; VkDescriptorPoolCreateInfo descPoolInfo; memset(&descPoolInfo, 0, sizeof(descPoolInfo)); @@ -572,16 +572,16 @@ VulkanRenderer2::initResources() } VkDescriptorSetLayoutBinding layoutBinding[2] = { - {0, // binding + { 0, // binding VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, // descriptorCount VK_SHADER_STAGE_VERTEX_BIT, - nullptr}, + nullptr }, { 1, // binding VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, // descriptorCount VK_SHADER_STAGE_FRAGMENT_BIT, - nullptr} + nullptr } }; VkDescriptorSetLayoutCreateInfo descLayoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -658,8 +658,8 @@ VulkanRenderer2::initResources() } // Shaders -#if 0 - #version 440 +# if 0 +# version 440 layout(location = 0) in vec4 position; layout(location = 1) in vec2 texcoord; @@ -677,10 +677,10 @@ VulkanRenderer2::initResources() v_texcoord = texcoord; gl_Position = ubuf.mvp * position; } -#endif /* 0 */ +# endif /* 0 */ VkShaderModule vertShaderModule = createShader(QStringLiteral(":/texture_vert.spv")); -#if 0 - #version 440 +# if 0 +# version 440 layout(location = 0) in vec2 v_texcoord; @@ -692,7 +692,7 @@ VulkanRenderer2::initResources() { fragColor = texture(tex, v_texcoord); } -#endif /* 0 */ +# endif /* 0 */ VkShaderModule fragShaderModule = createShader(QStringLiteral(":/texture_frag.spv")); // Graphics pipeline @@ -913,7 +913,7 @@ VulkanRenderer2::startNextFrame() ensureTexture(); VkClearColorValue clearColor = { - {0, 0, 0, 1} + { 0, 0, 0, 1 } }; VkClearDepthStencilValue clearDS = { 1, 0 }; VkClearValue clearValues[2]; @@ -970,11 +970,11 @@ VulkanRenderer2::startNextFrame() m_devFuncs->vkCmdBindVertexBuffers(cb, 0, 1, &m_buf, &vbOffset); VkViewport viewport; - viewport.x = destination.x(); - viewport.y = destination.y(); - viewport.width = destination.width(); - viewport.height = destination.height(); - + viewport.x = destination.x(); + viewport.y = destination.y(); + viewport.width = destination.width(); + viewport.height = destination.height(); + viewport.minDepth = 0; viewport.maxDepth = 1; m_devFuncs->vkCmdSetViewport(cb, 0, 1, &viewport); diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index 2c131e5d76c..6037e7c3826 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -32,13 +32,13 @@ ** ****************************************************************************/ #ifndef VULKANRENDERER_HPP -#define VULKANRENDERER_HPP +# define VULKANRENDERER_HPP -#include -#include +# include +# include -#if QT_CONFIG(vulkan) -# include "qt_vulkanwindowrenderer.hpp" +# if QT_CONFIG(vulkan) +# include "qt_vulkanwindowrenderer.hpp" class VulkanRenderer2 : public QVulkanWindowRenderer { public: @@ -92,6 +92,6 @@ class VulkanRenderer2 : public QVulkanWindowRenderer { QMatrix4x4 m_proj; }; -#endif // QT_CONFIG(vulkan) +# endif // QT_CONFIG(vulkan) #endif // VULKANRENDERER_HPP diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 005f39b1fb1..79dbc8f873e 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -820,7 +820,7 @@ class VulkanRendererEmu : public QVulkanWindowRenderer m_devFuncs->vkDeviceWaitIdle(m_window->device()); } }; -# endif /* 0*/ +# endif /* 0*/ VulkanWindowRenderer::VulkanWindowRenderer(QWidget *parent) : QVulkanWindow(NULL) diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 90d85e47472..d40f4cdd688 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -51,7 +51,7 @@ #include #include #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE -#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +# define DWMWA_USE_IMMERSIVE_DARK_MODE 20 #endif #include <86box/keyboard.h> @@ -63,7 +63,7 @@ #include #include -extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); +extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); #include #include @@ -74,15 +74,15 @@ extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); bool NewDarkMode = FALSE; -extern MainWindow* main_window; +extern MainWindow *main_window; struct { - HANDLE done_event = 0, ready_event = 0; - std::atomic_bool done{false}; + HANDLE done_event = 0, ready_event = 0; + std::atomic_bool done { false }; - size_t rawinput_offset = 0, rawinput_size = 0; - uint8_t* rawinput = nullptr; + size_t rawinput_offset = 0, rawinput_size = 0; + uint8_t *rawinput = nullptr; HANDLE thread = 0; } win_rawinput_data; @@ -91,11 +91,11 @@ static void win_poll_mouse(void) { // Yes, this is a thing in C++. - auto* data = &win_rawinput_data; - uint32_t size, i, count, total = 0; + auto *data = &win_rawinput_data; + uint32_t size, i, count, total = 0; RAWINPUT *input; - //static int64_t ms_time = plat_get_ticks(); - + // static int64_t ms_time = plat_get_ticks(); + if (data->rawinput_offset == 0) { BOOL isWow64; @@ -106,18 +106,18 @@ win_poll_mouse(void) } } - input = (RAWINPUT *)data->rawinput; + input = (RAWINPUT *) data->rawinput; for (;;) { - size = data->rawinput_size - (UINT)((BYTE *)input - data->rawinput); + size = data->rawinput_size - (UINT) ((BYTE *) input - data->rawinput); count = GetRawInputBuffer(input, &size, sizeof(RAWINPUTHEADER)); - if (count == 0 || count == (UINT)-1) { - if (!data->rawinput || (count == (UINT)-1 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { - const UINT RAWINPUT_BUFFER_SIZE_INCREMENT = 96; // 2 64-bit raw mouse packets - BYTE *rawinput = (BYTE *)realloc(data->rawinput, data->rawinput_size + RAWINPUT_BUFFER_SIZE_INCREMENT); + if (count == 0 || count == (UINT) -1) { + if (!data->rawinput || (count == (UINT) -1 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + const UINT RAWINPUT_BUFFER_SIZE_INCREMENT = 96; // 2 64-bit raw mouse packets + BYTE *rawinput = (BYTE *) realloc(data->rawinput, data->rawinput_size + RAWINPUT_BUFFER_SIZE_INCREMENT); if (!rawinput) { break; } - input = (RAWINPUT *)(rawinput + ((BYTE *)input - data->rawinput)); + input = (RAWINPUT *) (rawinput + ((BYTE *) input - data->rawinput)); data->rawinput = rawinput; data->rawinput_size += RAWINPUT_BUFFER_SIZE_INCREMENT; } else { @@ -134,21 +134,21 @@ win_poll_mouse(void) } if (total > 0) { - for (i = 0, input = (RAWINPUT *)data->rawinput; i < total; ++i, input = NEXTRAWINPUTBLOCK(input)) { + for (i = 0, input = (RAWINPUT *) data->rawinput; i < total; ++i, input = NEXTRAWINPUTBLOCK(input)) { if (input->header.dwType == RIM_TYPEMOUSE) { - RAWMOUSE *rawmouse = (RAWMOUSE *)((BYTE *)input + data->rawinput_offset); + RAWMOUSE *rawmouse = (RAWMOUSE *) ((BYTE *) input + data->rawinput_offset); if (mouse_capture) WindowsRawInputFilter::mouse_handle(rawmouse); } } } - //qDebug() << "Mouse delay: " << (plat_get_ticks() - ms_time); - //ms_time = plat_get_ticks(); + // qDebug() << "Mouse delay: " << (plat_get_ticks() - ms_time); + // ms_time = plat_get_ticks(); } static DWORD -win_rawinput_thread(void* param) +win_rawinput_thread(void *param) { RAWINPUTDEVICE rid = { .usUsagePage = 0x01, @@ -179,14 +179,14 @@ win_rawinput_thread(void* param) } // Clear the queue status so MsgWaitForMultipleObjects() will wait again - (void)GetQueueStatus(QS_RAWINPUT); + (void) GetQueueStatus(QS_RAWINPUT); win_poll_mouse(); } rid.dwFlags |= RIDEV_REMOVE; rid.hwndTarget = NULL; - + RegisterRawInputDevices(&rid, 1, sizeof(rid)); DestroyWindow(window); return 0; @@ -197,19 +197,17 @@ std::unique_ptr WindowsRawInputFilter::Register(MainWindow *window) { RAWINPUTDEVICE rid[1] = { - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = nullptr - } + { .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_NOHOTKEYS, + .hwndTarget = nullptr } }; if (!hook_enabled) { RegisterRawInputDevices(rid, 1, sizeof(rid[0])); } - win_rawinput_data.done_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + win_rawinput_data.done_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); win_rawinput_data.ready_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); if (!win_rawinput_data.done_event || !win_rawinput_data.ready_event) { @@ -250,13 +248,12 @@ WindowsRawInputFilter::~WindowsRawInputFilter() SetEvent(win_rawinput_data.done_event); if (win_rawinput_data.thread) WaitForSingleObject(win_rawinput_data.thread, INFINITE); - RAWINPUTDEVICE rid = - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - }; + RAWINPUTDEVICE rid = { + .usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL + }; if (!hook_enabled) RegisterRawInputDevices(&rid, 1, sizeof(rid)); @@ -267,25 +264,25 @@ WindowsRawInputFilter::~WindowsRawInputFilter() static void notify_drives(ULONG unitmask, int empty) { - if (unitmask & cdrom_assigned_letters) for (int i = 0; i < CDROM_NUM; i++) { - cdrom_t *dev = &(cdrom[i]); - - if ((dev->host_letter != 0xff) && - (unitmask & (1 << dev->host_letter))) { - if (empty) - cdrom_set_empty(dev); - else - cdrom_update_status(dev); + if (unitmask & cdrom_assigned_letters) + for (int i = 0; i < CDROM_NUM; i++) { + cdrom_t *dev = &(cdrom[i]); + + if ((dev->host_letter != 0xff) && (unitmask & (1 << dev->host_letter))) { + if (empty) + cdrom_set_empty(dev); + else + cdrom_update_status(dev); + } } - } } static void device_change(WPARAM wParam, LPARAM lParam) { - PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam; + PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR) lParam; - switch(wParam) { + switch (wParam) { case DBT_DEVICEARRIVAL: case DBT_DEVICEREMOVECOMPLETE: /* Check whether a CD or DVD was inserted into a drive. */ @@ -300,9 +297,9 @@ device_change(WPARAM wParam, LPARAM lParam) default: /* - Process other WM_DEVICECHANGE notifications for other + Process other WM_DEVICECHANGE notifications for other devices or reasons. - */ + */ break; } } @@ -363,25 +360,24 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); - if (msg != nullptr) switch(msg->message) { - case WM_INPUT: - if (window->isActiveWindow() && (menus_open == 0)) - handle_input((HRAWINPUT) msg->lParam); - else { - for (auto &w : window->renderers) { - if (w && w->isActiveWindow()) { - handle_input((HRAWINPUT) msg->lParam); - break; + if (msg != nullptr) + switch (msg->message) { + case WM_INPUT: + if (window->isActiveWindow() && (menus_open == 0)) + handle_input((HRAWINPUT) msg->lParam); + else { + for (auto &w : window->renderers) { + if (w && w->isActiveWindow()) { + handle_input((HRAWINPUT) msg->lParam); + break; + } } } - } - return true; - case WM_SETTINGCHANGE: - if ((((void *) msg->lParam) != nullptr) && - (wcscmp(L"ImmersiveColorSet", (wchar_t*)msg->lParam) == 0) && - color_scheme == 0) { + return true; + case WM_SETTINGCHANGE: + if ((((void *) msg->lParam) != nullptr) && (wcscmp(L"ImmersiveColorSet", (wchar_t *) msg->lParam) == 0) && color_scheme == 0) { - bool OldDarkMode = NewDarkMode; + bool OldDarkMode = NewDarkMode; #if 0 if (do_auto_pause && !dopause) { auto_paused = 1; @@ -389,48 +385,48 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess } #endif - if (!util::isWindowsLightTheme()) { - QFile f(":qdarkstyle/dark/darkstyle.qss"); - - if (!f.exists()) - printf("Unable to set stylesheet, file not found\n"); - else { - f.open(QFile::ReadOnly | QFile::Text); - QTextStream ts(&f); - qApp->setStyleSheet(ts.readAll()); + if (!util::isWindowsLightTheme()) { + QFile f(":qdarkstyle/dark/darkstyle.qss"); + + if (!f.exists()) + printf("Unable to set stylesheet, file not found\n"); + else { + f.open(QFile::ReadOnly | QFile::Text); + QTextStream ts(&f); + qApp->setStyleSheet(ts.readAll()); + } + QPalette palette(qApp->palette()); + palette.setColor(QPalette::Link, Qt::white); + palette.setColor(QPalette::LinkVisited, Qt::lightGray); + qApp->setPalette(palette); + NewDarkMode = TRUE; + } else { + qApp->setStyleSheet(""); + QPalette palette(qApp->palette()); + palette.setColor(QPalette::Link, Qt::blue); + palette.setColor(QPalette::LinkVisited, Qt::magenta); + qApp->setPalette(palette); + NewDarkMode = FALSE; } - QPalette palette(qApp->palette()); - palette.setColor(QPalette::Link, Qt::white); - palette.setColor(QPalette::LinkVisited, Qt::lightGray); - qApp->setPalette(palette); - NewDarkMode = TRUE; - } else { - qApp->setStyleSheet(""); - QPalette palette(qApp->palette()); - palette.setColor(QPalette::Link, Qt::blue); - palette.setColor(QPalette::LinkVisited, Qt::magenta); - qApp->setPalette(palette); - NewDarkMode = FALSE; - } - if (NewDarkMode != OldDarkMode) QTimer::singleShot(1000, [this] () { - BOOL DarkMode = NewDarkMode; - DwmSetWindowAttribute((HWND) window->winId(), - DWMWA_USE_IMMERSIVE_DARK_MODE, - (LPCVOID) &DarkMode, - sizeof(DarkMode)); + if (NewDarkMode != OldDarkMode) + QTimer::singleShot(1000, [this]() { + BOOL DarkMode = NewDarkMode; + DwmSetWindowAttribute((HWND) window->winId(), + DWMWA_USE_IMMERSIVE_DARK_MODE, + (LPCVOID) &DarkMode, + sizeof(DarkMode)); - window->resizeContents(monitors[0].mon_scrnsz_x, - monitors[0].mon_scrnsz_y); + window->resizeContents(monitors[0].mon_scrnsz_x, + monitors[0].mon_scrnsz_y); - for (int i = 1; i < MONITORS_NUM; i++) { - auto mon = &(monitors[i]); + for (int i = 1; i < MONITORS_NUM; i++) { + auto mon = &(monitors[i]); - if ((window->renderers[i] != nullptr) && - !window->renderers[i]->isHidden()) - window->resizeContentsMonitor(mon->mon_scrnsz_x, - mon->mon_scrnsz_y, i); - } + if ((window->renderers[i] != nullptr) && !window->renderers[i]->isHidden()) + window->resizeContentsMonitor(mon->mon_scrnsz_x, + mon->mon_scrnsz_y, i); + } #if 0 if (auto_paused) { @@ -438,19 +434,19 @@ WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *mess auto_paused = 0; } #endif - }); - } - break; - case WM_SYSKEYDOWN: - /* Stop processing of Alt-F4 */ - if (msg->wParam == 0x73) - return true; - break; - case WM_DEVICECHANGE: - if (msg->hwnd == (HWND) window->winId()) - device_change(msg->wParam, msg->lParam); - break; - } + }); + } + break; + case WM_SYSKEYDOWN: + /* Stop processing of Alt-F4 */ + if (msg->wParam == 0x73) + return true; + break; + case WM_DEVICECHANGE: + if (msg->hwnd == (HWND) window->winId()) + device_change(msg->wParam, msg->lParam); + break; + } } return false; @@ -491,7 +487,7 @@ WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) } void -WindowsRawInputFilter::mouse_handle(RAWMOUSE* raw) +WindowsRawInputFilter::mouse_handle(RAWMOUSE *raw) { RAWMOUSE state = *raw; static int x, delta_x; @@ -548,8 +544,8 @@ WindowsRawInputFilter::mouse_handle(RAWMOUSE* raw) */ delta_x = (state.lLastX - x) / 25; delta_y = (state.lLastY - y) / 25; - x = state.lLastX; - y = state.lLastY; + x = state.lLastX; + y = state.lLastY; } else { /* relative mouse, i.e. regular mouse */ delta_x = state.lLastX; diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index 28b061ac0c8..c70fadc3c81 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -57,20 +57,20 @@ class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter ~WindowsRawInputFilter(); - static void mouse_handle(RAWMOUSE* raw); + static void mouse_handle(RAWMOUSE *raw); private: MainWindow *window; - int buttons = 0; - int dx = 0; - int dy = 0; - int dwheel = 0; - int menus_open = 0; + int buttons = 0; + int dx = 0; + int dy = 0; + int dwheel = 0; + int menus_open = 0; WindowsRawInputFilter(MainWindow *window); - void handle_input(HRAWINPUT input); - void keyboard_handle(PRAWINPUT raw); + void handle_input(HRAWINPUT input); + void keyboard_handle(PRAWINPUT raw); }; #endif diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index b901e7338bb..5643df4d459 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -44,7 +44,7 @@ extern "C" { static Display *disp = nullptr; static QThread *procThread = nullptr; static XIEventMask ximask; -static std::atomic exitfromthread = false; +static std::atomic exitfromthread = false; static std::atomic xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; static int xi2opcode = 0; static double prev_coords[2] = { 0.0 }; @@ -56,8 +56,8 @@ parse_valuators(const double *input_values, const unsigned char *mask, int mask_len, double *output_values, int output_values_len) { - int i = 0; - int z = 0; + int i = 0; + int z = 0; int top = mask_len * 8; if (top > 16) top = 16; diff --git a/src/qt/xkbcommon_keyboard.cpp b/src/qt/xkbcommon_keyboard.cpp index f1a43621d42..6f358a9c3a1 100644 --- a/src/qt/xkbcommon_keyboard.cpp +++ b/src/qt/xkbcommon_keyboard.cpp @@ -24,175 +24,175 @@ extern "C" { #define IS_HEX_DIGIT(c) (IS_DEC_DIGIT(c) || (((c) >= 'A') && ((c) <= 'F')) || (((c) >= 'a') && ((c) <= 'f'))) static std::unordered_map xkb_keycodes = { - {"ESC", 0x01}, - {"AE01", 0x02}, - {"AE02", 0x03}, - {"AE03", 0x04}, - {"AE04", 0x05}, - {"AE05", 0x06}, - {"AE06", 0x07}, - {"AE07", 0x08}, - {"AE08", 0x09}, - {"AE09", 0x0a}, - {"AE10", 0x0b}, - {"AE11", 0x0c}, - {"AE12", 0x0d}, - {"BKSP", 0x0e}, - - {"TAB", 0x0f}, - {"AD01", 0x10}, - {"AD02", 0x11}, - {"AD03", 0x12}, - {"AD04", 0x13}, - {"AD05", 0x14}, - {"AD06", 0x15}, - {"AD07", 0x16}, - {"AD08", 0x17}, - {"AD09", 0x18}, - {"AD10", 0x19}, - {"AD11", 0x1a}, - {"AD12", 0x1b}, - {"RTRN", 0x1c}, - {"LNFD", 0x1c}, /* linefeed => Enter */ - - {"LCTL", 0x1d}, - {"CTRL", 0x1d}, - {"AC01", 0x1e}, - {"AC02", 0x1f}, - {"AC03", 0x20}, - {"AC04", 0x21}, - {"AC05", 0x22}, - {"AC06", 0x23}, - {"AC07", 0x24}, - {"AC08", 0x25}, - {"AC09", 0x26}, - {"AC10", 0x27}, - {"AC11", 0x28}, - - {"TLDE", 0x29}, - {"AE00", 0x29}, /* alias of TLDE on keycodes/xfree86 (i.e. X11 forwarding) */ - {"LFSH", 0x2a}, - {"BKSL", 0x2b}, - {"AC12", 0x2b}, - {"AB01", 0x2c}, - {"AB02", 0x2d}, - {"AB03", 0x2e}, - {"AB04", 0x2f}, - {"AB05", 0x30}, - {"AB06", 0x31}, - {"AB07", 0x32}, - {"AB08", 0x33}, - {"AB09", 0x34}, - {"AB10", 0x35}, - {"RTSH", 0x36}, - - {"KPMU", 0x37}, - {"LALT", 0x38}, - {"ALT", 0x38}, - {"SPCE", 0x39}, - {"CAPS", 0x3a}, - {"FK01", 0x3b}, - {"FK02", 0x3c}, - {"FK03", 0x3d}, - {"FK04", 0x3e}, - {"FK05", 0x3f}, - {"FK06", 0x40}, - {"FK07", 0x41}, - {"FK08", 0x42}, - {"FK09", 0x43}, - {"FK10", 0x44}, - - {"NMLK", 0x45}, - {"SCLK", 0x46}, - {"FK14", 0x46}, /* F14 => Scroll Lock (for Apple keyboards) */ - {"KP7", 0x47}, - {"KP8", 0x48}, - {"KP9", 0x49}, - {"KPSU", 0x4a}, - {"KP4", 0x4b}, - {"KP5", 0x4c}, - {"KP6", 0x4d}, - {"KPAD", 0x4e}, - {"KP1", 0x4f}, - {"KP2", 0x50}, - {"KP3", 0x51}, - {"KP0", 0x52}, - {"KPDL", 0x53}, - - {"LSGT", 0x56}, - {"FK11", 0x57}, - {"FK12", 0x58}, - {"FK16", 0x5d}, /* F16 => F13 */ - {"FK17", 0x5e}, /* F17 => F14 */ - {"FK18", 0x5f}, /* F18 => F15 */ + { "ESC", 0x01 }, + { "AE01", 0x02 }, + { "AE02", 0x03 }, + { "AE03", 0x04 }, + { "AE04", 0x05 }, + { "AE05", 0x06 }, + { "AE06", 0x07 }, + { "AE07", 0x08 }, + { "AE08", 0x09 }, + { "AE09", 0x0a }, + { "AE10", 0x0b }, + { "AE11", 0x0c }, + { "AE12", 0x0d }, + { "BKSP", 0x0e }, + + { "TAB", 0x0f }, + { "AD01", 0x10 }, + { "AD02", 0x11 }, + { "AD03", 0x12 }, + { "AD04", 0x13 }, + { "AD05", 0x14 }, + { "AD06", 0x15 }, + { "AD07", 0x16 }, + { "AD08", 0x17 }, + { "AD09", 0x18 }, + { "AD10", 0x19 }, + { "AD11", 0x1a }, + { "AD12", 0x1b }, + { "RTRN", 0x1c }, + { "LNFD", 0x1c }, /* linefeed => Enter */ + + { "LCTL", 0x1d }, + { "CTRL", 0x1d }, + { "AC01", 0x1e }, + { "AC02", 0x1f }, + { "AC03", 0x20 }, + { "AC04", 0x21 }, + { "AC05", 0x22 }, + { "AC06", 0x23 }, + { "AC07", 0x24 }, + { "AC08", 0x25 }, + { "AC09", 0x26 }, + { "AC10", 0x27 }, + { "AC11", 0x28 }, + + { "TLDE", 0x29 }, + { "AE00", 0x29 }, /* alias of TLDE on keycodes/xfree86 (i.e. X11 forwarding) */ + { "LFSH", 0x2a }, + { "BKSL", 0x2b }, + { "AC12", 0x2b }, + { "AB01", 0x2c }, + { "AB02", 0x2d }, + { "AB03", 0x2e }, + { "AB04", 0x2f }, + { "AB05", 0x30 }, + { "AB06", 0x31 }, + { "AB07", 0x32 }, + { "AB08", 0x33 }, + { "AB09", 0x34 }, + { "AB10", 0x35 }, + { "RTSH", 0x36 }, + + { "KPMU", 0x37 }, + { "LALT", 0x38 }, + { "ALT", 0x38 }, + { "SPCE", 0x39 }, + { "CAPS", 0x3a }, + { "FK01", 0x3b }, + { "FK02", 0x3c }, + { "FK03", 0x3d }, + { "FK04", 0x3e }, + { "FK05", 0x3f }, + { "FK06", 0x40 }, + { "FK07", 0x41 }, + { "FK08", 0x42 }, + { "FK09", 0x43 }, + { "FK10", 0x44 }, + + { "NMLK", 0x45 }, + { "SCLK", 0x46 }, + { "FK14", 0x46 }, /* F14 => Scroll Lock (for Apple keyboards) */ + { "KP7", 0x47 }, + { "KP8", 0x48 }, + { "KP9", 0x49 }, + { "KPSU", 0x4a }, + { "KP4", 0x4b }, + { "KP5", 0x4c }, + { "KP6", 0x4d }, + { "KPAD", 0x4e }, + { "KP1", 0x4f }, + { "KP2", 0x50 }, + { "KP3", 0x51 }, + { "KP0", 0x52 }, + { "KPDL", 0x53 }, + + { "LSGT", 0x56 }, + { "FK11", 0x57 }, + { "FK12", 0x58 }, + { "FK16", 0x5d }, /* F16 => F13 */ + { "FK17", 0x5e }, /* F17 => F14 */ + { "FK18", 0x5f }, /* F18 => F15 */ /* Japanese keys. */ - {"JPCM", 0x5c}, /* Num, */ - {"KPDC", 0x5c}, - {"HKTG", 0x70}, /* hiragana-katakana toggle */ - {"AB11", 0x73}, /* \_ and Brazilian /? */ - {"HZTG", 0x76}, /* hankaku-zenkaku toggle */ - {"HIRA", 0x77}, - {"KATA", 0x78}, - {"HENK", 0x79}, - {"KANA", 0x79}, /* kana => henkan (for Apple keyboards) */ - {"MUHE", 0x7b}, - {"EISU", 0x7b}, /* eisu => muhenkan (for Apple keyboards) */ - {"AE13", 0x7d}, /* \| */ - {"KPPT", 0x7e}, /* Brazilian Num. */ - {"I06", 0x7e}, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ + { "JPCM", 0x5c }, /* Num, */ + { "KPDC", 0x5c }, + { "HKTG", 0x70 }, /* hiragana-katakana toggle */ + { "AB11", 0x73 }, /* \_ and Brazilian /? */ + { "HZTG", 0x76 }, /* hankaku-zenkaku toggle */ + { "HIRA", 0x77 }, + { "KATA", 0x78 }, + { "HENK", 0x79 }, + { "KANA", 0x79 }, /* kana => henkan (for Apple keyboards) */ + { "MUHE", 0x7b }, + { "EISU", 0x7b }, /* eisu => muhenkan (for Apple keyboards) */ + { "AE13", 0x7d }, /* \| */ + { "KPPT", 0x7e }, /* Brazilian Num. */ + { "I06", 0x7e }, /* alias of KPPT on keycodes/xfree86 (i.e. X11 forwarding) */ /* Korean keys. */ - {"HJCV", 0xf1}, /* hancha toggle */ - {"HNGL", 0xf2}, /* latin toggle */ - - {"KPEN", 0x11c}, - {"RCTL", 0x11d}, - {"KPDV", 0x135}, - {"PRSC", 0x137}, - {"SYRQ", 0x137}, - {"FK13", 0x137}, /* F13 => SysRq (for Apple keyboards) */ - {"RALT", 0x138}, - {"ALGR", 0x138}, - {"LVL3", 0x138}, /* observed on TigerVNC with AltGr-enabled layout */ - {"PAUS", 0x145}, - {"FK15", 0x145}, /* F15 => Pause (for Apple keyboards) */ - {"BRK", 0x145}, - {"HOME", 0x147}, - {"UP", 0x148}, - {"PGUP", 0x149}, - {"LEFT", 0x14b}, - {"RGHT", 0x14d}, - {"END", 0x14f}, - {"DOWN", 0x150}, - {"PGDN", 0x151}, - {"INS", 0x152}, - {"DELE", 0x153}, - - {"LWIN", 0x15b}, - {"WIN", 0x15b}, - {"LMTA", 0x15b}, - {"META", 0x15b}, - {"RWIN", 0x15c}, - {"RMTA", 0x15c}, - {"MENU", 0x15d}, - {"COMP", 0x15d}, /* Compose as Menu */ + { "HJCV", 0xf1 }, /* hancha toggle */ + { "HNGL", 0xf2 }, /* latin toggle */ + + { "KPEN", 0x11c }, + { "RCTL", 0x11d }, + { "KPDV", 0x135 }, + { "PRSC", 0x137 }, + { "SYRQ", 0x137 }, + { "FK13", 0x137 }, /* F13 => SysRq (for Apple keyboards) */ + { "RALT", 0x138 }, + { "ALGR", 0x138 }, + { "LVL3", 0x138 }, /* observed on TigerVNC with AltGr-enabled layout */ + { "PAUS", 0x145 }, + { "FK15", 0x145 }, /* F15 => Pause (for Apple keyboards) */ + { "BRK", 0x145 }, + { "HOME", 0x147 }, + { "UP", 0x148 }, + { "PGUP", 0x149 }, + { "LEFT", 0x14b }, + { "RGHT", 0x14d }, + { "END", 0x14f }, + { "DOWN", 0x150 }, + { "PGDN", 0x151 }, + { "INS", 0x152 }, + { "DELE", 0x153 }, + + { "LWIN", 0x15b }, + { "WIN", 0x15b }, + { "LMTA", 0x15b }, + { "META", 0x15b }, + { "RWIN", 0x15c }, + { "RMTA", 0x15c }, + { "MENU", 0x15d }, + { "COMP", 0x15d }, /* Compose as Menu */ /* Multimedia keys. Same notes as evdev_keyboard apply here. */ - {"KPEQ", 0x59}, /* Num= */ - {"FRNT", 0x101}, /* # Logitech Task Select */ - {"UNDO", 0x108}, /* # */ - {"PAST", 0x10a}, /* # Paste */ - {"FIND", 0x112}, /* # Logitech */ - {"CUT", 0x117}, /* # */ - {"COPY", 0x118}, /* # */ - {"MUTE", 0x120}, - {"VOL-", 0x12e}, - {"VOL+", 0x130}, - {"HELP", 0x13b}, - {"OPEN", 0x13f}, - {"POWR", 0x15e}, - {"STOP", 0x168}, + { "KPEQ", 0x59 }, /* Num= */ + { "FRNT", 0x101 }, /* # Logitech Task Select */ + { "UNDO", 0x108 }, /* # */ + { "PAST", 0x10a }, /* # Paste */ + { "FIND", 0x112 }, /* # Logitech */ + { "CUT", 0x117 }, /* # */ + { "COPY", 0x118 }, /* # */ + { "MUTE", 0x120 }, + { "VOL-", 0x12e }, + { "VOL+", 0x130 }, + { "HELP", 0x13b }, + { "OPEN", 0x13f }, + { "POWR", 0x15e }, + { "STOP", 0x168 }, }; struct xkb_keymap *xkbcommon_keymap = nullptr; @@ -217,7 +217,7 @@ xkbcommon_translate(uint32_t keycode) /* If XKB doesn't know the key name for this keycode, assume an unnamed Ixxx key. This is useful for older XKB versions with an incomplete evdev keycode map. */ auto key_name_s = key_name ? std::string(key_name) : QString("I%1").arg(keycode).toStdString(); - auto ret = xkb_keycodes[key_name_s]; + auto ret = xkb_keycodes[key_name_s]; /* Observed with multimedia keys on Windows VcXsrv. */ if (!ret && (key_name_s.length() == 3) && (key_name_s[0] == 'I') && IS_HEX_DIGIT(key_name_s[1]) && IS_HEX_DIGIT(key_name_s[2])) diff --git a/src/qt/xkbcommon_keyboard.hpp b/src/qt/xkbcommon_keyboard.hpp index 221a7222828..9648eb2870b 100644 --- a/src/qt/xkbcommon_keyboard.hpp +++ b/src/qt/xkbcommon_keyboard.hpp @@ -13,6 +13,6 @@ * Copyright 2023 RichardG. */ extern void *xkbcommon_keymap; -void xkbcommon_init(struct xkb_keymap *keymap); -void xkbcommon_close(); -uint16_t xkbcommon_translate(uint32_t keycode); +void xkbcommon_init(struct xkb_keymap *keymap); +void xkbcommon_close(); +uint16_t xkbcommon_translate(uint32_t keycode); diff --git a/src/qt/xkbcommon_wl_keyboard.cpp b/src/qt/xkbcommon_wl_keyboard.cpp index 6158476e137..d5076a0b965 100644 --- a/src/qt/xkbcommon_wl_keyboard.cpp +++ b/src/qt/xkbcommon_wl_keyboard.cpp @@ -29,17 +29,17 @@ extern "C" { #include typedef struct { - struct wl_seat *wl_seat; + struct wl_seat *wl_seat; struct wl_keyboard *wl_kbd; - uint32_t version; + uint32_t version; struct xkb_keymap *keymap; struct wl_list link; } seat_t; -static bool wl_init_ok = false; -static struct wl_list seats; +static bool wl_init_ok = false; +static struct wl_list seats; static struct xkb_context *ctx; static void @@ -48,7 +48,8 @@ xkbcommon_wl_set_keymap() /* Grab keymap from the first seat with one. */ seat_t *seat; seat_t *tmp; - wl_list_for_each_safe(seat, tmp, &seats, link) { + wl_list_for_each_safe(seat, tmp, &seats, link) + { if (seat->keymap) { xkbcommon_init(seat->keymap); return; @@ -71,7 +72,7 @@ kbd_keymap(void *data, struct wl_keyboard *wl_kbd, uint32_t format, if (seat->keymap) { struct xkb_keymap *keymap = seat->keymap; - seat->keymap = NULL; + seat->keymap = NULL; xkbcommon_wl_set_keymap(); xkb_keymap_unref(keymap); } @@ -142,7 +143,7 @@ seat_capabilities(void *data, struct wl_seat *wl_seat, uint32_t caps) wl_keyboard_destroy(seat->wl_kbd); struct xkb_keymap *keymap = seat->keymap; - seat->keymap = NULL; + seat->keymap = NULL; xkbcommon_wl_set_keymap(); xkb_keymap_unref(keymap); @@ -181,7 +182,8 @@ display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t id) seat_t *seat; seat_t *tmp; - wl_list_for_each_safe(seat, tmp, &seats, link) { + wl_list_for_each_safe(seat, tmp, &seats, link) + { if (seat->wl_kbd) { if (seat->version >= WL_SEAT_RELEASE_SINCE_VERSION) wl_keyboard_release(seat->wl_kbd); diff --git a/src/qt/xkbcommon_x11_keyboard.cpp b/src/qt/xkbcommon_x11_keyboard.cpp index fc39ad8a2a2..471e50cf482 100644 --- a/src/qt/xkbcommon_x11_keyboard.cpp +++ b/src/qt/xkbcommon_x11_keyboard.cpp @@ -17,12 +17,12 @@ extern "C" { /* xkb.h has identifiers named "explicit", which is a C++ keyword now... */ #ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wkeyword-macro" +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wkeyword-macro" #endif #define explicit explicit_ #ifdef __clang__ -#pragma clang diagnostic pop +# pragma clang diagnostic pop #endif #include #undef explicit @@ -38,10 +38,10 @@ extern "C" { void xkbcommon_x11_init() { - xcb_connection_t *conn; + xcb_connection_t *conn; struct xkb_context *ctx; - int32_t core_kbd_device_id; - struct xkb_keymap *keymap; + int32_t core_kbd_device_id; + struct xkb_keymap *keymap; conn = (xcb_connection_t *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("connection"); if (!conn) { diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index f5b81e36943..ca5d237b95d 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -2494,7 +2494,6 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) dev->drv->seek_diff = dev->drv->seek_pos; cdrom_seek(dev->drv, 0, 0); dev->sector_pos = dev->drv->seek_pos; - dev->drv->cached_sector = -1; scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); break; @@ -3557,8 +3556,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) else cdrom_seek(dev->drv, pos, 0); - dev->sector_pos = dev->drv->seek_pos; - dev->drv->cached_sector = -1; + dev->sector_pos = dev->drv->seek_pos; scsi_cdrom_command_complete(dev); break; diff --git a/src/sio/sio_fdc37c93x.c b/src/sio/sio_fdc37c93x.c index 39946942472..42ab2c7a72b 100644 --- a/src/sio/sio_fdc37c93x.c +++ b/src/sio/sio_fdc37c93x.c @@ -1812,7 +1812,7 @@ fdc37c93x_reset(void *priv) memset(dev->gpio_pulldn, 0xff, 8); /* Acer V62X requires bit 0 to be clear to not be stuck in "clear password" mode. */ - if (machines[machine].init == machine_at_vectra54_init) { + if ((machines[machine].init == machine_at_vectra54_init) || (machines[machine].init == machine_at_vectra500mt_init)) { dev->gpio_pulldn[1] = 0x40; /* diff --git a/src/sio/sio_fdc37m60x.c b/src/sio/sio_fdc37m60x.c index e6470a6eadf..f3c2a0a7db1 100644 --- a/src/sio/sio_fdc37m60x.c +++ b/src/sio/sio_fdc37m60x.c @@ -685,7 +685,7 @@ fdc37m60x_init(const device_t *info) } const device_t fdc37m60x_device = { - .name = "SMC FDC37C93x Super I/O", + .name = "SMC FDC37M60x Super I/O", .internal_name = "fdc37m60x", .flags = 0, .local = 0, diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index f9e066b1f5a..7fdf6d2d6dd 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -38,6 +38,7 @@ typedef struct pc87306_t { uint8_t tries; + uint8_t cfg_lock; uint8_t regs[29]; uint8_t gpio[2]; uint16_t gpioba; @@ -155,6 +156,9 @@ lpt_handler(pc87306_t *dev) break; } + if (!(dev->regs[0x00] & 0x01)) + lpt_port = 0x000; + if (dev->regs[0x1b] & 0x10) lpt_irq = (dev->regs[0x1b] & 0x20) ? 7 : 5; @@ -187,18 +191,20 @@ serial_handler(pc87306_t *dev, int uart) uint8_t pnp_shift; uint8_t irq; - temp = (dev->regs[0x01] >> (2 << uart)) & 3; + serial_remove(dev->uart[uart]); fer_shift = 2 << uart; /* 2 for UART 1, 4 for UART 2 */ pnp_shift = 2 + (uart << 2); /* 2 for UART 1, 6 for UART 2 */ + temp = (dev->regs[0x01] >> fer_shift) & 3; + /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ fer_irq = ((dev->regs[1] >> fer_shift) & 1) ? 3 : 4; pnp1_irq = ((dev->regs[0x1c] >> pnp_shift) & 1) ? 4 : 3; irq = (dev->regs[0x1c] & 1) ? pnp1_irq : fer_irq; - switch (temp) { + if (dev->regs[0x00] & fer_shift) switch (temp) { case 0: serial_setup(dev->uart[uart], COM1_ADDR, irq); break; @@ -273,15 +279,14 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) return; } else { if (dev->tries) { - if ((dev->cur_reg == 0) && (val == 8)) - val = 0x4b; + if (dev->cfg_lock) + return; + valxor = val ^ dev->regs[dev->cur_reg]; dev->tries = 0; - if ((dev->cur_reg <= 28) && (dev->cur_reg != 8)) { - if (dev->cur_reg == 0) - val &= 0x5f; + if ((dev->cur_reg <= 0x1c) && (dev->cur_reg != 0x08)) dev->regs[dev->cur_reg] = val; - } else + else return; } else { dev->tries++; @@ -291,21 +296,12 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) switch (dev->cur_reg) { case 0x00: - if (valxor & 0x01) { - lpt_port_remove(dev->lpt); - if ((val & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } - if (valxor & 0x02) { - serial_remove(dev->uart[0x00]); - if ((val & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - } - if (valxor & 0x04) { - serial_remove(dev->uart[0x01]); - if ((val & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); - } + if (valxor & 0x01) + lpt_handler(dev); + if (valxor & 0x02) + serial_handler(dev, 0); + if (valxor & 0x04) + serial_handler(dev, 1); if (valxor & 0x28) { fdc_remove(dev->fdc); if ((val & 8) && !(dev->regs[0x02] & 1)) @@ -313,52 +309,24 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) } break; case 0x01: - if (valxor & 0x03) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } - if (valxor & 0xcc) { - serial_remove(dev->uart[0x00]); - if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - } - if (valxor & 0xf0) { - serial_remove(dev->uart[0x01]); - if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); - } + if (valxor & 0x03) + lpt_handler(dev); + if (valxor & 0xcc) + serial_handler(dev, 0); + if (valxor & 0xf0) + serial_handler(dev, 1); break; case 0x02: - if (valxor & 0x01) { - lpt_port_remove(dev->lpt); - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); - fdc_remove(dev->fdc); - - if (!(val & 1)) { - if (dev->regs[0x00] & 0x01) - lpt_handler(dev); - if (dev->regs[0x00] & 0x02) - serial_handler(dev, 0); - if (dev->regs[0x00] & 0x04) - serial_handler(dev, 1); - if (dev->regs[0x00] & 0x08) - fdc_set_base(dev->fdc, (dev->regs[0x00] & 0x20) ? FDC_SECONDARY_ADDR : FDC_PRIMARY_ADDR); - } - } - if (valxor & 0x88) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } + if (valxor & 0x01) + fdc_set_power_down(dev->fdc, val & 0x01); + if (valxor & 0x40) + dev->cfg_lock = val & 0x40; + if (valxor & 0x88) + lpt_handler(dev); break; case 0x04: - if (valxor & (0x05)) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) - lpt_handler(dev); - } + if (valxor & (0x05)) + lpt_handler(dev); if (valxor & 0x80) nvr_lock_set(0x00, 256, !!(val & 0x80), dev->nvr); break; @@ -389,37 +357,24 @@ pc87306_write(uint16_t port, uint8_t val, void *priv) pc87306_gpio_handler(dev); break; case 0x18: - if (valxor & (0x0e)) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 0x01) && !(dev->regs[0x02] & 0x01)) - lpt_handler(dev); - } + if (valxor & (0x0e)) + lpt_handler(dev); break; case 0x19: - if (valxor) { - lpt_port_remove(dev->lpt); - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); - } + if (valxor) + lpt_handler(dev); break; case 0x1b: if (valxor & 0x70) { - lpt_port_remove(dev->lpt); if (!(val & 0x40)) dev->regs[0x19] = 0xef; - if ((dev->regs[0x00] & 1) && !(dev->regs[0x02] & 1)) - lpt_handler(dev); + lpt_handler(dev); } break; case 0x1c: if (valxor) { - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); - - if ((dev->regs[0x00] & 2) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 0); - if ((dev->regs[0x00] & 4) && !(dev->regs[0x02] & 1)) - serial_handler(dev, 1); + serial_handler(dev, 0); + serial_handler(dev, 1); } break; @@ -437,18 +392,20 @@ pc87306_read(uint16_t port, void *priv) index = (port & 1) ? 0 : 1; - if (dev->tries == 0xff) { - ret = 0x88; - dev->tries = 0xfe; - } else if (dev->tries == 0xfe) { - ret = 0x00; - dev->tries = 0; - } else if (index) { - ret = dev->cur_reg & 0x1f; - dev->tries = 0; + if (index) { + if (dev->tries == 0xff) { + ret = 0x88; + dev->tries = 0xfe; + } else if (dev->tries == 0xfe) { + ret = 0x00; + dev->tries = 0; + } else { + ret = dev->cur_reg & 0x1f; + dev->tries = 0; + } } else { - if (dev->cur_reg == 8) - ret = 0x70; + if (dev->cur_reg == 0x08) + ret = 0x71; else if (dev->cur_reg < 28) ret = dev->regs[dev->cur_reg]; dev->tries = 0; @@ -462,30 +419,26 @@ pc87306_reset_common(void *priv) { pc87306_t *dev = (pc87306_t *) priv; - memset(dev->regs, 0, 29); - + memset(dev->regs, 0x00, 29); dev->tries = 0xff; - dev->regs[0x00] = 0x0B; + dev->regs[0x00] = 0x0b; dev->regs[0x01] = 0x01; dev->regs[0x03] = 0x01; - dev->regs[0x05] = 0x0D; - dev->regs[0x08] = 0x70; - dev->regs[0x09] = 0xC0; + dev->regs[0x05] = 0x0d; + dev->regs[0x08] = 0x71; + dev->regs[0x09] = 0xc0; dev->regs[0x0b] = 0x80; - dev->regs[0x0f] = 0x1E; + dev->regs[0x0f] = 0x1e; dev->regs[0x12] = 0x30; - dev->regs[0x19] = 0xEF; + dev->regs[0x19] = 0xef; /* 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" */ lpt_set_cnfga_readout(dev->lpt, 0x10); - lpt_port_remove(dev->lpt); lpt_handler(dev); - serial_remove(dev->uart[0x00]); - serial_remove(dev->uart[0x01]); serial_handler(dev, 0); serial_handler(dev, 1); fdc_reset(dev->fdc); @@ -495,6 +448,8 @@ pc87306_reset_common(void *priv) nvr_at_handler(1, 0x0070, dev->nvr); nvr_bank_set(0, 0, dev->nvr); nvr_wp_set(0, 0, dev->nvr); + + dev->cfg_lock = 0; } void diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index fd55ace65ce..ab290ef3d6b 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -1,987 +1,987 @@ -/* - * 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. - * - * Emulation of the NatSemi PC87307 Super I/O chip. - * - * Authors: Miran Grca, - * - * Copyright 2020-2025 Miran Grca. - */ -#include -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include <86box/io.h> -#include <86box/timer.h> -#include <86box/device.h> -#include <86box/lpt.h> -#include <86box/machine.h> -#include <86box/mem.h> -#include <86box/nvr.h> -#include <86box/pci.h> -#include <86box/rom.h> -#include <86box/serial.h> -#include <86box/fdd.h> -#include <86box/fdc.h> -#include <86box/keyboard.h> -#include <86box/sio.h> -#include <86box/random.h> -#include <86box/plat_fallthrough.h> -#include "cpu.h" - -typedef struct pc87307_t { - uint8_t id; - uint8_t baddr; - uint8_t pm_idx; - uint8_t regs[48]; - uint8_t ld_regs[256][256]; - uint8_t pcregs[16]; - uint8_t gpio[2][8]; - uint8_t pm[8]; - uint16_t superio_base; - uint16_t gpio_base; - uint16_t gpio_base2; - uint16_t pm_base; - int cur_reg; - void *kbc; - fdc_t *fdc; - serial_t *uart[2]; - lpt_t *lpt; -} pc87307_t; - -enum { - LD_KBD = 0, - LD_MOUSE, - LD_RTC, - LD_FDC, - LD_LPT, - LD_UART2, - LD_UART1, - LD_GPIO, - LD_PM -} pc87307_ld_t; - -#define LD_MIN LD_KBD -#define LD_MAX LD_PM - -static void fdc_handler(pc87307_t *dev); -static void lpt_handler(pc87307_t *dev); -static void serial_handler(pc87307_t *dev, int uart); -static void kbc_handler(pc87307_t *dev); -static void pc87307_write(uint16_t port, uint8_t val, void *priv); -static uint8_t pc87307_read(uint16_t port, void *priv); - -#ifdef ENABLE_PC87307_LOG -int pc87307_do_log = ENABLE_PC87307_LOG; - -static void -pc87307_log(const char *fmt, ...) -{ - va_list ap; - - if (pc87307_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -} -#else -# define pc87307_log(fmt, ...) -#endif - -static void -pc87307_gpio_write(uint16_t port, uint8_t val, void *priv) -{ - pc87307_t *dev = (pc87307_t *) priv; - uint8_t bank = !!(dev->regs[0x22] & 0x80); - - /* Bit 7 of SCNF2 = bank. */ - pc87307_log("[%04X:%08X] [W] (%04X) Bank %i = %02X\n", - CS, cpu_state.pc, port, bank, val); - - dev->gpio[bank][port & 0x0007] = val; - - if (bank == 0) { - machine_handle_gpio(1, ((dev->gpio[0][5] & dev->gpio[0][4]) << 8) | (dev->gpio[0][0] & dev->gpio[0][1])); - } -} - -uint8_t -pc87307_gpio_read(uint16_t port, void *priv) -{ - const pc87307_t *dev = (pc87307_t *) priv; - uint8_t pins = 0xff; - uint8_t bank = !!(dev->regs[0x22] & 0x80); - uint8_t ret = dev->gpio[bank][port & 0x0007]; - - switch (port & 0x0007) { - case 0x0000: - if (bank == 0) { - uint8_t mask = dev->gpio[0][1]; - pins = machine_handle_gpio(0, 0xFFFF) & 0xFF; - ret = (ret & mask) | (pins & ~mask); - } - break; - case 0x0004: - if (bank == 0) { - uint8_t mask = dev->gpio[0][5]; - pins = (machine_handle_gpio(0, 0xFFFF) >> 8) & 0xFF; - ret = (ret & mask) | (pins & ~mask); - } else - ret = 0xff; - break; - - default: - if (bank == 1) - ret = 0xff; - break; - } - - /* Bit 7 of SCNF2 = bank. */ - pc87307_log("[%04X:%08X] [R] (%04X) Bank %i = %02X\n", - CS, cpu_state.pc, port, bank, ret); - - return ret; -} - -static void -pc87307_gpio_remove(pc87307_t *dev) -{ - if (dev->gpio_base != 0xffff) { - io_removehandler(dev->gpio_base, 0x0008, - pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); - dev->gpio_base = 0xffff; - } - - if (dev->gpio_base2 != 0xffff) { - io_removehandler(dev->gpio_base2, 0x0008, - pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); - dev->gpio_base2 = 0xffff; - } -} - -static void -pc87307_gpio_init(pc87307_t *dev, int bank, uint16_t addr) -{ - uint16_t *bank_base = bank ? &(dev->gpio_base2) : &(dev->gpio_base); - - *bank_base = addr; - - io_sethandler(*bank_base, 0x0008, - pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); -} - -static void -pc87307_pm_write(uint16_t port, uint8_t val, void *priv) -{ - pc87307_t *dev = (pc87307_t *) priv; - - if (port & 1) - dev->pm[dev->pm_idx] = val; - else { - dev->pm_idx = val & 0x07; - - switch (dev->pm_idx) { - case 0x00: - fdc_handler(dev); - lpt_handler(dev); - serial_handler(dev, 1); - serial_handler(dev, 0); - break; - - default: - break; - } - } -} - -uint8_t -pc87307_pm_read(uint16_t port, void *priv) -{ - const pc87307_t *dev = (pc87307_t *) priv; - - if (port & 1) - return dev->pm[dev->pm_idx]; - else - return dev->pm_idx; -} - -static void -pc87307_pm_remove(pc87307_t *dev) -{ - if (dev->pm_base != 0xffff) { - io_removehandler(dev->pm_base, 0x0008, - pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); - dev->pm_base = 0xffff; - } -} - -static void -pc87307_pm_init(pc87307_t *dev, uint16_t addr) -{ - dev->pm_base = addr; - - io_sethandler(dev->pm_base, 0x0008, - pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); -} - -static void -kbc_handler(pc87307_t *dev) -{ - uint8_t active = (dev->ld_regs[LD_KBD][0x00] & 0x01) && - (dev->pm[0x00] & 0x01); - uint8_t active_2 = dev->ld_regs[LD_MOUSE][0x00] & 0x01; - uint8_t irq = (dev->ld_regs[LD_KBD][0x40] & 0x0f); - uint8_t irq_2 = (dev->ld_regs[LD_MOUSE][0x40] & 0x0f); - uint16_t addr = (dev->ld_regs[LD_KBD][0x30] << 8) | - dev->ld_regs[LD_KBD][0x31]; - uint16_t addr_2 = (dev->ld_regs[LD_KBD][0x32] << 8) | - dev->ld_regs[LD_KBD][0x33]; - - pc87307_log("%02X, %02X, %02X, %02X, %04X, %04X\n", - active, active_2, irq, irq_2, addr, addr_2); - - if (addr <= 0xfff8) { - pc87307_log("Enabling KBC #1 on %04X...\n", addr); - kbc_at_port_handler(0, active, addr, dev->kbc); - } - - if (addr_2 <= 0xfff8) { - pc87307_log("Enabling KBC #2 on %04X...\n", addr_2); - kbc_at_port_handler(1, active, addr_2, dev->kbc); - } - - kbc_at_set_irq(0, active ? irq : 0xffff, dev->kbc); - kbc_at_set_irq(1, (active && active_2) ? irq_2 : 0xffff, dev->kbc); -} - -static void -fdc_handler(pc87307_t *dev) -{ - fdc_remove(dev->fdc); - - uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && - (dev->pm[0x00] & 0x08); - uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); - uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f); - uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | - dev->ld_regs[LD_FDC][0x31]) & 0xfff8; - - if (active && (addr <= 0xfff8)) { - pc87307_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); - fdc_set_base(dev->fdc, addr); - fdc_set_irq(dev->fdc, irq); - fdc_set_dma_ch(dev->fdc, dma); - } -} - -static void -lpt_handler(pc87307_t *dev) -{ - uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && - (dev->pm[0x00] & 0x10); - uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); - uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f); - uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | - dev->ld_regs[LD_LPT][0x31]; - uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7); - uint16_t mask = 0xfffc; - - if (irq > 15) - irq = 0xff; - - if (dma >= 4) - dma = 0xff; - - lpt_port_remove(dev->lpt); - - switch (mode) { - default: - case 0x00: - lpt_set_epp(dev->lpt, 0); - lpt_set_ecp(dev->lpt, 0); - lpt_set_ext(dev->lpt, 0); - break; - case 0x01: - lpt_set_epp(dev->lpt, 0); - lpt_set_ecp(dev->lpt, 0); - lpt_set_ext(dev->lpt, 1); - break; - case 0x02: case 0x03: - mask = 0xfff8; - lpt_set_epp(dev->lpt, 1); - lpt_set_ecp(dev->lpt, 0); - lpt_set_ext(dev->lpt, 0); - break; - case 0x04: - lpt_set_epp(dev->lpt, 0); - lpt_set_ecp(dev->lpt, 1); - lpt_set_ext(dev->lpt, 0); - break; - case 0x07: - mask = 0xfff8; - lpt_set_epp(dev->lpt, 1); - lpt_set_ecp(dev->lpt, 1); - lpt_set_ext(dev->lpt, 0); - break; - } - - lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10)); - - if (active && (addr <= (0xfffc & mask))) { - pc87307_log("Enabling LPT1 on %04X...\n", addr); - lpt_port_setup(dev->lpt, addr & mask); - } else - lpt_port_setup(dev->lpt, 0xffff); - - lpt_port_irq(dev->lpt, irq); - lpt_port_dma(dev->lpt, dma); -} - -static void -serial_handler(pc87307_t *dev, int uart) -{ - serial_remove(dev->uart[uart]); - - uint8_t active = (dev->ld_regs[LD_UART1 - uart][0x00] & 0x01) && - (dev->pm[0x00] & (1 << (6 - uart))); - uint8_t irq = (dev->ld_regs[LD_UART1 - uart][0x40] & 0x0f); - uint16_t addr = (dev->ld_regs[LD_UART1 - uart][0x30] << 8) | - dev->ld_regs[LD_UART1 - uart][0x31]; - - if (active && (addr <= 0xfff8)) { - pc87307_log("Enabling COM%i on %04X...\n", uart + 1, addr); - serial_setup(dev->uart[uart], addr, irq); - } else - serial_setup(dev->uart[uart], 0x0000, irq); -} - -static void -gpio_handler(pc87307_t *dev) -{ - pc87307_gpio_remove(dev); - - uint8_t active = (dev->ld_regs[LD_GPIO][0x00] & 0x01); - uint16_t addr = (dev->ld_regs[LD_GPIO][0x30] << 8) | - dev->ld_regs[LD_GPIO][0x31]; - uint16_t addr_2 = (dev->ld_regs[LD_GPIO][0x32] << 8) | - dev->ld_regs[LD_GPIO][0x33]; - - if (active) { - pc87307_log("Enabling GPIO #1 on %04X...\n", addr); - pc87307_gpio_init(dev, 0, addr); - pc87307_log("Enabling GPIO #2 on %04X...\n", addr_2); - pc87307_gpio_init(dev, 1, addr_2); - } -} - -static void -pm_handler(pc87307_t *dev) -{ - pc87307_pm_remove(dev); - - uint8_t active = (dev->ld_regs[LD_PM][0x00] & 0x01); - uint16_t addr = (dev->ld_regs[LD_PM][0x30] << 8) | - dev->ld_regs[LD_PM][0x31]; - - if (active) { - pc87307_log("Enabling power management on %04X...\n", addr); - pc87307_pm_init(dev, addr); - } -} - -static void -superio_handler(pc87307_t *dev) -{ - if (dev->superio_base != 0x0000) - io_removehandler(dev->superio_base, 0x0002, - pc87307_read, NULL, NULL, - pc87307_write, NULL, NULL, dev); - - switch (dev->regs[0x22] & 0x03) { - default: - dev->superio_base = 0x0000; - break; case 0x02: - dev->superio_base = 0x015c; - break; - case 0x03: - dev->superio_base = 0x002e; - break; - } - - if (dev->superio_base != 0x0000) { - pc87307_log("Enabling Super I/O on %04X...\n", dev->superio_base); - io_sethandler(dev->superio_base, 0x0002, - pc87307_read, NULL, NULL, - pc87307_write, NULL, NULL, dev); - } -} - -static void -pc87307_write(uint16_t port, uint8_t val, void *priv) -{ - pc87307_t *dev = (pc87307_t *) priv; - uint8_t ld = dev->regs[0x07]; - uint8_t reg = dev->cur_reg - 0x30; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t old = dev->regs[dev->cur_reg]; - - if (index) { - dev->cur_reg = val; - return; - } else { -#ifdef ENABLE_PC87307_LOG - if (dev->cur_reg >= 0x30) - pc87307_log("[%04X:%08X] [W] (%04X) %02X:%02X = %02X\n", - CS, cpu_state.pc, port, ld, dev->cur_reg, val); - else - pc87307_log("[%04X:%08X] [W] (%04X) %02X = %02X\n", - CS, cpu_state.pc, port, dev->cur_reg, val); -#endif - switch (dev->cur_reg) { - case 0x00: - case 0x02: case 0x03: - case 0x06: case 0x07: - dev->regs[dev->cur_reg] = val; - break; - case 0x21: - dev->regs[dev->cur_reg] = val; - fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, !(val & 0x04)); - break; - case 0x22: - dev->regs[dev->cur_reg] = val; - superio_handler(dev); - break; - case 0x23: - dev->regs[dev->cur_reg] = (old & 0xf0) | (val & 0x0f); - break; - case 0x24: - dev->pcregs[dev->regs[0x23]] = val; - break; - default: - if (dev->cur_reg >= 0x30) - old = dev->ld_regs[ld][reg]; - break; - } - } - - switch (dev->cur_reg) { - case 0x30: - switch (ld) { - default: - break; - case LD_KBD: case LD_MOUSE: - dev->ld_regs[ld][reg] = val; - kbc_handler(dev); - break; - case LD_RTC: - dev->ld_regs[ld][reg] = val; - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - fdc_handler(dev); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = val; - lpt_handler(dev); - break; - case LD_UART2: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 1); - break; - case LD_UART1: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 0); - break; - case LD_GPIO: - dev->ld_regs[ld][reg] = val; - gpio_handler(dev); - break; - case LD_PM: - dev->ld_regs[ld][reg] = val; - pm_handler(dev); - break; - } - break; - /* I/O Range Check. */ - case 0x31: - switch (ld) { - default: - break; - case LD_MIN ... LD_MAX: - if (ld != LD_MOUSE) - dev->ld_regs[ld][reg] = val; - break; - } - break; - /* Base Address 0 MSB. */ - case 0x60: - switch (ld) { - default: - break; - case LD_KBD: - dev->ld_regs[ld][reg] = val; - kbc_handler(dev); - break; - case LD_RTC: - dev->ld_regs[ld][reg] = val; - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - fdc_handler(dev); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); - lpt_handler(dev); - break; - case LD_UART2: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 1); - break; - case LD_UART1: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 0); - break; - case LD_GPIO: - dev->ld_regs[ld][reg] = val; - gpio_handler(dev); - break; - case LD_PM: - dev->ld_regs[ld][reg] = val; - pm_handler(dev); - break; - } - break; - /* Base Address 0 LSB. */ - case 0x61: - switch (ld) { - default: - break; - case LD_KBD: - dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); - kbc_handler(dev); - break; - case LD_RTC: - dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); - break; - case LD_FDC: - dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); - fdc_handler(dev); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = (old & 0x03) | (val & 0xfc); - lpt_handler(dev); - break; - case LD_UART2: - dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); - serial_handler(dev, 1); - break; - case LD_UART1: - dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); - serial_handler(dev, 0); - break; - case LD_GPIO: - dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); - gpio_handler(dev); - break; - case LD_PM: - dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); - pm_handler(dev); - break; - } - break; - /* Base Address 1 MSB (undocumented for Logical Device 7). */ - case 0x62: - switch (ld) { - default: - break; - case LD_KBD: - dev->ld_regs[ld][reg] = val; - kbc_handler(dev); - break; - case LD_GPIO: - dev->ld_regs[ld][reg] = val; - gpio_handler(dev); - break; - } - break; - /* Base Address 1 LSB (undocumented for Logical Device 7). */ - case 0x63: - switch (ld) { - default: - break; - case LD_KBD: - dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); - kbc_handler(dev); - break; - case LD_GPIO: - dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); - gpio_handler(dev); - break; - } - break; - /* Interrupt Select. */ - case 0x70: - switch (ld) { - default: - break; - case LD_KBD: case LD_MOUSE: - dev->ld_regs[ld][reg] = val; - kbc_handler(dev); - break; - case LD_RTC: - dev->ld_regs[ld][reg] = val; - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - fdc_handler(dev); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = val; - lpt_handler(dev); - break; - case LD_UART2: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 1); - break; - case LD_UART1: - dev->ld_regs[ld][reg] = val; - serial_handler(dev, 0); - break; - } - break; - /* Interrupt Type. */ - case 0x71: - switch (ld) { - default: - break; - case LD_MIN ... LD_MAX: - if ((ld == LD_KBD) || (ld == LD_MOUSE)) - dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); - else - dev->ld_regs[ld][reg] = (old & 0xfd) | (val & 0x02); - break; - } - break; - /* DMA Channel Select 0. */ - case 0x74: - switch (ld) { - default: - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - fdc_handler(dev); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = val; - lpt_handler(dev); - break; - case LD_UART2: - dev->ld_regs[ld][reg] = val; - break; - } - break; - /* DMA Channel Select 1. */ - case 0x75: - switch (ld) { - default: - break; - case LD_UART2: - dev->ld_regs[ld][reg] = val; - break; - } - break; - /* Configuration Register 0. */ - case 0xf0: - switch (ld) { - default: - break; - case LD_KBD: - dev->ld_regs[ld][reg] = val; - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); - fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); - break; - case LD_LPT: - dev->ld_regs[ld][reg] = val; - lpt_handler(dev); - break; - case LD_UART2: case LD_UART1: - dev->ld_regs[ld][reg] = val; - break; - } - break; - /* Configuration Register 1. */ - case 0xf1: - switch (ld) { - default: - break; - case LD_FDC: - dev->ld_regs[ld][reg] = val; - break; - } - break; - - default: - break; - } -} - -static uint8_t -pc87307_read(uint16_t port, void *priv) -{ - const pc87307_t *dev = (pc87307_t *) priv; - uint8_t ld = dev->regs[0x07]; - uint8_t reg = dev->cur_reg - 0x30; - uint8_t index = (port & 1) ? 0 : 1; - uint8_t ret = 0xff; - - if (index) - ret = dev->cur_reg; - else { - if (dev->cur_reg >= 0x30) - ret = dev->ld_regs[ld][reg]; - else if (dev->cur_reg == 0x24) - ret = dev->pcregs[dev->regs[0x23]]; - /* Write-only registers. */ - else if ((dev->cur_reg == 0x00) || - (dev->cur_reg == 0x02) || (dev->cur_reg == 0x03)) - ret = 0x00; - else - ret = dev->regs[dev->cur_reg]; -#ifdef EANBLE_PC87307_LOG - if (dev->cur_reg >= 0x30) - pc87307_log("[%04X:%08X] [R] (%04X) %02X:%02X = %02X\n", - CS, cpu_state.pc, port, ld, dev->cur_reg, ret); - else - pc87307_log("[%04X:%08X] [R] (%04X) %02X = %02X\n", - CS, cpu_state.pc, port, dev->cur_reg, ret); -#endif - } - - return ret; -} - -void -pc87307_reset(void *priv) -{ - pc87307_t *dev = (pc87307_t *) priv; - - memset(dev->regs, 0x00, 0x30); - for (uint16_t i = 0; i < 256; i++) - memset(dev->ld_regs[i], 0x00, 0xd0); - memset(dev->pcregs, 0x00, 0x10); - memset(dev->gpio, 0xff, 0x08); - memset(dev->pm, 0x00, 0x08); - - dev->regs[0x20] = dev->id; - dev->regs[0x21] = 0x04; - dev->regs[0x22] = dev->baddr; - - dev->ld_regs[LD_KBD ][0x00] = 0x01; - dev->ld_regs[LD_KBD ][0x31] = 0x60; - dev->ld_regs[LD_KBD ][0x33] = 0x64; - dev->ld_regs[LD_KBD ][0x40] = 0x01; - dev->ld_regs[LD_KBD ][0x41] = 0x02; - dev->ld_regs[LD_KBD ][0x44] = 0x04; - dev->ld_regs[LD_KBD ][0x45] = 0x04; - dev->ld_regs[LD_KBD ][0xc0] = 0x40; - - dev->ld_regs[LD_MOUSE][0x40] = 0x0c; - dev->ld_regs[LD_MOUSE][0x41] = 0x02; - dev->ld_regs[LD_MOUSE][0x44] = 0x04; - dev->ld_regs[LD_MOUSE][0x45] = 0x04; - - dev->ld_regs[LD_RTC ][0x00] = 0x01; - dev->ld_regs[LD_RTC ][0x31] = 0x70; - dev->ld_regs[LD_RTC ][0x40] = 0x08; - dev->ld_regs[LD_RTC ][0x44] = 0x04; - dev->ld_regs[LD_RTC ][0x45] = 0x04; - - dev->ld_regs[LD_FDC ][0x01] = 0x01; - dev->ld_regs[LD_FDC ][0x30] = 0x03; - dev->ld_regs[LD_FDC ][0x31] = 0xf0; - dev->ld_regs[LD_FDC ][0x32] = 0x03; - dev->ld_regs[LD_FDC ][0x33] = 0xf7; - dev->ld_regs[LD_FDC ][0x40] = 0x06; - dev->ld_regs[LD_FDC ][0x41] = 0x03; - dev->ld_regs[LD_FDC ][0x44] = 0x02; - dev->ld_regs[LD_FDC ][0x45] = 0x04; - dev->ld_regs[LD_FDC ][0xc0] = 0x02; - - dev->ld_regs[LD_LPT ][0x30] = 0x02; - dev->ld_regs[LD_LPT ][0x31] = 0x78; - dev->ld_regs[LD_LPT ][0x40] = 0x07; - dev->ld_regs[LD_LPT ][0x44] = 0x04; - dev->ld_regs[LD_LPT ][0x45] = 0x04; - dev->ld_regs[LD_LPT ][0xc0] = 0xf2; - - dev->ld_regs[LD_UART2][0x30] = 0x02; - dev->ld_regs[LD_UART2][0x31] = 0xf8; - dev->ld_regs[LD_UART2][0x40] = 0x03; - dev->ld_regs[LD_UART2][0x41] = 0x03; - dev->ld_regs[LD_UART2][0x44] = 0x04; - dev->ld_regs[LD_UART2][0x45] = 0x04; - dev->ld_regs[LD_UART2][0xc0] = 0x02; - - dev->ld_regs[LD_UART1][0x30] = 0x03; - dev->ld_regs[LD_UART1][0x31] = 0xf8; - dev->ld_regs[LD_UART1][0x40] = 0x04; - dev->ld_regs[LD_UART1][0x41] = 0x03; - dev->ld_regs[LD_UART1][0x44] = 0x04; - dev->ld_regs[LD_UART1][0x45] = 0x04; - dev->ld_regs[LD_UART1][0xc0] = 0x02; - - dev->ld_regs[LD_GPIO ][0x44] = 0x04; - dev->ld_regs[LD_GPIO ][0x45] = 0x04; - - dev->ld_regs[LD_PM ][0x44] = 0x04; - dev->ld_regs[LD_PM ][0x45] = 0x04; - - dev->gpio[0][0] = 0xff; - dev->gpio[0][1] = 0x00; - dev->gpio[0][2] = 0x00; - dev->gpio[0][3] = 0xff; - dev->gpio[0][4] = 0xff; - dev->gpio[0][5] = 0x00; - dev->gpio[0][6] = 0x00; - dev->gpio[0][7] = 0xff; - dev->gpio[1][1] = 0x00; - - dev->pm[0] = 0xff; - dev->pm[1] = 0xff; - dev->pm[4] = 0x0e; - dev->pm[7] = 0x01; - - dev->gpio_base = dev->pm_base = 0xffff; - - /* - 0 = 360 rpm @ 500 kbps for 3.5" - 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" - */ - fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, 0); - fdc_reset(dev->fdc); - - kbc_handler(dev); - fdc_handler(dev); - lpt_handler(dev); - serial_handler(dev, 0); - serial_handler(dev, 1); - gpio_handler(dev); - pm_handler(dev); - superio_handler(dev); -} - -static void -pc87307_close(void *priv) -{ - pc87307_t *dev = (pc87307_t *) priv; - - free(dev); -} - -static void * -pc87307_init(const device_t *info) -{ - pc87307_t *dev = (pc87307_t *) calloc(1, sizeof(pc87307_t)); - - dev->id = info->local & 0xff; - - dev->fdc = device_add(&fdc_at_nsc_device); - - dev->uart[0] = device_add_inst(&ns16550_device, 1); - dev->uart[1] = device_add_inst(&ns16550_device, 2); - - dev->lpt = device_add_inst(&lpt_port_device, 1); - lpt_set_cnfga_readout(dev->lpt, 0x14); - - switch (info->local & PCX730X_KBC) { - case PCX730X_AMI: - default: - dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_AMI | 0x00003500)); - break; - /* Optiplex! */ - case PCX730X_PHOENIX_42: - dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_PHOENIX | 0x00013700)); - break; - case PCX730X_PHOENIX_42I: - dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_PHOENIX | 0x00041600)); - break; - } - - if (info->local & PCX730X_15C) - dev->baddr = 0x02; - else - dev->baddr = 0x03; - - pc87307_reset(dev); - - return dev; -} - -const device_t pc87307_device = { - .name = "National Semiconductor PC87307 Super I/O", - .internal_name = "pc87307", - .flags = 0, - .local = 0x1c0, - .init = pc87307_init, - .close = pc87307_close, - .reset = pc87307_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87307_15c_device = { - .name = "National Semiconductor PC87307 Super I/O (Port 15Ch)", - .internal_name = "pc87307_15c", - .flags = 0, - .local = 0x2c0, - .init = pc87307_init, - .close = pc87307_close, - .reset = pc87307_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc87307_both_device = { - .name = "National Semiconductor PC87307 Super I/O (Ports 2Eh and 15Ch)", - .internal_name = "pc87307_both", - .flags = 0, - .local = 0x3c0, - .init = pc87307_init, - .close = pc87307_close, - .reset = pc87307_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; - -const device_t pc97307_device = { - .name = "National Semiconductor PC97307 Super I/O", - .internal_name = "pc97307", - .flags = 0, - .local = 0x1cf, - .init = pc87307_init, - .close = pc87307_close, - .reset = pc87307_reset, - .available = NULL, - .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL -}; +/* + * 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. + * + * Emulation of the NatSemi PC87307 Super I/O chip. + * + * Authors: Miran Grca, + * + * Copyright 2020-2025 Miran Grca. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/io.h> +#include <86box/timer.h> +#include <86box/device.h> +#include <86box/lpt.h> +#include <86box/machine.h> +#include <86box/mem.h> +#include <86box/nvr.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/serial.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/sio.h> +#include <86box/random.h> +#include <86box/plat_fallthrough.h> +#include "cpu.h" + +typedef struct pc87307_t { + uint8_t id; + uint8_t baddr; + uint8_t pm_idx; + uint8_t regs[48]; + uint8_t ld_regs[256][256]; + uint8_t pcregs[16]; + uint8_t gpio[2][8]; + uint8_t pm[8]; + uint16_t superio_base; + uint16_t gpio_base; + uint16_t gpio_base2; + uint16_t pm_base; + int cur_reg; + void *kbc; + fdc_t *fdc; + serial_t *uart[2]; + lpt_t *lpt; +} pc87307_t; + +enum { + LD_KBD = 0, + LD_MOUSE, + LD_RTC, + LD_FDC, + LD_LPT, + LD_UART2, + LD_UART1, + LD_GPIO, + LD_PM +} pc87307_ld_t; + +#define LD_MIN LD_KBD +#define LD_MAX LD_PM + +static void fdc_handler(pc87307_t *dev); +static void lpt_handler(pc87307_t *dev); +static void serial_handler(pc87307_t *dev, int uart); +static void kbc_handler(pc87307_t *dev); +static void pc87307_write(uint16_t port, uint8_t val, void *priv); +static uint8_t pc87307_read(uint16_t port, void *priv); + +#ifdef ENABLE_PC87307_LOG +int pc87307_do_log = ENABLE_PC87307_LOG; + +static void +pc87307_log(const char *fmt, ...) +{ + va_list ap; + + if (pc87307_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define pc87307_log(fmt, ...) +#endif + +static void +pc87307_gpio_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + uint8_t bank = !!(dev->regs[0x22] & 0x80); + + /* Bit 7 of SCNF2 = bank. */ + pc87307_log("[%04X:%08X] [W] (%04X) Bank %i = %02X\n", + CS, cpu_state.pc, port, bank, val); + + dev->gpio[bank][port & 0x0007] = val; + + if (bank == 0) { + machine_handle_gpio(1, ((dev->gpio[0][5] & dev->gpio[0][4]) << 8) | (dev->gpio[0][0] & dev->gpio[0][1])); + } +} + +uint8_t +pc87307_gpio_read(uint16_t port, void *priv) +{ + const pc87307_t *dev = (pc87307_t *) priv; + uint8_t pins = 0xff; + uint8_t bank = !!(dev->regs[0x22] & 0x80); + uint8_t ret = dev->gpio[bank][port & 0x0007]; + + switch (port & 0x0007) { + case 0x0000: + if (bank == 0) { + uint8_t mask = dev->gpio[0][1]; + pins = machine_handle_gpio(0, 0xFFFF) & 0xFF; + ret = (ret & mask) | (pins & ~mask); + } + break; + case 0x0004: + if (bank == 0) { + uint8_t mask = dev->gpio[0][5]; + pins = (machine_handle_gpio(0, 0xFFFF) >> 8) & 0xFF; + ret = (ret & mask) | (pins & ~mask); + } else + ret = 0xff; + break; + + default: + if (bank == 1) + ret = 0xff; + break; + } + + /* Bit 7 of SCNF2 = bank. */ + pc87307_log("[%04X:%08X] [R] (%04X) Bank %i = %02X\n", + CS, cpu_state.pc, port, bank, ret); + + return ret; +} + +static void +pc87307_gpio_remove(pc87307_t *dev) +{ + if (dev->gpio_base != 0xffff) { + io_removehandler(dev->gpio_base, 0x0008, + pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); + dev->gpio_base = 0xffff; + } + + if (dev->gpio_base2 != 0xffff) { + io_removehandler(dev->gpio_base2, 0x0008, + pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); + dev->gpio_base2 = 0xffff; + } +} + +static void +pc87307_gpio_init(pc87307_t *dev, int bank, uint16_t addr) +{ + uint16_t *bank_base = bank ? &(dev->gpio_base2) : &(dev->gpio_base); + + *bank_base = addr; + + io_sethandler(*bank_base, 0x0008, + pc87307_gpio_read, NULL, NULL, pc87307_gpio_write, NULL, NULL, dev); +} + +static void +pc87307_pm_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + if (port & 1) + dev->pm[dev->pm_idx] = val; + else { + dev->pm_idx = val & 0x07; + + switch (dev->pm_idx) { + case 0x00: + fdc_handler(dev); + lpt_handler(dev); + serial_handler(dev, 1); + serial_handler(dev, 0); + break; + + default: + break; + } + } +} + +uint8_t +pc87307_pm_read(uint16_t port, void *priv) +{ + const pc87307_t *dev = (pc87307_t *) priv; + + if (port & 1) + return dev->pm[dev->pm_idx]; + else + return dev->pm_idx; +} + +static void +pc87307_pm_remove(pc87307_t *dev) +{ + if (dev->pm_base != 0xffff) { + io_removehandler(dev->pm_base, 0x0008, + pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); + dev->pm_base = 0xffff; + } +} + +static void +pc87307_pm_init(pc87307_t *dev, uint16_t addr) +{ + dev->pm_base = addr; + + io_sethandler(dev->pm_base, 0x0008, + pc87307_pm_read, NULL, NULL, pc87307_pm_write, NULL, NULL, dev); +} + +static void +kbc_handler(pc87307_t *dev) +{ + uint8_t active = (dev->ld_regs[LD_KBD][0x00] & 0x01) && + (dev->pm[0x00] & 0x01); + uint8_t active_2 = dev->ld_regs[LD_MOUSE][0x00] & 0x01; + uint8_t irq = (dev->ld_regs[LD_KBD][0x40] & 0x0f); + uint8_t irq_2 = (dev->ld_regs[LD_MOUSE][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_KBD][0x30] << 8) | + dev->ld_regs[LD_KBD][0x31]; + uint16_t addr_2 = (dev->ld_regs[LD_KBD][0x32] << 8) | + dev->ld_regs[LD_KBD][0x33]; + + pc87307_log("%02X, %02X, %02X, %02X, %04X, %04X\n", + active, active_2, irq, irq_2, addr, addr_2); + + if (addr <= 0xfff8) { + pc87307_log("Enabling KBC #1 on %04X...\n", addr); + kbc_at_port_handler(0, active, addr, dev->kbc); + } + + if (addr_2 <= 0xfff8) { + pc87307_log("Enabling KBC #2 on %04X...\n", addr_2); + kbc_at_port_handler(1, active, addr_2, dev->kbc); + } + + kbc_at_set_irq(0, active ? irq : 0xffff, dev->kbc); + kbc_at_set_irq(1, (active && active_2) ? irq_2 : 0xffff, dev->kbc); +} + +static void +fdc_handler(pc87307_t *dev) +{ + fdc_remove(dev->fdc); + + uint8_t active = (dev->ld_regs[LD_FDC][0x00] & 0x01) && + (dev->pm[0x00] & 0x08); + uint8_t irq = (dev->ld_regs[LD_FDC][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_FDC][0x44] & 0x0f); + uint16_t addr = ((dev->ld_regs[LD_FDC][0x30] << 8) | + dev->ld_regs[LD_FDC][0x31]) & 0xfff8; + + if (active && (addr <= 0xfff8)) { + pc87307_log("Enabling FDC on %04X, IRQ %i...\n", addr, irq); + fdc_set_base(dev->fdc, addr); + fdc_set_irq(dev->fdc, irq); + fdc_set_dma_ch(dev->fdc, dma); + } +} + +static void +lpt_handler(pc87307_t *dev) +{ + uint8_t active = (dev->ld_regs[LD_LPT][0x00] & 0x01) && + (dev->pm[0x00] & 0x10); + uint8_t irq = (dev->ld_regs[LD_LPT][0x40] & 0x0f); + uint8_t dma = (dev->ld_regs[LD_LPT][0x44] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_LPT][0x30] << 8) | + dev->ld_regs[LD_LPT][0x31]; + uint8_t mode = (dev->ld_regs[LD_LPT][0xf0] >> 7); + uint16_t mask = 0xfffc; + + if (irq > 15) + irq = 0xff; + + if (dma >= 4) + dma = 0xff; + + lpt_port_remove(dev->lpt); + + switch (mode) { + default: + case 0x00: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x01: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 1); + break; + case 0x02: case 0x03: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 0); + lpt_set_ext(dev->lpt, 0); + break; + case 0x04: + lpt_set_epp(dev->lpt, 0); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + case 0x07: + mask = 0xfff8; + lpt_set_epp(dev->lpt, 1); + lpt_set_ecp(dev->lpt, 1); + lpt_set_ext(dev->lpt, 0); + break; + } + + lpt_set_cfg_regs_enabled(dev->lpt, !!(dev->ld_regs[LD_LPT][0xf0] & 0x10)); + + if (active && (addr <= (0xfffc & mask))) { + pc87307_log("Enabling LPT1 on %04X...\n", addr); + lpt_port_setup(dev->lpt, addr & mask); + } else + lpt_port_setup(dev->lpt, 0xffff); + + lpt_port_irq(dev->lpt, irq); + lpt_port_dma(dev->lpt, dma); +} + +static void +serial_handler(pc87307_t *dev, int uart) +{ + serial_remove(dev->uart[uart]); + + uint8_t active = (dev->ld_regs[LD_UART1 - uart][0x00] & 0x01) && + (dev->pm[0x00] & (1 << (6 - uart))); + uint8_t irq = (dev->ld_regs[LD_UART1 - uart][0x40] & 0x0f); + uint16_t addr = (dev->ld_regs[LD_UART1 - uart][0x30] << 8) | + dev->ld_regs[LD_UART1 - uart][0x31]; + + if (active && (addr <= 0xfff8)) { + pc87307_log("Enabling COM%i on %04X...\n", uart + 1, addr); + serial_setup(dev->uart[uart], addr, irq); + } else + serial_setup(dev->uart[uart], 0x0000, irq); +} + +static void +gpio_handler(pc87307_t *dev) +{ + pc87307_gpio_remove(dev); + + uint8_t active = (dev->ld_regs[LD_GPIO][0x00] & 0x01); + uint16_t addr = (dev->ld_regs[LD_GPIO][0x30] << 8) | + dev->ld_regs[LD_GPIO][0x31]; + uint16_t addr_2 = (dev->ld_regs[LD_GPIO][0x32] << 8) | + dev->ld_regs[LD_GPIO][0x33]; + + if (active) { + pc87307_log("Enabling GPIO #1 on %04X...\n", addr); + pc87307_gpio_init(dev, 0, addr); + pc87307_log("Enabling GPIO #2 on %04X...\n", addr_2); + pc87307_gpio_init(dev, 1, addr_2); + } +} + +static void +pm_handler(pc87307_t *dev) +{ + pc87307_pm_remove(dev); + + uint8_t active = (dev->ld_regs[LD_PM][0x00] & 0x01); + uint16_t addr = (dev->ld_regs[LD_PM][0x30] << 8) | + dev->ld_regs[LD_PM][0x31]; + + if (active) { + pc87307_log("Enabling power management on %04X...\n", addr); + pc87307_pm_init(dev, addr); + } +} + +static void +superio_handler(pc87307_t *dev) +{ + if (dev->superio_base != 0x0000) + io_removehandler(dev->superio_base, 0x0002, + pc87307_read, NULL, NULL, + pc87307_write, NULL, NULL, dev); + + switch (dev->regs[0x22] & 0x03) { + default: + dev->superio_base = 0x0000; + break; case 0x02: + dev->superio_base = 0x015c; + break; + case 0x03: + dev->superio_base = 0x002e; + break; + } + + if (dev->superio_base != 0x0000) { + pc87307_log("Enabling Super I/O on %04X...\n", dev->superio_base); + io_sethandler(dev->superio_base, 0x0002, + pc87307_read, NULL, NULL, + pc87307_write, NULL, NULL, dev); + } +} + +static void +pc87307_write(uint16_t port, uint8_t val, void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t old = dev->regs[dev->cur_reg]; + + if (index) { + dev->cur_reg = val; + return; + } else { +#ifdef ENABLE_PC87307_LOG + if (dev->cur_reg >= 0x30) + pc87307_log("[%04X:%08X] [W] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, val); + else + pc87307_log("[%04X:%08X] [W] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, val); +#endif + switch (dev->cur_reg) { + case 0x00: + case 0x02: case 0x03: + case 0x06: case 0x07: + dev->regs[dev->cur_reg] = val; + break; + case 0x21: + dev->regs[dev->cur_reg] = val; + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, !(val & 0x04)); + break; + case 0x22: + dev->regs[dev->cur_reg] = val; + superio_handler(dev); + break; + case 0x23: + dev->regs[dev->cur_reg] = (old & 0xf0) | (val & 0x0f); + break; + case 0x24: + dev->pcregs[dev->regs[0x23]] = val; + break; + default: + if (dev->cur_reg >= 0x30) + old = dev->ld_regs[ld][reg]; + break; + } + } + + switch (dev->cur_reg) { + case 0x30: + switch (ld) { + default: + break; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 1); + break; + case LD_UART1: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 0); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = val; + gpio_handler(dev); + break; + case LD_PM: + dev->ld_regs[ld][reg] = val; + pm_handler(dev); + break; + } + break; + /* I/O Range Check. */ + case 0x31: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if (ld != LD_MOUSE) + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Base Address 0 MSB. */ + case 0x60: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 1); + break; + case LD_UART1: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 0); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = val; + gpio_handler(dev); + break; + case LD_PM: + dev->ld_regs[ld][reg] = val; + pm_handler(dev); + break; + } + break; + /* Base Address 0 LSB. */ + case 0x61: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); + break; + case LD_FDC: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = (old & 0x03) | (val & 0xfc); + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); + serial_handler(dev, 1); + break; + case LD_UART1: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); + serial_handler(dev, 0); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = (old & 0x07) | (val & 0xf8); + gpio_handler(dev); + break; + case LD_PM: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); + pm_handler(dev); + break; + } + break; + /* Base Address 1 MSB (undocumented for Logical Device 7). */ + case 0x62: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = val; + gpio_handler(dev); + break; + } + break; + /* Base Address 1 LSB (undocumented for Logical Device 7). */ + case 0x63: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = (old & 0x04) | (val & 0xfb); + kbc_handler(dev); + break; + case LD_GPIO: + dev->ld_regs[ld][reg] = (old & 0x01) | (val & 0xfe); + gpio_handler(dev); + break; + } + break; + /* Interrupt Select. */ + case 0x70: + switch (ld) { + default: + break; + case LD_KBD: case LD_MOUSE: + dev->ld_regs[ld][reg] = val; + kbc_handler(dev); + break; + case LD_RTC: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 1); + break; + case LD_UART1: + dev->ld_regs[ld][reg] = val; + serial_handler(dev, 0); + break; + } + break; + /* Interrupt Type. */ + case 0x71: + switch (ld) { + default: + break; + case LD_MIN ... LD_MAX: + if ((ld == LD_KBD) || (ld == LD_MOUSE)) + dev->ld_regs[ld][reg] = (old & 0xfc) | (val & 0x03); + else + dev->ld_regs[ld][reg] = (old & 0xfd) | (val & 0x02); + break; + } + break; + /* DMA Channel Select 0. */ + case 0x74: + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_handler(dev); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* DMA Channel Select 1. */ + case 0x75: + switch (ld) { + default: + break; + case LD_UART2: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Configuration Register 0. */ + case 0xf0: + switch (ld) { + default: + break; + case LD_KBD: + dev->ld_regs[ld][reg] = val; + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + fdc_update_densel_polarity(dev->fdc, (val & 0x20) ? 1 : 0); + fdc_update_enh_mode(dev->fdc, (val & 0x40) ? 1 : 0); + break; + case LD_LPT: + dev->ld_regs[ld][reg] = val; + lpt_handler(dev); + break; + case LD_UART2: case LD_UART1: + dev->ld_regs[ld][reg] = val; + break; + } + break; + /* Configuration Register 1. */ + case 0xf1: + switch (ld) { + default: + break; + case LD_FDC: + dev->ld_regs[ld][reg] = val; + break; + } + break; + + default: + break; + } +} + +static uint8_t +pc87307_read(uint16_t port, void *priv) +{ + const pc87307_t *dev = (pc87307_t *) priv; + uint8_t ld = dev->regs[0x07]; + uint8_t reg = dev->cur_reg - 0x30; + uint8_t index = (port & 1) ? 0 : 1; + uint8_t ret = 0xff; + + if (index) + ret = dev->cur_reg; + else { + if (dev->cur_reg >= 0x30) + ret = dev->ld_regs[ld][reg]; + else if (dev->cur_reg == 0x24) + ret = dev->pcregs[dev->regs[0x23]]; + /* Write-only registers. */ + else if ((dev->cur_reg == 0x00) || + (dev->cur_reg == 0x02) || (dev->cur_reg == 0x03)) + ret = 0x00; + else + ret = dev->regs[dev->cur_reg]; +#ifdef EANBLE_PC87307_LOG + if (dev->cur_reg >= 0x30) + pc87307_log("[%04X:%08X] [R] (%04X) %02X:%02X = %02X\n", + CS, cpu_state.pc, port, ld, dev->cur_reg, ret); + else + pc87307_log("[%04X:%08X] [R] (%04X) %02X = %02X\n", + CS, cpu_state.pc, port, dev->cur_reg, ret); +#endif + } + + return ret; +} + +void +pc87307_reset(void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + memset(dev->regs, 0x00, 0x30); + for (uint16_t i = 0; i < 256; i++) + memset(dev->ld_regs[i], 0x00, 0xd0); + memset(dev->pcregs, 0x00, 0x10); + memset(dev->gpio, 0xff, 0x08); + memset(dev->pm, 0x00, 0x08); + + dev->regs[0x20] = dev->id; + dev->regs[0x21] = 0x04; + dev->regs[0x22] = dev->baddr; + + dev->ld_regs[LD_KBD ][0x00] = 0x01; + dev->ld_regs[LD_KBD ][0x31] = 0x60; + dev->ld_regs[LD_KBD ][0x33] = 0x64; + dev->ld_regs[LD_KBD ][0x40] = 0x01; + dev->ld_regs[LD_KBD ][0x41] = 0x02; + dev->ld_regs[LD_KBD ][0x44] = 0x04; + dev->ld_regs[LD_KBD ][0x45] = 0x04; + dev->ld_regs[LD_KBD ][0xc0] = 0x40; + + dev->ld_regs[LD_MOUSE][0x40] = 0x0c; + dev->ld_regs[LD_MOUSE][0x41] = 0x02; + dev->ld_regs[LD_MOUSE][0x44] = 0x04; + dev->ld_regs[LD_MOUSE][0x45] = 0x04; + + dev->ld_regs[LD_RTC ][0x00] = 0x01; + dev->ld_regs[LD_RTC ][0x31] = 0x70; + dev->ld_regs[LD_RTC ][0x40] = 0x08; + dev->ld_regs[LD_RTC ][0x44] = 0x04; + dev->ld_regs[LD_RTC ][0x45] = 0x04; + + dev->ld_regs[LD_FDC ][0x01] = 0x01; + dev->ld_regs[LD_FDC ][0x30] = 0x03; + dev->ld_regs[LD_FDC ][0x31] = 0xf0; + dev->ld_regs[LD_FDC ][0x32] = 0x03; + dev->ld_regs[LD_FDC ][0x33] = 0xf7; + dev->ld_regs[LD_FDC ][0x40] = 0x06; + dev->ld_regs[LD_FDC ][0x41] = 0x03; + dev->ld_regs[LD_FDC ][0x44] = 0x02; + dev->ld_regs[LD_FDC ][0x45] = 0x04; + dev->ld_regs[LD_FDC ][0xc0] = 0x02; + + dev->ld_regs[LD_LPT ][0x30] = 0x02; + dev->ld_regs[LD_LPT ][0x31] = 0x78; + dev->ld_regs[LD_LPT ][0x40] = 0x07; + dev->ld_regs[LD_LPT ][0x44] = 0x04; + dev->ld_regs[LD_LPT ][0x45] = 0x04; + dev->ld_regs[LD_LPT ][0xc0] = 0xf2; + + dev->ld_regs[LD_UART2][0x30] = 0x02; + dev->ld_regs[LD_UART2][0x31] = 0xf8; + dev->ld_regs[LD_UART2][0x40] = 0x03; + dev->ld_regs[LD_UART2][0x41] = 0x03; + dev->ld_regs[LD_UART2][0x44] = 0x04; + dev->ld_regs[LD_UART2][0x45] = 0x04; + dev->ld_regs[LD_UART2][0xc0] = 0x02; + + dev->ld_regs[LD_UART1][0x30] = 0x03; + dev->ld_regs[LD_UART1][0x31] = 0xf8; + dev->ld_regs[LD_UART1][0x40] = 0x04; + dev->ld_regs[LD_UART1][0x41] = 0x03; + dev->ld_regs[LD_UART1][0x44] = 0x04; + dev->ld_regs[LD_UART1][0x45] = 0x04; + dev->ld_regs[LD_UART1][0xc0] = 0x02; + + dev->ld_regs[LD_GPIO ][0x44] = 0x04; + dev->ld_regs[LD_GPIO ][0x45] = 0x04; + + dev->ld_regs[LD_PM ][0x44] = 0x04; + dev->ld_regs[LD_PM ][0x45] = 0x04; + + dev->gpio[0][0] = 0xff; + dev->gpio[0][1] = 0x00; + dev->gpio[0][2] = 0x00; + dev->gpio[0][3] = 0xff; + dev->gpio[0][4] = 0xff; + dev->gpio[0][5] = 0x00; + dev->gpio[0][6] = 0x00; + dev->gpio[0][7] = 0xff; + dev->gpio[1][1] = 0x00; + + dev->pm[0] = 0xff; + dev->pm[1] = 0xff; + dev->pm[4] = 0x0e; + dev->pm[7] = 0x01; + + dev->gpio_base = dev->pm_base = 0xffff; + + /* + 0 = 360 rpm @ 500 kbps for 3.5" + 1 = Default, 300 rpm @ 500, 300, 250, 1000 kbps for 3.5" + */ + fdc_toggle_flag(dev->fdc, FDC_FLAG_PS2_MCA, 0); + fdc_reset(dev->fdc); + + kbc_handler(dev); + fdc_handler(dev); + lpt_handler(dev); + serial_handler(dev, 0); + serial_handler(dev, 1); + gpio_handler(dev); + pm_handler(dev); + superio_handler(dev); +} + +static void +pc87307_close(void *priv) +{ + pc87307_t *dev = (pc87307_t *) priv; + + free(dev); +} + +static void * +pc87307_init(const device_t *info) +{ + pc87307_t *dev = (pc87307_t *) calloc(1, sizeof(pc87307_t)); + + dev->id = info->local & 0xff; + + dev->fdc = device_add(&fdc_at_nsc_device); + + dev->uart[0] = device_add_inst(&ns16550_device, 1); + dev->uart[1] = device_add_inst(&ns16550_device, 2); + + dev->lpt = device_add_inst(&lpt_port_device, 1); + lpt_set_cnfga_readout(dev->lpt, 0x14); + + switch (info->local & PCX730X_KBC) { + case PCX730X_AMI: + default: + dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_AMI | 0x00003500)); + break; + /* Optiplex! */ + case PCX730X_PHOENIX_42: + dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_PHOENIX | 0x00013700)); + break; + case PCX730X_PHOENIX_42I: + dev->kbc = device_add_params(&kbc_at_device, (void *) (KBC_VEN_PHOENIX | 0x00041600)); + break; + } + + if (info->local & PCX730X_15C) + dev->baddr = 0x02; + else + dev->baddr = 0x03; + + pc87307_reset(dev); + + return dev; +} + +const device_t pc87307_device = { + .name = "National Semiconductor PC87307 Super I/O", + .internal_name = "pc87307", + .flags = 0, + .local = 0x1c0, + .init = pc87307_init, + .close = pc87307_close, + .reset = pc87307_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t pc87307_15c_device = { + .name = "National Semiconductor PC87307 Super I/O (Port 15Ch)", + .internal_name = "pc87307_15c", + .flags = 0, + .local = 0x2c0, + .init = pc87307_init, + .close = pc87307_close, + .reset = pc87307_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t pc87307_both_device = { + .name = "National Semiconductor PC87307 Super I/O (Ports 2Eh and 15Ch)", + .internal_name = "pc87307_both", + .flags = 0, + .local = 0x3c0, + .init = pc87307_init, + .close = pc87307_close, + .reset = pc87307_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t pc97307_device = { + .name = "National Semiconductor PC97307 Super I/O", + .internal_name = "pc97307", + .flags = 0, + .local = 0x1cf, + .init = pc87307_init, + .close = pc87307_close, + .reset = pc87307_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/sio/sio_w83977.c b/src/sio/sio_w83977.c index a14e50942fb..07fda5d4e24 100644 --- a/src/sio/sio_w83977.c +++ b/src/sio/sio_w83977.c @@ -1330,7 +1330,7 @@ w83977_init(const device_t *info) } const device_t w83977_device = { - .name = "SMC FDC37C93x Super I/O", + .name = "Winbond W83977F/TF/EF Super I/O", .internal_name = "w83977", .flags = 0, .local = 0, diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index ccb54ab1909..a6a9b691aa7 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -192,6 +192,10 @@ if(OPL4ML) target_compile_definitions(snd PRIVATE USE_OPL4ML) target_sources(snd PRIVATE midi_opl4.c midi_opl4_yrw801.c) endif() + +if(SOFTMODEM) + target_compile_definitions(snd PRIVATE USE_SOFTMODEM) +endif() find_package(PkgConfig) pkg_check_modules(SERIALPORT libserialport) diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index 77e5825d906..0713568732d 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -10,7 +10,7 @@ * * Authors: RichardG, * - * Copyright 2021 RichardG. + * Copyright 2021-2025 RichardG. */ #include #include @@ -35,7 +35,10 @@ static const struct { uint16_t reset_flags; uint16_t extid_flags; uint8_t pcsr_mask; /* register 26 bits [15:8] */ - uint8_t eascr_mask; /* register 2A bits [14:11] */ + uint8_t eascr_mask; /* register 2A bits [14:11] (audio) or 56 bits ... */ + uint8_t modem_flags; + uint16_t gpi_mask; /* modem GPIO input-capable bits */ + uint16_t gpo_mask; /* modem GPIO output-capable bits */ const ac97_vendor_reg_t *vendor_regs; } ac97_codecs[] = { @@ -44,7 +47,7 @@ static const struct { .device = &ad1881_device, .min_rate = 7000, .max_rate = 48000, - .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MASTER_6B | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, .reset_flags = (1 << AC97_3D_SHIFT), /* datasheet contradicts itself on AC97_HPOUT */ .extid_flags = AC97_VRA, .pcsr_mask = 0xbf, @@ -52,26 +55,26 @@ static const struct { }, { .device = &ak4540_device, - .misc_flags = AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .pcsr_mask = 0x1f }, { .device = &alc100_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_POP | AC97_MS | AC97_LPBK, .reset_flags = (22 << AC97_3D_SHIFT), .extid_flags = AC97_AMAP, .pcsr_mask = 0xbf }, { .device = &cs4297_device, - .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MASTER_6B | AC97_AUXOUT | AC97_AUXOUT_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_HPOUT | AC97_DAC_18B | AC97_ADC_18B, .pcsr_mask = 0x7f, .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5a, 0x0301, 0x0000}, {0}} }, { .device = &cs4297a_device, - .misc_flags = AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MASTER_6B | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_HPOUT | AC97_DAC_20B | AC97_ADC_18B | (6 << AC97_3D_SHIFT), .extid_flags = AC97_AMAP, .pcsr_mask = 0xff, @@ -79,7 +82,7 @@ static const struct { }, { .device = &stac9708_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, .extid_flags = AC97_SDAC, .pcsr_mask = 0xff, @@ -88,7 +91,7 @@ static const struct { }, { .device = &stac9721_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = (26 << AC97_3D_SHIFT) | AC97_DAC_18B | AC97_ADC_18B, .extid_flags = AC97_AMAP, .pcsr_mask = 0xff, @@ -96,21 +99,33 @@ static const struct { }, { .device = &tr28023_device, - .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_POP | AC97_MS | AC97_LPBK, .pcsr_mask = 0x3f }, { .device = &w83971d_device, - .misc_flags = AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_MASTER_6B | AC97_MONOOUT | AC97_MONOOUT_6B | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = (27 << AC97_3D_SHIFT), .pcsr_mask = 0x3f }, { .device = &wm9701a_device, - .misc_flags = AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, + .misc_flags = AC97_AUDIO | AC97_AUXOUT | AC97_MONOOUT | AC97_PCBEEP | AC97_PHONE | AC97_VIDEO | AC97_AUXIN | AC97_MS | AC97_LPBK, .reset_flags = AC97_DAC_18B | AC97_ADC_18B, .pcsr_mask = 0x3f + }, +#ifdef USE_SOFTMODEM + { + .device = &si3036_device, + .misc_flags = AC97_MODEM | AC97_GAIN_3B, + .min_rate = 7200, + .max_rate = 13714, + .modem_flags = AC97_LIN1 | AC97_LIN2, + .gpi_mask = 0xe83a, + .gpo_mask = 0xfc3f, + .vendor_regs = (const ac97_vendor_reg_t[]) {{0, 0x5a, 0x0142, 0x0000}, {0, 0x5c, 0xf010, 0xfefd}, {0, 0x5e, 0x004c, 0x0000}, {0, 0x62, 0x0000, 0x01f8}, {0, 0x64, 0x0080, 0x0000}, {0}} } +#endif // clang-format on }; @@ -143,11 +158,10 @@ static const int32_t codec_attn[] = { }; ac97_codec_t **ac97_codec = NULL; -ac97_codec_t **ac97_modem_codec = NULL; int ac97_codec_count = 0; -int ac97_modem_codec_count = 0; int ac97_codec_id = 0; -int ac97_modem_codec_id = 0; + +static void ac97_codec_reset_ex(ac97_codec_t *dev, uint8_t flags); uint16_t ac97_codec_readw(ac97_codec_t *dev, uint8_t reg) @@ -155,10 +169,15 @@ ac97_codec_readw(ac97_codec_t *dev, uint8_t reg) /* Redirect a read from extended pages 1+ to the right array. */ reg &= 0x7e; uint16_t ret = dev->regs[0x24 >> 1] & 0x000f; - if ((ret > 0) && (reg >= 0x60) && (reg < 0x6f)) + if ((ret > 0) && (reg >= 0x60) && (reg < 0x6f)) { /* Extended */ ret = (ret <= dev->vendor_reg_page_max) ? dev->vendor_reg_pages[(ret << 3) | ((reg & 0x0e) >> 1)] : 0; - else + } else if (reg == 0x54) { /* GPIO Status */ + ret = dev->gpo & ~dev->regs[0x4c >> 1]; /* outputs */ + ret |= dev->gpi & dev->regs[0x4c >> 1] & ~dev->regs[0x50 >> 1]; /* non-sticky inputs */ + ret |= dev->regs[reg >> 1] & dev->regs[0x4c >> 1] & dev->regs[0x50 >> 1]; /* sticky inputs */ + } else { ret = dev->regs[reg >> 1]; + } ac97_codec_log("AC97 Codec %d: readw(%02X) = %04X\n", dev->codec_id, reg, ret); @@ -175,9 +194,15 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) uint16_t prev = dev->regs[reg >> 1]; int j; + /* Initial filtering by codec type. */ + if (!(ac97_codecs[dev->model].misc_flags & AC97_AUDIO) && (reg <= 0x3a)) + return; + if (!(ac97_codecs[dev->model].misc_flags & AC97_MODEM) && (reg >= 0x3c) && (reg <= 0x58)) + return; + switch (reg) { case 0x00: /* Reset / ID code */ - ac97_codec_reset(dev); + ac97_codec_reset_ex(dev, AC97_AUDIO); return; case 0x02: /* Master Volume */ @@ -260,13 +285,13 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) break; case 0x1c: /* Record Gain */ - val &= 0x8f0f; + val &= (ac97_codecs[dev->model].misc_flags & AC97_GAIN_3B) ? 0x8e0e : 0x8f0f; break; case 0x1e: /* Record Gain Mic */ if (!(ac97_codecs[dev->model].reset_flags & AC97_MICPCM)) return; - val &= 0x800f; + val &= (ac97_codecs[dev->model].misc_flags & AC97_GAIN_3B) ? 0x800e : 0x800f; break; case 0x20: /* General Purpose */ @@ -350,11 +375,11 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) case 0x2c: /* PCM Front DAC Rate */ case 0x32: /* PCM L/R ADC Rate */ -rate: /* Writable only if VRA/VRM is set. */ +rate_vrx: /* Writable only if VRA/VRM is set. */ i = (reg >= 0x32) ? AC97_VRM : AC97_VRA; if (!(ac97_codecs[dev->model].extid_flags & i)) return; - +rate: /* Limit to supported sample rate range. */ if (val < ac97_codecs[dev->model].min_rate) val = ac97_codecs[dev->model].min_rate; @@ -365,17 +390,17 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) case 0x2e: /* PCM Surround DAC Rate */ if (!(ac97_codecs[dev->model].extid_flags & AC97_SDAC)) return; - goto rate; + goto rate_vrx; case 0x30: /* PCM LFE DAC Rate */ if (!(ac97_codecs[dev->model].extid_flags & AC97_LDAC)) return; - goto rate; + goto rate_vrx; case 0x34: /* Mic ADC Rate */ if (!(ac97_codecs[dev->model].reset_flags & AC97_MICPCM)) return; - goto rate; + goto rate_vrx; case 0x36: /* Center/LFE Volume */ if (ac97_codecs[dev->model].extid_flags & AC97_LDAC) @@ -406,6 +431,86 @@ ac97_codec_writew(ac97_codec_t *dev, uint8_t reg, uint16_t val) return; break; + case 0x3c: /* Reset / Extended Modem ID */ + ac97_codec_reset_ex(dev, AC97_MODEM); + return; + + case 0x3e: /* Extended Modem Control/Status */ + i = 0x0300; + if (ac97_codecs[dev->model].modem_flags & AC97_LIN1) + i |= 0x0c00; + if (ac97_codecs[dev->model].modem_flags & AC97_LIN2) + i |= 0x3000; + if (ac97_codecs[dev->model].modem_flags & AC97_HSET) + i |= 0xc000; + val &= i; + + /* Update status bits to reflect powerdowns. */ + val |= (~val & i) >> 8; + break; + + case 0x40: /* Line1 DAC/ADC Rate */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_LIN1)) + return; + goto rate; + + case 0x42: /* Line2 DAC/ADC Rate */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_LIN2)) + return; + goto rate; + + case 0x44: /* Handset DAC/ADC Rate */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_HSET)) + return; + goto rate; + + case 0x46: /* Line 1 DAC/ADC Level */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_LIN1)) + return; +modem_gain: + val &= (ac97_codecs[dev->model].misc_flags & AC97_GAIN_3B) ? 0x8e8e : 0x8f8f; + break; + + case 0x48: /* Line 2 DAC/ADC Level */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_LIN2)) + return; + goto modem_gain; + + case 0x4a: /* Handset DAC/ADC Level */ + if (!(ac97_codecs[dev->model].modem_flags & AC97_HSET)) + return; + goto modem_gain; + + case 0x56: /* Miscellaneous Modem AFE Status/Control */ + if (ac97_codecs[dev->model].modem_flags & AC97_LIN1) + i |= 0x0007; + if (ac97_codecs[dev->model].modem_flags & AC97_LIN2) + i |= 0x0070; + if (ac97_codecs[dev->model].modem_flags & AC97_HSET) + i |= 0x0700; + val &= i; + break; + + case 0x4c: /* GPIO Pin Configuration */ + val &= ac97_codecs[dev->model].gpi_mask | ac97_codecs[dev->model].gpo_mask; + break; + + case 0x4e: /* GPIO Pin Polarity/Type */ + val |= ~(ac97_codecs[dev->model].gpi_mask | ac97_codecs[dev->model].gpo_mask); + break; + + case 0x50: /* GPIO Pin Sticky */ + dev->regs[0x54 >> 1] &= val; /* clear sticky inputs that are no longer sticky (assumed undefined behavior) */ + fallthrough; + + case 0x52: /* GPIO Pin Wake-up Mask */ + val &= ac97_codecs[dev->model].gpi_mask; + break; + + case 0x54: /* GPIO Pin Status */ + val = dev->regs[reg >> 1] & ~val; /* clear sticky inputs */ + break; + case 0x60 ... 0x6e: /* Extended */ /* Get extended register page. */ i = dev->regs[0x24 >> 1] & 0x000f; @@ -462,47 +567,83 @@ void ac97_codec_reset(void *priv) { ac97_codec_t *dev = (ac97_codec_t *) priv; - uint16_t i; + ac97_codec_reset_ex(dev, AC97_AUDIO | AC97_MODEM); +} - ac97_codec_log("AC97 Codec %d: reset()\n", dev->codec_id); +static void +ac97_codec_reset_ex(ac97_codec_t *dev, uint8_t flags) +{ + ac97_codec_log("AC97 Codec %d: reset(%02X)\n", dev->codec_id, flags); memset(dev->regs, 0, sizeof(dev->regs)); - /* Set default level and gain values. */ - dev->regs[0x02 >> 1] = AC97_MUTE; - if (ac97_codecs[dev->model].misc_flags & AC97_AUXOUT) - dev->regs[0x04 >> 1] = AC97_MUTE; - if (ac97_codecs[dev->model].misc_flags & AC97_MONOOUT) - dev->regs[0x06 >> 1] = AC97_MUTE; - if (ac97_codecs[dev->model].misc_flags & AC97_PHONE) - dev->regs[0x0c >> 1] = AC97_MUTE | 0x0008; - dev->regs[0x0e >> 1] = AC97_MUTE | 0x0008; /* mic */ - dev->regs[0x10 >> 1] = dev->regs[0x12 >> 1] = dev->regs[0x18 >> 1] = AC97_MUTE | 0x0808; /* line in, CD, PCM out */ - if (ac97_codecs[dev->model].misc_flags & AC97_VIDEO) - dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; - if (ac97_codecs[dev->model].misc_flags & AC97_AUXIN) - dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; - dev->regs[0x1c >> 1] = AC97_MUTE; /* record gain */ - if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) - dev->regs[0x1e >> 1] = AC97_MUTE; /* mic record gain */ - if (ac97_codecs[dev->model].misc_flags & AC97_LDAC) - dev->regs[0x36 >> 1] = AC97_MUTE_L; - if (ac97_codecs[dev->model].misc_flags & AC97_CDAC) - dev->regs[0x36 >> 1] |= AC97_MUTE_R; - if (ac97_codecs[dev->model].misc_flags & AC97_SDAC) - dev->regs[0x38 >> 1] = AC97_MUTE_L | AC97_MUTE_R; - - /* Set flags. */ - dev->regs[0x00 >> 1] = ac97_codecs[dev->model].reset_flags; - dev->regs[0x26 >> 1] = 0x000f; /* codec ready */ - dev->regs[0x28 >> 1] = (dev->codec_id << 14) | ac97_codecs[dev->model].extid_flags; - ac97_codec_writew(dev, 0x2a, 0x0000); /* reset variable DAC/ADC sample rates */ - i = ac97_codecs[dev->model].extid_flags & (AC97_CDAC | AC97_SDAC | AC97_LDAC); - dev->regs[0x2a >> 1] |= i | (i << 5); /* any additional DACs are ready but powered down */ - if (ac97_codecs[dev->model].extid_flags & AC97_SPDIF) - dev->regs[0x2a >> 1] |= AC97_SPCV; - if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) - dev->regs[0x2a >> 1] |= AC97_MADC | AC97_PRL; + if ((flags & AC97_AUDIO) && (ac97_codecs[dev->model].misc_flags & AC97_AUDIO)) { + /* Set default level and gain values. */ + dev->regs[0x02 >> 1] = AC97_MUTE; + if (ac97_codecs[dev->model].misc_flags & AC97_AUXOUT) + dev->regs[0x04 >> 1] = AC97_MUTE; + if (ac97_codecs[dev->model].misc_flags & AC97_MONOOUT) + dev->regs[0x06 >> 1] = AC97_MUTE; + if (ac97_codecs[dev->model].misc_flags & AC97_PHONE) + dev->regs[0x0c >> 1] = AC97_MUTE | 0x0008; + dev->regs[0x0e >> 1] = AC97_MUTE | 0x0008; /* mic */ + dev->regs[0x10 >> 1] = dev->regs[0x12 >> 1] = dev->regs[0x18 >> 1] = AC97_MUTE | 0x0808; /* line in, CD, PCM out */ + if (ac97_codecs[dev->model].misc_flags & AC97_VIDEO) + dev->regs[0x14 >> 1] = AC97_MUTE | 0x0808; + if (ac97_codecs[dev->model].misc_flags & AC97_AUXIN) + dev->regs[0x16 >> 1] = AC97_MUTE | 0x0808; + dev->regs[0x18 >> 1] = AC97_MUTE | 0x0808; /* PCM */ + dev->regs[0x1c >> 1] = AC97_MUTE; /* record gain */ + if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) + dev->regs[0x1e >> 1] = AC97_MUTE; /* mic record gain */ + if (ac97_codecs[dev->model].misc_flags & AC97_LDAC) + dev->regs[0x36 >> 1] = AC97_MUTE_L; + if (ac97_codecs[dev->model].misc_flags & AC97_CDAC) + dev->regs[0x36 >> 1] |= AC97_MUTE_R; + if (ac97_codecs[dev->model].misc_flags & AC97_SDAC) + dev->regs[0x38 >> 1] = AC97_MUTE_L | AC97_MUTE_R; + + /* Set flags. */ + dev->regs[0x00 >> 1] = ac97_codecs[dev->model].reset_flags; + dev->regs[0x26 >> 1] = 0x000f; /* codec ready */ + dev->regs[0x28 >> 1] = (dev->codec_id << 14) | ac97_codecs[dev->model].extid_flags; + ac97_codec_writew(dev, 0x2a, 0x0000); /* reset variable DAC/ADC sample rates */ + uint16_t i = ac97_codecs[dev->model].extid_flags & (AC97_CDAC | AC97_SDAC | AC97_LDAC); + dev->regs[0x2a >> 1] |= i | (i << 5); /* any additional DACs are ready but powered down */ + if (ac97_codecs[dev->model].extid_flags & AC97_SPDIF) + dev->regs[0x2a >> 1] |= AC97_SPCV; + if (ac97_codecs[dev->model].reset_flags & AC97_MICPCM) + dev->regs[0x2a >> 1] |= AC97_MADC | AC97_PRL; + } + + if ((flags & AC97_MODEM) && (ac97_codecs[dev->model].misc_flags & AC97_MODEM)) { + if (ac97_codecs[dev->model].modem_flags & AC97_LIN1) { + dev->regs[0x3e >> 1] |= 0x0c00; + dev->regs[0x40 >> 1] = /*4*/8000; + dev->regs[0x46 >> 1] = 0x8080; + } + if (ac97_codecs[dev->model].modem_flags & AC97_LIN2) { + dev->regs[0x3e >> 1] |= 0x3000; + dev->regs[0x42 >> 1] = /*4*/8000; + dev->regs[0x48 >> 1] = 0x8080; + } + if (ac97_codecs[dev->model].modem_flags & AC97_HSET) { + dev->regs[0x3e >> 1] |= 0xc000; + dev->regs[0x44 >> 1] = /*4*/8000; + dev->regs[0x4a >> 1] = 0x8080; + } + dev->regs[0x4c >> 1] = ac97_codecs[dev->model].gpi_mask | ac97_codecs[dev->model].gpo_mask; + dev->regs[0x4e >> 1] = 0xffff; + + /* Set flags. */ + dev->regs[0x3c >> 1] = (dev->codec_id << 14) | (ac97_codecs[dev->model].modem_flags & ~AC97_CIDR); + if (ac97_codecs[dev->model].modem_flags & AC97_CIDR) + dev->regs[0x56 >> 1] |= 0x2000; + if (ac97_codecs[dev->model].modem_flags & AC97_CID1) + dev->regs[0x56 >> 1] |= 0x4000; + if (ac97_codecs[dev->model].modem_flags & AC97_CID2) + dev->regs[0x56 >> 1] |= 0x8000; + } /* Set vendor ID. */ dev->regs[0x7c >> 1] = ac97_codecs[dev->model].device->local >> 16; @@ -510,13 +651,16 @@ ac97_codec_reset(void *priv) /* Set vendor-specific registers. */ if (ac97_codecs[dev->model].vendor_regs) { - for (i = 0; ac97_codecs[dev->model].vendor_regs[i].index; i++) { + for (int i = 0; ac97_codecs[dev->model].vendor_regs[i].index; i++) { if (ac97_codecs[dev->model].vendor_regs[i].page > 0) dev->vendor_reg_pages[(ac97_codecs[dev->model].vendor_regs[i].page << 3) | (ac97_codecs[dev->model].vendor_regs[i].index >> 1)] = ac97_codecs[dev->model].vendor_regs[i].value; else dev->regs[ac97_codecs[dev->model].vendor_regs[i].index >> 1] = ac97_codecs[dev->model].vendor_regs[i].value; } } + + if (flags & AC97_MODEM) + dev->gpi = dev->gpo = 0; } void @@ -534,7 +678,7 @@ ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r) *r = 0; } else { /* per-channel mute */ /* Determine attenuation value. */ - uint8_t l_val = val >> 8; + uint8_t l_val = ((reg == 0x06) || (reg == 0x0c) || (reg == 0x0e)) ? val : (val >> 8); /* mono controls only have the right bits */ uint8_t r_val = val; if (reg <= 0x06) { /* 6-bit level */ *l = codec_attn[0x3f - (l_val & 0x3f)]; @@ -561,7 +705,7 @@ ac97_codec_getattn(void *priv, uint8_t reg, int *l, int *r) uint32_t ac97_codec_getrate(void *priv, uint8_t reg) { - const ac97_codec_t *dev = (ac97_codec_t *) priv; + ac97_codec_t *dev = (ac97_codec_t *) priv; /* Get configured sample rate, which is always 48000 if VRA/VRM is not set. */ uint32_t ret = dev->regs[reg >> 1]; @@ -575,6 +719,29 @@ ac97_codec_getrate(void *priv, uint8_t reg) return ret; } +void +ac97_codec_setgpi(void *priv, uint16_t gpi) +{ + ac97_codec_t *dev = (ac97_codec_t *) priv; + + ac97_codec_log("AC97 Codec %d: setgpi(%04X)\n", dev->codec_id, gpi); + + /* Set status bits for sticky inputs. */ + gpi &= ac97_codecs[dev->model].gpi_mask; + dev->regs[0x54 >> 1] |= (dev->gpi ^ gpi) & dev->regs[0x4c >> 1] & dev->regs[0x50 >> 1]; /* set on (transition & input & sticky) */ + dev->gpi = gpi; +} + +void +ac97_codec_setgpo(void *priv, uint16_t gpo) +{ + ac97_codec_t *dev = (ac97_codec_t *) priv; + + ac97_codec_log("AC97 Codec %d: setgpo(%04X)\n", dev->codec_id, gpo); + + dev->gpo = gpo & ac97_codecs[dev->model].gpo_mask; +} + static void * ac97_codec_init(const device_t *info) { @@ -603,7 +770,7 @@ ac97_codec_init(const device_t *info) if (--ac97_codec_count == 0) ac97_codec = NULL; else - ac97_codec += sizeof(ac97_codec_t *); + ac97_codec++; dev->codec_id = ac97_codec_id++; /* Allocate vendor-specific register pages if required. */ @@ -792,3 +959,19 @@ const device_t wm9701a_device = { .force_redraw = NULL, .config = NULL }; + +#ifdef USE_SOFTMODEM +const device_t si3036_device = { + .name = "Silicon Laboratories Si3036 Modem", + .internal_name = "si3036", + .flags = DEVICE_AC97, + .local = AC97_CODEC_SI3036, + .init = ac97_codec_init, + .close = ac97_codec_close, + .reset = ac97_codec_reset, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; +#endif diff --git a/src/sound/snd_ac97_via.c b/src/sound/snd_ac97_via.c index 28b802a6fd9..f1ddc5f92b5 100644 --- a/src/sound/snd_ac97_via.c +++ b/src/sound/snd_ac97_via.c @@ -10,7 +10,7 @@ * * Authors: RichardG, * - * Copyright 2021 RichardG. + * Copyright 2021-2025 RichardG. */ #include #include @@ -35,8 +35,6 @@ typedef struct ac97_via_sgd_t { uint8_t id; uint8_t always_run; - uint8_t modem; - uint8_t pad; struct _ac97_via_ *dev; uint32_t entry_ptr; @@ -65,22 +63,20 @@ typedef struct _ac97_via_ { uint16_t audio_codec_base; uint16_t modem_sgd_base; uint16_t modem_codec_base; - uint8_t sgd_regs[2][256]; + uint8_t sgd_regs[256]; uint8_t pcm_enabled : 1; uint8_t fm_enabled : 1; + uint8_t modem_enabled : 1; uint8_t vsr_enabled : 1; - struct { - union { - uint8_t regs_codec[2][128]; - uint8_t regs_linear[256]; - }; - } codec_shadow[2]; - uint8_t pci_slot; - uint8_t irq_state; - int irq_pin; - - ac97_codec_t *codec[2][2]; - ac97_via_sgd_t sgd[2][6]; + uint8_t codec_shadow[256]; + uint8_t pci_slot; + uint8_t irq_state; + int irq_pin; + + ac97_codec_t *codec[2]; + ac97_codec_t *audio_codec; + ac97_codec_t *modem_codec; + ac97_via_sgd_t sgd[6]; int master_vol_l; int master_vol_r; @@ -107,7 +103,7 @@ ac97_via_log(const char *fmt, ...) #endif static void ac97_via_sgd_process(void *priv); -static void ac97_via_update_codec(ac97_via_t *dev, int modem); +static void ac97_via_update_codec(ac97_via_t *dev); static void ac97_via_speed_changed(void *priv); static void ac97_via_filter_cd_audio(int channel, double *buffer, void *priv); @@ -118,73 +114,70 @@ ac97_via_set_slot(void *priv, int slot, int irq_pin) ac97_via_log("AC97 VIA: set_slot(%d, %d)\n", slot, irq_pin); - dev->pci_slot = slot; - dev->irq_pin = irq_pin; + dev->pci_slot = slot; + dev->irq_pin = irq_pin; } uint8_t -ac97_via_read_status(void *priv, uint8_t modem) +ac97_via_read_status(void *priv) { const ac97_via_t *dev = (ac97_via_t *) priv; uint8_t ret = 0x00; /* Flag each codec as ready if present. */ - for (uint8_t i = 0; i <= 1; i++) { - if (dev->codec[modem][i]) + for (uint8_t i = 0; i < (sizeof(dev->codec) / sizeof(dev->codec[0])); i++) { + if (dev->codec[i]) ret |= 0x01 << (i << 1); } - ac97_via_log("AC97 VIA %d: read_status() = %02X\n", modem, ret); + ac97_via_log("AC97 VIA: read_status() = %02X\n", ret); return ret; } void -ac97_via_write_control(void *priv, uint8_t modem, uint8_t val) +ac97_via_write_control(void *priv, uint8_t val) { ac97_via_t *dev = (ac97_via_t *) priv; uint8_t i; - ac97_via_log("AC97 VIA %d: write_control(%02X)\n", modem, val); + ac97_via_log("AC97 VIA: write_control(%02X)\n", val); /* Reset codecs if requested. */ if (!(val & 0x40)) { - for (i = 0; i <= 1; i++) { - if (dev->codec[modem][i]) - ac97_codec_reset(dev->codec[modem][i]); + for (i = 0; i < (sizeof(dev->codec) / sizeof(dev->codec[0])); i++) { + if (dev->codec[i]) + ac97_codec_reset(dev->codec[i]); } } - if (!modem) { - /* Set the variable sample rate flag. */ - dev->vsr_enabled = (val & 0xf8) == 0xc8; - - /* Start or stop PCM playback. */ - i = (val & 0xf4) == 0xc4; - if (i && !dev->pcm_enabled) - timer_advance_u64(&dev->sgd[0][0].poll_timer, dev->sgd[0][0].timer_latch); - dev->pcm_enabled = i; - - /* Start or stop FM playback. */ - i = (val & 0xf2) == 0xc2; - if (i && !dev->fm_enabled) - timer_advance_u64(&dev->sgd[0][2].poll_timer, dev->sgd[0][2].timer_latch); - dev->fm_enabled = i; - - /* Update primary audio codec state. */ - if (dev->codec[0][0]) - ac97_via_update_codec(dev, 0); - } + /* Set the variable sample rate flag. */ + dev->vsr_enabled = (val & 0xf8) == 0xc8; + + /* Start or stop PCM playback. */ + i = (val & 0xf4) == 0xc4; + if (i && !dev->pcm_enabled) + timer_advance_u64(&dev->sgd[0].poll_timer, dev->sgd[0].timer_latch); + dev->pcm_enabled = i; + + /* Start or stop FM playback. */ + i = (val & 0xf2) == 0xc2; + if (i && !dev->fm_enabled) + timer_advance_u64(&dev->sgd[2].poll_timer, dev->sgd[2].timer_latch); + dev->fm_enabled = i; + + /* Update audio codec state. */ + ac97_via_update_codec(dev); } static void -ac97_via_update_irqs(ac97_via_t *dev, int modem) +ac97_via_update_irqs(ac97_via_t *dev) { /* Check interrupt flags in all SGDs. */ for (uint8_t i = 0x00; i < ((sizeof(dev->sgd) / sizeof(dev->sgd[0])) << 4); i += 0x10) { /* Stop immediately if any flag is set. Doing it this way optimizes rising edges for the playback SGD (0 - first to be checked). */ - if (dev->sgd_regs[modem][i] & (dev->sgd_regs[modem][i | 0x2] & 0x03)) { + if (dev->sgd_regs[i] & (dev->sgd_regs[i | 0x2] & 0x03)) { pci_set_irq(dev->pci_slot, dev->irq_pin, &dev->irq_state); return; } @@ -194,28 +187,28 @@ ac97_via_update_irqs(ac97_via_t *dev, int modem) } static void -ac97_via_update_codec(ac97_via_t *dev, int modem) +ac97_via_update_codec(ac97_via_t *dev) { - /* Get primary audio codec. */ - ac97_codec_t *codec = dev->codec[modem][0]; - /* Update volumes according to codec registers. */ - ac97_codec_getattn(codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); - ac97_codec_getattn(codec, 0x18, &dev->sgd[modem][0].vol_l, &dev->sgd[modem][0].vol_r); - ac97_codec_getattn(codec, 0x18, &dev->sgd[modem][2].vol_l, &dev->sgd[modem][2].vol_r); /* VIAFMTSR sets Master, CD and PCM volumes to 0 dB */ - ac97_codec_getattn(codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); + if (dev->audio_codec) { + ac97_codec_getattn(dev->audio_codec, 0x02, &dev->master_vol_l, &dev->master_vol_r); + ac97_codec_getattn(dev->audio_codec, 0x18, &dev->sgd[0].vol_l, &dev->sgd[0].vol_r); + ac97_codec_getattn(dev->audio_codec, 0x18, &dev->sgd[2].vol_l, &dev->sgd[2].vol_r); /* VIAFMTSR sets Master, CD and PCM volumes to 0 dB */ + ac97_codec_getattn(dev->audio_codec, 0x12, &dev->cd_vol_l, &dev->cd_vol_r); + ac97_codec_getattn(dev->audio_codec, 0x0c, &dev->sgd[4].vol_l, &dev->sgd[4].vol_r); + } /* Update sample rate according to codec registers and the variable sample rate flag. */ ac97_via_speed_changed(dev); } -uint8_t +static uint8_t ac97_via_sgd_read(uint16_t addr, void *priv) { const ac97_via_t *dev = (ac97_via_t *) priv; -// #ifdef ENABLE_AC97_VIA_LOG - uint8_t modem = (addr & 0xff00) == dev->modem_sgd_base; -// #endif +#ifdef ENABLE_AC97_VIA_LOG + uint8_t modem = (addr & 0xff00) == dev->modem_sgd_base; +#endif addr &= 0xff; uint8_t ret; @@ -223,78 +216,78 @@ ac97_via_sgd_read(uint16_t addr, void *priv) /* Process SGD channel registers. */ switch (addr & 0xf) { case 0x4: - ret = dev->sgd[modem][addr >> 4].entry_ptr; + ret = dev->sgd[addr >> 4].entry_ptr; break; case 0x5: - ret = dev->sgd[modem][addr >> 4].entry_ptr >> 8; + ret = dev->sgd[addr >> 4].entry_ptr >> 8; break; case 0x6: - ret = dev->sgd[modem][addr >> 4].entry_ptr >> 16; + ret = dev->sgd[addr >> 4].entry_ptr >> 16; break; case 0x7: - ret = dev->sgd[modem][addr >> 4].entry_ptr >> 24; + ret = dev->sgd[addr >> 4].entry_ptr >> 24; break; case 0xc: - ret = dev->sgd[modem][addr >> 4].sample_count; + ret = dev->sgd[addr >> 4].sample_count; break; case 0xd: - ret = dev->sgd[modem][addr >> 4].sample_count >> 8; + ret = dev->sgd[addr >> 4].sample_count >> 8; break; case 0xe: - ret = dev->sgd[modem][addr >> 4].sample_count >> 16; + ret = dev->sgd[addr >> 4].sample_count >> 16; break; default: - ret = dev->sgd_regs[modem][addr]; + ret = dev->sgd_regs[addr]; break; } } else { /* Process regular registers. */ switch (addr) { case 0x84: - ret = (dev->sgd_regs[modem][0x00] & 0x01); - ret |= (dev->sgd_regs[modem][0x10] & 0x01) << 1; - ret |= (dev->sgd_regs[modem][0x20] & 0x01) << 2; + ret = (dev->sgd_regs[0x00] & 0x01); + ret |= (dev->sgd_regs[0x10] & 0x01) << 1; + ret |= (dev->sgd_regs[0x20] & 0x01) << 2; - ret |= (dev->sgd_regs[modem][0x00] & 0x02) << 3; - ret |= (dev->sgd_regs[modem][0x10] & 0x02) << 4; - ret |= (dev->sgd_regs[modem][0x20] & 0x02) << 5; + ret |= (dev->sgd_regs[0x00] & 0x02) << 3; + ret |= (dev->sgd_regs[0x10] & 0x02) << 4; + ret |= (dev->sgd_regs[0x20] & 0x02) << 5; break; case 0x85: - ret = (dev->sgd_regs[modem][0x00] & 0x04) >> 2; - ret |= (dev->sgd_regs[modem][0x10] & 0x04) >> 1; - ret |= (dev->sgd_regs[modem][0x20] & 0x04); + ret = (dev->sgd_regs[0x00] & 0x04) >> 2; + ret |= (dev->sgd_regs[0x10] & 0x04) >> 1; + ret |= (dev->sgd_regs[0x20] & 0x04); - ret |= (dev->sgd_regs[modem][0x00] & 0x80) >> 3; - ret |= (dev->sgd_regs[modem][0x10] & 0x80) >> 2; - ret |= (dev->sgd_regs[modem][0x20] & 0x80) >> 1; + ret |= (dev->sgd_regs[0x00] & 0x80) >> 3; + ret |= (dev->sgd_regs[0x10] & 0x80) >> 2; + ret |= (dev->sgd_regs[0x20] & 0x80) >> 1; break; case 0x86: - ret = (dev->sgd_regs[modem][0x40] & 0x01); - ret |= (dev->sgd_regs[modem][0x50] & 0x01) << 1; + ret = (dev->sgd_regs[0x40] & 0x01); + ret |= (dev->sgd_regs[0x50] & 0x01) << 1; - ret |= (dev->sgd_regs[modem][0x40] & 0x02) << 3; - ret |= (dev->sgd_regs[modem][0x50] & 0x02) << 4; + ret |= (dev->sgd_regs[0x40] & 0x02) << 3; + ret |= (dev->sgd_regs[0x50] & 0x02) << 4; break; case 0x87: - ret = (dev->sgd_regs[modem][0x40] & 0x04) >> 2; - ret |= (dev->sgd_regs[modem][0x50] & 0x04) >> 1; + ret = (dev->sgd_regs[0x40] & 0x04) >> 2; + ret |= (dev->sgd_regs[0x50] & 0x04) >> 1; - ret |= (dev->sgd_regs[modem][0x40] & 0x80) >> 3; - ret |= (dev->sgd_regs[modem][0x50] & 0x80) >> 2; + ret |= (dev->sgd_regs[0x40] & 0x80) >> 3; + ret |= (dev->sgd_regs[0x50] & 0x80) >> 2; break; default: - ret = dev->sgd_regs[modem][addr]; + ret = dev->sgd_regs[addr]; break; } } @@ -304,7 +297,7 @@ ac97_via_sgd_read(uint16_t addr, void *priv) return ret; } -void +static void ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; @@ -328,42 +321,42 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 0xf) { case 0x0: /* Clear RWC status bits. */ - dev->sgd_regs[modem][addr] &= ~(val & 0x07); + dev->sgd_regs[addr] &= ~(val & 0x07); /* Update status interrupts. */ - ac97_via_update_irqs(dev, modem); + ac97_via_update_irqs(dev); return; case 0x1: /* Start SGD if requested. */ if (val & 0x80) { - if (dev->sgd_regs[modem][addr & 0xf0] & 0x80) { + if (dev->sgd_regs[addr & 0xf0] & 0x80) { /* Queue SGD trigger if already running. */ - dev->sgd_regs[modem][addr & 0xf0] |= 0x08; + dev->sgd_regs[addr & 0xf0] |= 0x08; } else { /* Start SGD immediately. */ - dev->sgd_regs[modem][addr & 0xf0] = (dev->sgd_regs[modem][addr & 0xf0] & ~0x47) | 0x80; + dev->sgd_regs[addr & 0xf0] = (dev->sgd_regs[addr & 0xf0] & ~0x47) | 0x80; /* Start at the specified entry pointer. */ - dev->sgd[modem][addr >> 4].entry_ptr = AS_U32(dev->sgd_regs[modem][(addr & 0xf0) | 0x4]) & 0xfffffffe; - dev->sgd[modem][addr >> 4].restart = 2; + dev->sgd[addr >> 4].entry_ptr = AS_U32(dev->sgd_regs[(addr & 0xf0) | 0x4]) & 0xfffffffe; + dev->sgd[addr >> 4].restart = 2; /* Start the actual SGD process. */ - ac97_via_sgd_process(&dev->sgd[modem][addr >> 4]); + ac97_via_sgd_process(&dev->sgd[addr >> 4]); } } /* Stop SGD if requested. */ if (val & 0x40) - dev->sgd_regs[modem][addr & 0xf0] &= ~0x88; + dev->sgd_regs[addr & 0xf0] &= ~0x88; val &= 0x08; /* (Un)pause SGD if requested. */ if (val & 0x08) - dev->sgd_regs[modem][addr & 0xf0] |= 0x40; + dev->sgd_regs[addr & 0xf0] |= 0x40; else - dev->sgd_regs[modem][addr & 0xf0] &= ~0x40; + dev->sgd_regs[addr & 0xf0] &= ~0x40; break; @@ -391,55 +384,114 @@ ac97_via_sgd_write(uint16_t addr, uint8_t val, void *priv) case 0x82: /* Determine the selected codec. */ - i = !!(dev->sgd_regs[modem][0x83] & 0x40); - codec = dev->codec[modem][i]; + i = !!(dev->sgd_regs[0x83] & 0x40); + codec = dev->codec[i]; /* Keep value in register if this codec is not present. */ if (codec) { + /* Set audio and modem codecs according to type. */ + if (codec->regs[0x3c >> 1]) { + if (!dev->modem_codec) { + dev->modem_codec = codec; + if (val & 0x80) + ac97_via_update_codec(dev); + } + /* Start modem pollers. */ + if (!dev->modem_enabled) { + dev->modem_enabled = 1; + timer_advance_u64(&dev->sgd[4].poll_timer, dev->sgd[4].timer_latch); + timer_advance_u64(&dev->sgd[5].poll_timer, dev->sgd[5].timer_latch); + } + } else if (!dev->audio_codec) { + dev->audio_codec = codec; + if (val & 0x80) + ac97_via_update_codec(dev); + } + /* Read from or write to codec. */ if (val & 0x80) { - if (val & 1) { /* return 0x0000 on unaligned reads (real 686B behavior) */ - dev->sgd_regs[modem][0x80] = dev->sgd_regs[modem][0x81] = 0x00; - } else { - AS_U16(dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = AS_U16(dev->sgd_regs[modem][0x80]) = ac97_codec_readw(codec, val); - } + if (val & 1) /* return 0x0000 on unaligned reads (real 686B behavior) */ + AS_U16(dev->sgd_regs[0x80]) = 0x0000; + else + AS_U16(dev->codec_shadow[(i << 7) | (val & 0x7f)]) = AS_U16(dev->sgd_regs[0x80]) = ac97_codec_readw(codec, val); /* Flag data/status/index for this codec as valid. */ - dev->sgd_regs[modem][0x83] |= 0x02 << (i << 1); + dev->sgd_regs[0x83] |= 0x02 << (i << 1); } else if (!(val & 1)) { /* do nothing on unaligned writes */ ac97_codec_writew(codec, val, - AS_U16(dev->codec_shadow[modem].regs_codec[i][val & 0x7f]) = AS_U16(dev->sgd_regs[modem][0x80])); + AS_U16(dev->codec_shadow[(i << 7) | val]) = AS_U16(dev->sgd_regs[0x80])); - /* Update primary audio codec state if that codec was written to. */ - if (!modem && !i) { - ac97_via_update_codec(dev, 0); + /* Update audio codec state. */ + ac97_via_update_codec(dev); - /* Set up CD audio filter if CD volume was written to. Setting it - up at init prevents CD audio from working on other cards, but - this works as the CD channel is muted by default per AC97 spec. */ - if (val == 0x12) - sound_set_cd_audio_filter(ac97_via_filter_cd_audio, dev); - } + /* Set up CD audio filter if CD volume was written to. Setting it + up at init prevents CD audio from working on other cards, but + this works as the CD channel is muted by default per AC97 spec. */ + if (!i && (val == 0x12)) + sound_set_cd_audio_filter(ac97_via_filter_cd_audio, dev); } } - break; case 0x83: /* Clear RWC status bits. */ -#if 0 /* race condition with Linux accessing a register and clearing status bits on the same dword write */ - val = ((dev->sgd_regs[modem][addr] & 0x3f) & ~(val & 0x0a)) | (val & 0xc0); -#else - val = (dev->sgd_regs[modem][addr] & 0x3f) | (val & 0xc0); -#endif + val = ((dev->sgd_regs[addr] & 0x3f) & ~(val & 0x0a)) | (val & 0xc0); + break; + + case 0x88 ... 0x89: + dev->sgd_regs[addr] = val; + + /* Send GPO to codec. */ + for (uint8_t i = 0; i < (sizeof(dev->codec) / sizeof(dev->codec[0])); i++) { + if (dev->codec[i]) + ac97_codec_setgpo(dev->codec[i], AS_U16(dev->sgd_regs[0x88])); + } + return; + + case 0x8a ... 0x8b: + /* Clear RWC status bits. */ + val = dev->sgd_regs[addr] & ~val; break; + case 0x8c ... 0x8d: + return; + default: break; } } - dev->sgd_regs[modem][addr] = val; + dev->sgd_regs[addr] = val; +} + +static void +ac97_via_sgd_writew(uint16_t addr, uint16_t val, void *priv) +{ + if ((addr & 0xfe) == 0x82) { + /* Invert order on writes to 82-83 to ensure the correct codec ID is set and + any status bits are cleared before performing the codec register operation. */ + ac97_via_sgd_write(addr + 1, val >> 8, priv); + ac97_via_sgd_write(addr, val & 0xff, priv); + } else { + ac97_via_sgd_write(addr, val & 0xff, priv); + ac97_via_sgd_write(addr + 1, val >> 8, priv); + } +} + +static void +ac97_via_sgd_writel(uint16_t addr, uint32_t val, void *priv) +{ + ac97_via_sgd_write(addr, val & 0xff, priv); + ac97_via_sgd_write(addr + 1, val >> 8, priv); + if ((addr & 0xfc) == 0x80) { + /* Invert order on writes to 82-83 to ensure the correct codec ID is set and + any status bits are cleared before performing the codec register operation. */ + ac97_via_sgd_write(addr + 3, val >> 24, priv); + ac97_via_sgd_write(addr + 2, val >> 16, priv); + } else { + ac97_via_sgd_write(addr + 2, val >> 16, priv); + ac97_via_sgd_write(addr + 3, val >> 24, priv); + } } void @@ -448,12 +500,12 @@ ac97_via_remap_audio_sgd(void *priv, uint16_t new_io_base, uint8_t enable) ac97_via_t *dev = (ac97_via_t *) priv; if (dev->audio_sgd_base) - io_removehandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_removehandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, ac97_via_sgd_writew, ac97_via_sgd_writel, dev); dev->audio_sgd_base = new_io_base; if (dev->audio_sgd_base && enable) - io_sethandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_sethandler(dev->audio_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, ac97_via_sgd_writew, ac97_via_sgd_writel, dev); } void @@ -462,26 +514,26 @@ ac97_via_remap_modem_sgd(void *priv, uint16_t new_io_base, uint8_t enable) ac97_via_t *dev = (ac97_via_t *) priv; if (dev->modem_sgd_base) - io_removehandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_removehandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, ac97_via_sgd_writew, ac97_via_sgd_writel, dev); dev->modem_sgd_base = new_io_base; if (dev->modem_sgd_base && enable) - io_sethandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, NULL, NULL, dev); + io_sethandler(dev->modem_sgd_base, 256, ac97_via_sgd_read, NULL, NULL, ac97_via_sgd_write, ac97_via_sgd_writew, ac97_via_sgd_writel, dev); } uint8_t ac97_via_codec_read(uint16_t addr, void *priv) { const ac97_via_t *dev = (ac97_via_t *) priv; +#ifdef ENABLE_AC97_VIA_LOG uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; +#endif uint8_t ret = 0xff; addr &= 0xff; - ret = dev->codec_shadow[modem].regs_linear[addr]; - - ac97_via_log("AC97 VIA %d: codec_read(%02X) = %02X\n", modem, addr, ret); + ret = dev->codec_shadow[addr]; ac97_via_log("[%04X:%08X] [%i] AC97 VIA %d: codec_read(%02X) = %02X\n", CS, cpu_state.pc, msw & 1, modem, addr, ret); @@ -492,15 +544,15 @@ void ac97_via_codec_write(uint16_t addr, uint8_t val, void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; +#ifdef ENABLE_AC97_VIA_LOG uint8_t modem = (addr & 0xff00) == dev->modem_codec_base; +#endif addr &= 0xff; ac97_via_log("[%04X:%08X] [%i] AC97 VIA %d: codec_write(%02X, %02X)\n", CS, cpu_state.pc, msw & 1, modem, addr, val); - ac97_via_log("AC97 VIA %d: codec_write(%02X, %02X)\n", modem, addr, val); - /* Unknown behavior, maybe it does write to the shadow registers? */ - dev->codec_shadow[modem].regs_linear[addr] = val; + dev->codec_shadow[addr] = val; } void @@ -564,7 +616,7 @@ ac97_via_sgd_process(void *priv) ac97_via_t *dev = sgd->dev; /* Stop if this SGD is not active. */ - uint8_t sgd_status = dev->sgd_regs[sgd->modem][sgd->id] & 0xc4; + uint8_t sgd_status = dev->sgd_regs[sgd->id] & 0xc4; if (!(sgd_status & 0x80)) return; @@ -577,7 +629,7 @@ ac97_via_sgd_process(void *priv) if (sgd->restart) { /* (Re)load entry pointer if required. */ if (sgd->restart & 2) - sgd->entry_ptr = AS_U32(dev->sgd_regs[sgd->modem][sgd->id | 0x4]) & 0xfffffffe; /* TODO: probe real hardware - does "even addr" actually mean dword aligned? */ + sgd->entry_ptr = AS_U32(dev->sgd_regs[sgd->id | 0x4]) & 0xfffffffe; /* TODO: probe real hardware - does "even addr" actually mean dword aligned? */ sgd->restart = 0; /* Read entry. */ @@ -625,17 +677,17 @@ ac97_via_sgd_process(void *priv) ac97_via_log(" with STOP"); /* Raise STOP to pause SGD. */ - dev->sgd_regs[sgd->modem][sgd->id] |= 0x04; + dev->sgd_regs[sgd->id] |= 0x04; } if (sgd->entry_flags & 0x40) { ac97_via_log(" with FLAG"); /* Raise FLAG to pause SGD. */ - dev->sgd_regs[sgd->modem][sgd->id] |= 0x01; + dev->sgd_regs[sgd->id] |= 0x01; #ifdef ENABLE_AC97_VIA_LOG - if (dev->sgd_regs[sgd->modem][sgd->id | 0x2] & 0x01) + if (dev->sgd_regs[sgd->id | 0x2] & 0x01) ac97_via_log(" interrupt"); #endif } @@ -644,19 +696,19 @@ ac97_via_sgd_process(void *priv) ac97_via_log(" with EOL"); /* Raise EOL. */ - dev->sgd_regs[sgd->modem][sgd->id] |= 0x02; + dev->sgd_regs[sgd->id] |= 0x02; #ifdef ENABLE_AC97_VIA_LOG - if (dev->sgd_regs[sgd->modem][sgd->id | 0x2] & 0x02) + if (dev->sgd_regs[sgd->id | 0x2] & 0x02) ac97_via_log(" interrupt"); #endif /* Restart SGD if a trigger is queued or auto-start is enabled. */ - if ((dev->sgd_regs[sgd->modem][sgd->id] & 0x08) || (dev->sgd_regs[sgd->modem][sgd->id | 0x2] & 0x80)) { + if ((dev->sgd_regs[sgd->id] & 0x08) || (dev->sgd_regs[sgd->id | 0x2] & 0x80)) { ac97_via_log(" restart"); /* Un-queue trigger. */ - dev->sgd_regs[sgd->modem][sgd->id] &= ~0x08; + dev->sgd_regs[sgd->id] &= ~0x08; /* Go back to the starting block on the next run. */ sgd->restart = 2; @@ -664,13 +716,13 @@ ac97_via_sgd_process(void *priv) ac97_via_log(" finish"); /* Terminate SGD. */ - dev->sgd_regs[sgd->modem][sgd->id] &= ~0x80; + dev->sgd_regs[sgd->id] &= ~0x80; } } ac97_via_log("\n"); /* Fire any requested status interrupts. */ - ac97_via_update_irqs(dev, sgd->modem); + ac97_via_update_irqs(dev); } } } @@ -678,8 +730,8 @@ ac97_via_sgd_process(void *priv) static void ac97_via_poll_stereo(void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - ac97_via_sgd_t *sgd = &dev->sgd[0][0]; /* Audio Read */ + ac97_via_sgd_t *sgd = (ac97_via_sgd_t *) priv; + ac97_via_t *dev = sgd->dev; /* Schedule next run if PCM playback is enabled. */ if (dev->pcm_enabled) @@ -689,7 +741,7 @@ ac97_via_poll_stereo(void *priv) ac97_via_update_stereo(dev, sgd); /* Feed next sample from the FIFO. */ - switch (dev->sgd_regs[0][sgd->id | 0x2] & 0x30) { + switch (dev->sgd_regs[sgd->id | 0x2] & 0x30) { case 0x00: /* Mono, 8-bit PCM */ if ((sgd->fifo_end - sgd->fifo_pos) >= 1) { sgd->out_l = sgd->out_r = (sgd->fifo[sgd->fifo_pos++ & (sizeof(sgd->fifo) - 1)] ^ 0x80) << 8; @@ -734,8 +786,8 @@ ac97_via_poll_stereo(void *priv) static void ac97_via_poll_fm(void *priv) { - ac97_via_t *dev = (ac97_via_t *) priv; - ac97_via_sgd_t *sgd = &dev->sgd[0][2]; /* FM Read */ + ac97_via_sgd_t *sgd = (ac97_via_sgd_t *) priv; + ac97_via_t *dev = sgd->dev; /* Schedule next run if FM playback is enabled. */ if (dev->fm_enabled) @@ -758,20 +810,65 @@ ac97_via_poll_fm(void *priv) sgd->out_l = sgd->out_r = 0; } +static void +ac97_via_poll_modem(void *priv) +{ + ac97_via_sgd_t *sgd = (ac97_via_sgd_t *) priv; + ac97_via_t *dev = sgd->dev; + + /* Schedule next run if modem playback/capture is enabled. */ + if (dev->modem_enabled) + timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); + + /* Update modem audio buffer. */ + ac97_via_update_stereo(dev, sgd); + + /* Feed next sample from the FIFO. + The data format is not documented, but it probes as 16-bit mono at the codec sample rate. */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { + sgd->out_l = sgd->out_r = AS_I16(sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]); + sgd->fifo_pos += 2; + return; + } + + /* Feed silence if the FIFO is empty. */ + sgd->out_l = sgd->out_r = 0; +} + +static void +ac97_via_poll_modem_capture(void *priv) +{ + ac97_via_sgd_t *sgd = (ac97_via_sgd_t *) priv; + ac97_via_t *dev = sgd->dev; + + /* Schedule next run if modem playback/capture is enabled. */ + if (dev->modem_enabled) + timer_advance_u64(&sgd->poll_timer, sgd->timer_latch); + + /* Feed next sample into the FIFO. + The data format is not documented, but it probes as 16-bit mono at the codec sample rate. */ + if ((sgd->fifo_end - sgd->fifo_pos) >= 2) { + AS_I16(sgd->fifo[sgd->fifo_pos & (sizeof(sgd->fifo) - 1)]) = 0; + sgd->fifo_pos += 2; + } +} + static void ac97_via_get_buffer(int32_t *buffer, int len, void *priv) { ac97_via_t *dev = (ac97_via_t *) priv; - ac97_via_update_stereo(dev, &dev->sgd[0][0]); - ac97_via_update_stereo(dev, &dev->sgd[0][2]); + ac97_via_update_stereo(dev, &dev->sgd[0]); + ac97_via_update_stereo(dev, &dev->sgd[2]); + ac97_via_update_stereo(dev, &dev->sgd[4]); for (int c = 0; c < len * 2; c++) { - buffer[c] += dev->sgd[0][0].buffer[c] / 2; - buffer[c] += dev->sgd[0][2].buffer[c] / 2; + buffer[c] += dev->sgd[0].buffer[c] / 2; + buffer[c] += dev->sgd[2].buffer[c] / 2; + buffer[c] += dev->sgd[4].buffer[c] / 2; } - dev->sgd[0][0].pos = dev->sgd[0][2].pos = 0; + dev->sgd[0].pos = dev->sgd[2].pos = dev->sgd[4].pos = 0; } static void @@ -792,13 +889,20 @@ ac97_via_speed_changed(void *priv) double freq; /* Get variable sample rate if enabled. */ - if (dev->vsr_enabled && dev->codec[0][0]) - freq = ac97_codec_getrate(dev->codec[0][0], 0x2c); + if (dev->vsr_enabled && dev->audio_codec) + freq = ac97_codec_getrate(dev->audio_codec, 0x2c); + else + freq = (double) SOUND_FREQ; + + dev->sgd[0].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / freq)); + dev->sgd[2].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 24000.0)); /* FM operates at a fixed 24 KHz */ + + if (dev->modem_codec) + freq = ac97_codec_getrate(dev->modem_codec, 0x40); else freq = (double) SOUND_FREQ; - dev->sgd[0][0].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / freq)); - dev->sgd[0][2].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / 24000.0)); /* FM operates at a fixed 24 KHz */ + dev->sgd[4].timer_latch = dev->sgd[5].timer_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / freq)); } static void * @@ -809,30 +913,27 @@ ac97_via_init(UNUSED(const device_t *info)) ac97_via_log("AC97 VIA: init()\n"); /* Set up codecs. */ - ac97_codec = &dev->codec[0][0]; - ac97_modem_codec = &dev->codec[1][0]; - ac97_codec_count = ac97_modem_codec_count = sizeof(dev->codec[0]) / sizeof(dev->codec[0][0]); - ac97_codec_id = ac97_modem_codec_id = 0; + ac97_codec = &dev->codec[0]; + ac97_codec_count = sizeof(dev->codec) / sizeof(dev->codec[0]); + ac97_codec_id = 0; /* Set up SGD channels. */ for (uint8_t i = 0; i < (sizeof(dev->sgd) / sizeof(dev->sgd[0])); i++) { - for (uint8_t j = 0; j < 2; j++) { - dev->sgd[j][i].id = i << 4; - dev->sgd[j][i].dev = dev; + dev->sgd[i].id = i << 4; + dev->sgd[i].dev = dev; - dev->sgd[j][i].modem = j; + /* Disable the FIFO on SGDs we don't care about. */ + if ((i != 0) && (i != 2) && (i != 4) && (i != 5)) + dev->sgd[i].always_run = 1; - /* Disable the FIFO on SGDs we don't care about. */ - if ((i != 0) && (i != 2)) - dev->sgd[j][i].always_run = 1; - - timer_add(&dev->sgd[j][i].dma_timer, ac97_via_sgd_process, &dev->sgd[j][i], 0); - } + timer_add(&dev->sgd[i].dma_timer, ac97_via_sgd_process, &dev->sgd[i], 0); } /* Set up playback pollers. */ - timer_add(&dev->sgd[0][0].poll_timer, ac97_via_poll_stereo, dev, 0); - timer_add(&dev->sgd[0][2].poll_timer, ac97_via_poll_fm, dev, 0); + timer_add(&dev->sgd[0].poll_timer, ac97_via_poll_stereo, &dev->sgd[0], 0); + timer_add(&dev->sgd[2].poll_timer, ac97_via_poll_fm, &dev->sgd[2], 0); + timer_add(&dev->sgd[4].poll_timer, ac97_via_poll_modem, &dev->sgd[4], 0); + timer_add(&dev->sgd[5].poll_timer, ac97_via_poll_modem_capture, &dev->sgd[5], 0); ac97_via_speed_changed(dev); /* Set up playback handler. */ diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 6c32b18929b..44e328842db 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -300,7 +300,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 3) { case 0: /* Index */ - if ((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) + if (((ad1848->regs[12] & 0x40) && (ad1848->type >= AD1848_TYPE_CS4231)) || ((ad1848->type == AD1848_TYPE_OPTI930) && (ad1848->opti930_mode2))) ad1848->index = val & 0x1f; /* cs4231a extended mode enabled */ else ad1848->index = val & 0x0f; /* ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? */ @@ -344,7 +344,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) case 12: if (ad1848->type >= AD1848_TYPE_CS4248) { - ad1848->regs[12] = 0x80 | (val & 0x70) | (ad1848->regs[12] & 0x0f); + ad1848->regs[12] = 0x80 | (val & 0x60) | (ad1848->regs[12] & 0x0f); if ((ad1848->type >= AD1848_TYPE_CS4231) && (ad1848->type < AD1848_TYPE_CS4235)) { if (val & 0x40) ad1848->fmt_mask |= 0x80; @@ -425,6 +425,19 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848->fm_vol_r = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; } } + if ((ad1848->type >= AD1848_TYPE_CS4232) && (ad1848->type <= AD1848_TYPE_CS4236)) { + if (ad1848->index == 18) { + if (val & 0x80) + ad1848->fm_vol_l = 0; + else + ad1848->fm_vol_l = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; + } else { + if (val & 0x80) + ad1848->fm_vol_r = 0; + else + ad1848->fm_vol_r = (int) ad1848_vols_5bits_aux_gain[val & 0x1f]; + } + } break; case 20 ... 21: @@ -508,6 +521,8 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) } if (ad1848->type == AD1848_TYPE_CS4231) /* I23 is reserved and read-only on CS4231 non-A */ goto readonly_i; + if ((ad1848->type >= AD1848_TYPE_CS4232) && (ad1848->type <= AD1848_TYPE_CS4236)) /* I23 bits 7-1 are read-only on CS4231A/4232/4236 non-B, Win2k relies on this for detection */ + val = (val & 0x01); break; case 24: @@ -801,7 +816,7 @@ ad1848_set_cd_audio_channel(void *priv, int channel) { ad1848_t *ad1848 = (ad1848_t *) priv; - const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15; + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : (ad1848->type == AD1848_TYPE_OPTI930) ? 19 : 15; if (channel > max_channel) channel = max_channel; @@ -824,7 +839,7 @@ ad1848_filter_channel(void *priv, int channel, double *out_l, double *out_r) { const ad1848_t *ad1848 = (ad1848_t *) priv; - const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15; + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : (ad1848->type == AD1848_TYPE_OPTI930) ? 19 : 15; if (channel > max_channel) channel = max_channel; @@ -865,7 +880,13 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->regs[13] = 0; ad1848->regs[14] = ad1848->regs[15] = 0; - if (type == AD1848_TYPE_CS4231) { + if (type == AD1848_TYPE_OPTI930) { + ad1848->regs[18] = ad1848->regs[19] = 0x88; /* LINE volume */ + ad1848->regs[20] = ad1848->regs[21] = 0x84; /* OPTi 930 MIC volume */ + ad1848->regs[22] = ad1848->regs[23] = 0x84; /* OPTi 930 master volume */ + ad1848->regs[24] = 0; + ad1848->regs[25] = 0; + } else if (type == AD1848_TYPE_CS4231) { ad1848->regs[16] = ad1848->regs[17] = 0; ad1848->regs[18] = ad1848->regs[19] = 0x88; ad1848->regs[22] = 0x80; diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 1f88db71951..3eebf616e02 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -189,7 +189,6 @@ static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; typedef struct azt2316a_t { int type; - int wss_interrupt_after_config; uint8_t wss_config; @@ -248,13 +247,13 @@ azt2316a_wss_write(uint16_t addr, uint8_t val, void *priv) { azt2316a_t *azt2316a = (azt2316a_t *) priv; int interrupt = 0; + uint8_t oldconfig = azt2316a->wss_config; aztech_log(azt2316a->log, "Aztech WSS: [W] (%04X) = %02X\n", addr, val); - if (azt2316a->wss_interrupt_after_config) { - if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) { // TODO: is this the right edge? - interrupt = 1; - } + if ((oldconfig & 0x40) != (val & 0x40)) { + aztech_log(azt2316a->log, "Aztech WSS: Config IRQ bit changed\n"); + interrupt = 1; } azt2316a->wss_config = val; @@ -263,8 +262,15 @@ azt2316a_wss_write(uint16_t addr, uint8_t val, void *priv) ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); - if (interrupt) - picint(1 << azt2316a->cur_wss_irq); + if (interrupt) { + if (azt2316a->wss_config & 0x40) { + aztech_log(azt2316a->log, "Aztech WSS: Firing config change IRQ\n"); + picint(1 << azt2316a->cur_wss_irq); + } else { + aztech_log(azt2316a->log, "Aztech WSS: Clearing config change IRQ\n"); + picintc(1 << azt2316a->cur_wss_irq); + } + } } /* generate a config word based on current settings */ @@ -1040,10 +1046,20 @@ azt2316a_enable_wss(uint8_t enable, void *priv) { azt2316a_t *azt2316a = (azt2316a_t *) priv; - if (enable) + sound_set_cd_audio_filter(NULL, NULL); + + if (enable) { azt2316a->cur_mode = 1; - else + sound_set_cd_audio_filter(ad1848_filter_cd_audio, &azt2316a->ad1848); + azt2316a->sb->opl_mixer = azt2316a; + azt2316a->sb->opl_mix = azt1605_filter_opl; + } + else { azt2316a->cur_mode = 0; + sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb); + azt2316a->sb->opl_mixer = NULL; + azt2316a->sb->opl_mix = NULL; + } } static void @@ -1306,8 +1322,6 @@ azt_init(const device_t *info) if (addr_setting) azt2316a->cur_addr = addr_setting; - azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); - /* wss part */ ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); if (azt2316a->type == SB_SUBTYPE_CLONE_AZT2316A_0X11) @@ -1453,7 +1467,7 @@ static const device_config_t azt1605_config[] = { // clang-format off { .name = "codec", - .description = "CODEC", + .description = "Codec", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = AD1848_TYPE_CS4248, @@ -1466,17 +1480,6 @@ static const device_config_t azt1605_config[] = { }, .bios = { { 0 } } }, - { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { { 0 } }, - .bios = { { 0 } } - }, { .name = "addr", .description = "SB Address", @@ -1582,7 +1585,7 @@ static const device_config_t azt2316a_config[] = { // clang-format off { .name = "codec", - .description = "CODEC", + .description = "Codec", .type = CONFIG_SELECTION, .default_string = NULL, .default_int = AD1848_TYPE_CS4248, @@ -1595,17 +1598,6 @@ static const device_config_t azt2316a_config[] = { }, .bios = { { 0 } } }, - { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_string = NULL, - .default_int = 0, - .file_filter = NULL, - .spinner = { 0 }, - .selection = { { 0 } }, - .bios = { { 0 } } - }, { .name = "addr", .description = "SB Address", diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 15ad717824c..4fd630e07c9 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -40,6 +40,7 @@ #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> +#define PNP_ROM_CS4232 "roms/sound/crystal/CS4232.BIN" #define PNP_ROM_CS4236B "roms/sound/crystal/PNPISA01.BIN" #define CRYSTAL_NOEEPROM 0x100 @@ -88,6 +89,20 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0 0x5E, 0xAF, 0x57, 0x2B, 0x15, 0x8A, 0xC5, 0xE2, 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; + +static const uint8_t cs4232_default[] = { + // clang-format off + /* Chip configuration */ + 0x00, /* external decode length */ + 0x48, /* reserved */ + 0x75, 0xb9, 0xfc, /* IRQ routing */ + 0x10, 0x03, /* DMA routing */ + + /* Default PnP data */ + 0x0e, 0x63, 0x42, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00 /* hinted by documentation to be just the header */ + // clang-format on +}; + static const uint8_t cs4236_default[] = { // clang-format off /* Chip configuration */ @@ -388,9 +403,17 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) case 6: /* RAM Access End */ /* TriGem Delhi-III BIOS writes undocumented value 0x40 instead of 0x00. */ - if ((val == 0x00) || (val == 0x40)) { + /* Intel Atlantis, Holly, Monaco, Morrison and Thor BIOSes use several undocumented values */ + /* 0x25, 0x60, 0x69, 0x86, 0xE2, 0xFE and 0xFF were observed on these BIOSes */ + /* CS4232 likely accepts any written value to end RAM writes */ + if ((val == 0x00) || (val == 0x40) || (dev->type == CRYSTAL_CS4232)) { cs423x_log("CS423x: RAM end\n"); dev->ram_dl = CRYSTAL_RAM_CMD; + /* CS4232 resource data at 0x2090/2091 is written backwards */ + if (dev->type == CRYSTAL_CS4232) { + dev->ram_data[0x2090] = 0x00; + dev->ram_data[0x2091] = 0x48; + } /* Update PnP state and resource data. */ dev->pnp_size = (dev->type >= CRYSTAL_CS4236) ? 384 : 256; /* we don't know the length */ @@ -568,7 +591,11 @@ cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv) { cs423x_t *dev = (cs423x_t *) priv; uint8_t ctx = (dev->regs[7] & 0x80); - uint8_t enable_opl = (dev->ad1848.xregs[4] & 0x10) && !(dev->indirect_regs[2] & 0x85); + uint8_t enable_opl = (dev->ad1848.xregs[4] & 0x10) && !(dev->indirect_regs[2] & 0x85); /* CS4236B+ */ + + /* CS4232/4236 (non-B) doesn't have an IFM bit, always enable the OPL on these chips */ + if (dev->type <= CRYSTAL_CS4236) + enable_opl = 1; /* Check if a context switch (WSS=1 <-> SBPro=0) occurred through the address being written. */ if ((dev->regs[7] & 0x80) ? ((addr & 0xfff0) == dev->sb_base) : ((addr & 0xfffc) == dev->wss_base)) { @@ -804,6 +831,10 @@ static void cs423x_load_defaults(cs423x_t *dev, uint8_t *dest) { switch (dev->type) { + case CRYSTAL_CS4232: + memcpy(dest, cs4232_default, sizeof(cs4232_default)); + dev->pnp_size = 9; /* header-only PnP ROM size */ + break; case CRYSTAL_CS4236: case CRYSTAL_CS4236B: case CRYSTAL_CS4237B: @@ -837,7 +868,11 @@ cs423x_reset(void *priv) memset(dev->ram_data, 0, sizeof(dev->ram_data)); /* Load default configuration data to RAM. */ - cs423x_load_defaults(dev, &dev->ram_data[0x4000]); + /* CS4232 uses 0x2090 as the initial RAM location instead of 0x4000 */ + if (dev->type == CRYSTAL_CS4232) + cs423x_load_defaults(dev, &dev->ram_data[0x2090]); + else + cs423x_load_defaults(dev, &dev->ram_data[0x4000]); if (dev->eeprom) { /* Load EEPROM data to RAM if the magic bytes are present. */ @@ -846,7 +881,10 @@ cs423x_reset(void *priv) dev->pnp_size = (dev->eeprom_data[2] << 8) | dev->eeprom_data[3]; if (dev->pnp_size > 384) dev->pnp_size = 384; - memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4); + if (dev->type == CRYSTAL_CS4232) + memcpy(&dev->ram_data[0x2090], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4); + else + memcpy(&dev->ram_data[0x4000], &dev->eeprom_data[4], sizeof(dev->eeprom_data) - 4); } else { cs423x_log("CS423x: EEPROM data invalid, ignoring\n"); } @@ -886,6 +924,7 @@ cs423x_init(const device_t *info) dev->type = info->local & 0xff; cs423x_log("CS423x: init(%02X)\n", dev->type); switch (dev->type) { + case CRYSTAL_CS4232: case CRYSTAL_CS4236: case CRYSTAL_CS4236B: case CRYSTAL_CS4237B: @@ -893,29 +932,46 @@ cs423x_init(const device_t *info) case CRYSTAL_CS4235: case CRYSTAL_CS4239: /* Different WSS codec families. */ - dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : AD1848_TYPE_CS4236); + dev->ad1848_type = (dev->type >= CRYSTAL_CS4235) ? AD1848_TYPE_CS4235 : ((dev->type >= CRYSTAL_CS4236B) ? AD1848_TYPE_CS4236B : (dev->type >= CRYSTAL_CS4236) ? AD1848_TYPE_CS4236 : AD1848_TYPE_CS4232); /* Different Chip Version and ID values (N/A on CS4236), which shouldn't be reset by ad1848_init. */ dev->ad1848.xregs[25] = dev->type; - /* Same EEPROM structure. */ - dev->pnp_offset = 0x4013; + /* Same EEPROM structure on CS4236+. CS4232 is different. */ + if (dev->type == CRYSTAL_CS4232) + dev->pnp_offset = 0x2097; + else + dev->pnp_offset = 0x4013; if (!(info->local & CRYSTAL_NOEEPROM)) { /* Start a new EEPROM with the default configuration data. */ cs423x_load_defaults(dev, &dev->eeprom_data[4]); /* Load PnP resource data ROM. */ - FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb"); - if (fp) { - uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4; - /* This is wrong. The header field only indicates PnP resource data length, and real chips use - it to locate the firmware patch area, but we don't need any of that, so we can get away - with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */ - dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp); - fclose(fp); + if (dev->type == CRYSTAL_CS4232) { + FILE *fp = rom_fopen(PNP_ROM_CS4232, "rb"); + if (fp) { + uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x0f) + 4; + /* This is wrong. The header field only indicates PnP resource data length, and real chips use + it to locate the firmware patch area, but we don't need any of that, so we can get away + with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */ + dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp); + fclose(fp); + } else { + dev->pnp_size = 0; + } } else { - dev->pnp_size = 0; + FILE *fp = rom_fopen(PNP_ROM_CS4236B, "rb"); + if (fp) { + uint16_t eeprom_pnp_offset = (dev->pnp_offset & 0x1ff) + 4; + /* This is wrong. The header field only indicates PnP resource data length, and real chips use + it to locate the firmware patch area, but we don't need any of that, so we can get away + with pretending the whole ROM is PnP data, at least until we can get full EEPROM dumps. */ + dev->pnp_size = fread(&dev->eeprom_data[eeprom_pnp_offset], 1, sizeof(dev->eeprom_data) - eeprom_pnp_offset, fp); + fclose(fp); + } else { + dev->pnp_size = 0; + } } /* Populate EEPROM header if the PnP ROM was loaded. */ @@ -928,6 +984,10 @@ cs423x_init(const device_t *info) /* Patch PnP ROM and set EEPROM file name. */ switch (dev->type) { + case CRYSTAL_CS4232: + dev->nvr_path = "cs4232.nvr"; + break; + case CRYSTAL_CS4236: if (dev->pnp_size) { dev->eeprom_data[26] = 0x36; @@ -1005,6 +1065,7 @@ cs423x_init(const device_t *info) /* Initialize SBPro codec. The WSS codec is initialized later by cs423x_reset */ dev->sb = device_add_inst(&sb_pro_compat_device, 1); sound_set_cd_audio_filter(sbpro_filter_cd_audio, dev->sb); /* CD audio filter for the default context */ + music_add_handler(sb_get_music_buffer_sbpro, dev->sb); /* Init the SBPro OPL3 since sb_pro_compat_init does not */ /* Initialize RAM, registers and WSS codec. */ cs423x_reset(dev); @@ -1037,6 +1098,12 @@ cs423x_close(void *priv) free(dev); } +static int +cs4232_available(void) +{ + return rom_present(PNP_ROM_CS4232); +} + static int cs423x_available(void) { @@ -1051,6 +1118,34 @@ cs423x_speed_changed(void *priv) ad1848_speed_changed(&dev->ad1848); } +const device_t cs4232_device = { + .name = "Crystal CS4232", + .internal_name = "cs4232", + .flags = DEVICE_ISA16, + .local = CRYSTAL_CS4232, + .init = cs423x_init, + .close = cs423x_close, + .reset = cs423x_reset, + .available = cs4232_available, + .speed_changed = cs423x_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t cs4232_onboard_device = { + .name = "Crystal CS4232 (On-Board)", + .internal_name = "cs4232_onboard", + .flags = DEVICE_ISA16, + .local = CRYSTAL_CS4232 | CRYSTAL_NOEEPROM, + .init = cs423x_init, + .close = cs423x_close, + .reset = cs423x_reset, + .available = cs423x_available, + .speed_changed = cs423x_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + const device_t cs4235_device = { .name = "Crystal CS4235", .internal_name = "cs4235", diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index c6f25aadfdc..6734b56cb5c 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -6,13 +6,15 @@ * * This file is part of the 86Box distribution. * - * OPTi MediaCHIPS 82C929A (also known as OPTi MAD16 Pro) audio controller emulation. + * OPTi MediaCHIPS 82C929A/82C930 (also known as OPTi MAD16 Pro) audio controller emulation. * * Authors: Cacodemon345 * Eluan Costa Miranda + * win2kgamer * * Copyright 2022 Cacodemon345. * Copyright 2020 Eluan Costa Miranda. + * Copyright 2025 win2kgamer */ #include #include @@ -36,9 +38,34 @@ #include <86box/mem.h> #include <86box/rom.h> #include <86box/plat_unused.h> +#include <86box/log.h> + +#ifdef ENABLE_OPTIMC_LOG +int optimc_do_log = ENABLE_OPTIMC_LOG; + +static void +optimc_log(void *priv, const char *fmt, ...) +{ + if (optimc_do_log) { + va_list ap; + va_start(ap, fmt); + log_out(priv, fmt, ap); + va_end(ap); + } +} +#else +# define optimc_log(fmt, ...) +#endif static int optimc_wss_dma[4] = { 0, 0, 1, 3 }; static int optimc_wss_irq[8] = { 5, 7, 9, 10, 11, 12, 14, 15 }; +static int opti930_wss_irq[8] = { 0, 7, 9, 10, 11, 5, 0, 0 }; +static double opti930_vols_5bits[32]; + +enum optimc_types { + OPTI_929 = 0xE3, + OPTI_930 = 0xE4, +}; enum optimc_local_flags { OPTIMC_CS4231 = 0x100, @@ -51,10 +78,13 @@ typedef struct optimc_t { uint8_t wss_config; uint8_t reg_enabled; + uint8_t passwd_enabled; + uint8_t index; uint16_t cur_addr; uint16_t cur_wss_addr; uint16_t cur_mpu401_addr; + uint16_t cur_opti930_addr; /* OPTi 930 relocatable index/data registers */ int cur_irq; int cur_dma; @@ -71,9 +101,60 @@ typedef struct optimc_t { mpu_t *mpu; sb_t *sb; - uint8_t regs[6]; + uint8_t regs[12]; + uint8_t opti930_mcbase; + uint8_t lastpw; + double master_l; + double master_r; + + void * log; /* New logging system */ } optimc_t, opti_82c929a_t; +static void +opti930_update_mastervol(void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + /* Master volume attenuation */ + if (optimc->ad1848.regs[22] & 0x80) + optimc->master_l = 0; + else + optimc->master_l = opti930_vols_5bits[optimc->ad1848.regs[22] & 0x1F] / 65536.0; + + if (optimc->ad1848.regs[23] & 0x80) + optimc->master_r = 0; + else + optimc->master_r = opti930_vols_5bits[optimc->ad1848.regs[23] & 0x1F] / 65536.0; +} + +void +opti930_filter_cd_audio(int channel, double *buffer, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + + opti930_update_mastervol(optimc); + + const double cd_vol = channel ? optimc->ad1848.cd_vol_r : optimc->ad1848.cd_vol_l; + double master = channel ? optimc->master_r : optimc->master_l; + double c = ((*buffer * cd_vol / 3.0) * master) / 65536.0; + + *buffer = c; +} + +static void +opti930_filter_opl(void *priv, double *out_l, double *out_r) +{ + optimc_t *optimc = (optimc_t *) priv; + + if (optimc->cur_wss_enabled) { + opti930_update_mastervol(optimc); + *out_l /= optimc->sb->mixer_sbpro.fm_l; + *out_r /= optimc->sb->mixer_sbpro.fm_r; + *out_l *= optimc->master_l; + *out_r *= optimc->master_r; + ad1848_filter_channel((void *) &optimc->ad1848, AD1848_AUX2, out_l, out_r); + } +} + static void optimc_filter_opl(void *priv, double *out_l, double *out_r) { @@ -91,9 +172,10 @@ optimc_wss_read(UNUSED(uint16_t addr), void *priv) { const optimc_t *optimc = (optimc_t *) priv; - if (!(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) + if (optimc->type == OPTI_929 && !(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) return 0xFF; + optimc_log(optimc->log, "OPTi WSS Read: val = %02X\n", ((optimc->wss_config & 0x40) | 4)); return 4 | (optimc->wss_config & 0x40); } @@ -102,11 +184,43 @@ optimc_wss_write(UNUSED(uint16_t addr), uint8_t val, void *priv) { optimc_t *optimc = (optimc_t *) priv; - if (!(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) + optimc_log(optimc->log, "OPTi WSS Write: val = %02X\n", val); + if (optimc->type == OPTI_929 && !(optimc->regs[4] & 0x10) && optimc->cur_mode == 0) return; optimc->wss_config = val; ad1848_setdma(&optimc->ad1848, optimc_wss_dma[val & 3]); - ad1848_setirq(&optimc->ad1848, optimc_wss_irq[(val >> 3) & 7]); + if (optimc->type == OPTI_929) + ad1848_setirq(&optimc->ad1848, optimc_wss_irq[(val >> 3) & 7]); + else + ad1848_setirq(&optimc->ad1848, opti930_wss_irq[(val >> 3) & 7]); +} + +static void +opti930_get_buffer(int32_t *buffer, int len, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + + if (optimc->regs[3] & 0x4) + return; + + /* wss part */ + opti930_update_mastervol(optimc); + ad1848_update(&optimc->ad1848); + for (int c = 0; c < len * 2; c++) { + double out_l = 0.0; + double out_r = 0.0; + + out_l = (optimc->ad1848.buffer[c] * optimc->master_l); + out_r = (optimc->ad1848.buffer[c + 1] * optimc->master_r); + + buffer[c] += (int32_t) out_l; + buffer[c + 1] += (int32_t) out_r; + } + + optimc->ad1848.pos = 0; + + /* sbprov2 part */ + sb_get_buffer_sbpro(buffer, len, optimc->sb); } static void @@ -145,6 +259,198 @@ optimc_add_opl(optimc_t *optimc) io_sethandler(0x0388, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); } +static void +opti930_reg_write(uint16_t addr, uint8_t val, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + uint16_t idx = optimc->index; + uint8_t old = optimc->regs[idx]; + + if ((addr == optimc->cur_opti930_addr) && (optimc->reg_enabled || !optimc->passwd_enabled)) { + optimc_log(optimc->log, "OPTi930 Index Write: val = %02X\n", val); + optimc->index = (val - 1); + } + if ((addr == optimc->cur_opti930_addr +1) && (optimc->reg_enabled || !optimc->passwd_enabled)) { + switch (idx) { + case 0: /* MC1 */ + optimc->regs[0] = val; + if (val != old) { + /* Update SBPro address */ + io_removehandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); + optimc_remove_opl(optimc); + optimc->cur_addr = (val & 0x80) ? 0x240 : 0x220; + sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr); + optimc_add_opl(optimc); + io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); + /* Update WSS address */ + io_removehandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); + io_removehandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); + switch ((val >> 4) & 0x3) { + case 0: /* WSBase = 0x530 */ + optimc->cur_wss_addr = 0x530; + break; + case 1: /* WSBase = 0xE80 */ + optimc->cur_wss_addr = 0xE80; + break; + case 2: /* WSBase = 0xF40 */ + optimc->cur_wss_addr = 0xF40; + break; + case 3: /* WSBase = 0x604 */ + optimc->cur_wss_addr = 0x604; + break; + + default: + break; + } + io_sethandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); + io_sethandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); + /* Update gameport */ + gameport_remap(optimc->gameport, (optimc->regs[0] & 0x1) ? 0x00 : 0x200); + } + break; + case 1: /* MC2 */ + optimc->regs[1] = val; + break; + case 2: /* MC3 */ + optimc->regs[2] = val; + if (val != old) { + switch (val & 0x3) { + case 0: + break; + case 1: + optimc->cur_dma = 0; + break; + case 2: + optimc->cur_dma = 1; + break; + case 3: + optimc->cur_dma = 3; + break; + } + switch ((val >> 3) & 0x7) { + case 0: + break; + case 1: + optimc->cur_irq = 7; + break; + case 2: + optimc->cur_irq = 9; + break; + case 3: + optimc->cur_irq = 10; + break; + case 4: + optimc->cur_irq = 11; + break; + case 5: + default: + optimc->cur_irq = 5; + break; + } + sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq); + sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); + /* Writes here also set WSS IRQ/DMA, the DOS setup utility and NEC PowerMate V BIOS imply this */ + /* The OPTi 82c930 driver on the NEC Ready preloads requires this to function properly */ + ad1848_setdma(&optimc->ad1848, optimc_wss_dma[val & 3]); + ad1848_setirq(&optimc->ad1848, opti930_wss_irq[(val >> 3) & 7]); + } + break; + case 3: /* MC4 */ + optimc->regs[3] = val; + break; + case 4: /* MC5 */ + optimc->regs[4] = val; + /* OPTi 930 enables/disables AD1848 MODE2 from here */ + if (val & 0x20) { + optimc->ad1848.opti930_mode2 = 1; + optimc->ad1848.fmt_mask |= 0x80; + } + else { + optimc->ad1848.opti930_mode2 = 0; + optimc->ad1848.fmt_mask &= ~0x80; + } + break; + case 5: /* MC6 */ + optimc->regs[5] = val; + if (old != val) { + switch ((val >> 3) & 0x3) { + case 0: + optimc->cur_mpu401_irq = 9; + break; + case 1: + optimc->cur_mpu401_irq = 10; + break; + case 2: + optimc->cur_mpu401_irq = 5; + break; + case 3: + optimc->cur_mpu401_irq = 7; + break; + + default: + break; + } + switch ((val >> 5) & 0x3) { + case 0: + optimc->cur_mpu401_addr = 0x330; + break; + case 1: + optimc->cur_mpu401_addr = 0x320; + break; + case 2: + optimc->cur_mpu401_addr = 0x310; + break; + case 3: + optimc->cur_mpu401_addr = 0x300; + break; + + default: + break; + } + mpu401_change_addr(optimc->mpu, optimc->cur_mpu401_addr); + mpu401_setirq(optimc->mpu, optimc->cur_mpu401_irq); + optimc->cur_mode = optimc->cur_wss_enabled = !!(val & 0x02); + sound_set_cd_audio_filter(NULL, NULL); + if (optimc->cur_wss_enabled) { /* WSS */ + sound_set_cd_audio_filter(opti930_filter_cd_audio, optimc); + optimc->sb->opl_mixer = optimc; + optimc->sb->opl_mix = opti930_filter_opl; + } + else { /* SBPro */ + sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); + optimc->sb->opl_mixer = NULL; + optimc->sb->opl_mix = NULL; + } + } + break; + case 6: /* MC7 */ + optimc->regs[6] = val; + break; + case 7: /* MC8 */ + optimc->regs[7] = val; + break; + case 8: /* MC9 */ + optimc->regs[8] = val; + break; + case 9: /* MC10 */ + optimc->regs[9] = val; + break; + case 10: /* MC11, read-only */ + break; + case 11: /* MC12 */ + optimc->regs[11] = val; + break; + default: + break; + } + optimc_log(optimc->log, "OPTi930 Data Write: idx = %02X, val = %02X\n", idx, val); + } + if ((optimc->cur_opti930_addr != 0xF8E) && optimc->reg_enabled) { + optimc_log(optimc->log, "OPTi930 disable reg access on data write\n"); + optimc->reg_enabled = 0; + } +} + static void optimc_reg_write(uint16_t addr, uint8_t val, void *priv) { @@ -285,6 +591,7 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *priv) break; } } + optimc_log(optimc->log, "OPTi929 Write: idx = %02X, val = %02X\n", idx, val); if (optimc->reg_enabled) optimc->reg_enabled = 0; if ((addr == 0xF8F) && ((val == optimc->type) || (val == 0x00))) { @@ -318,6 +625,36 @@ optimc_reg_write(uint16_t addr, uint8_t val, void *priv) } } +static uint8_t +opti930_reg_read(uint16_t addr, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + uint16_t idx = optimc->index; + uint8_t temp = 0xFF; + + if ((addr == optimc->cur_opti930_addr) && (optimc->reg_enabled || !optimc->passwd_enabled)) + temp = optimc->index; + if ((addr == optimc->cur_opti930_addr +1) && (optimc->reg_enabled || !optimc->passwd_enabled)) { + switch (idx) { + case 0 ... 9: + temp = optimc->regs[optimc->index]; + break; + case 10: + temp = ((optimc->ad1848.regs[24] & 0x10) >> 2); + break; + case 11: + temp = optimc->regs[11]; + break; + } + } + if ((optimc->cur_opti930_addr != 0xF8E) && optimc->reg_enabled) { + optimc_log(optimc->log, "OPTi930 disable reg access on data read\n"); + optimc->reg_enabled = 0; + } + optimc_log(optimc->log, "OPTi930 Read: idx = %02X, val = %02X\n", optimc->index, temp); + return temp; +} + static uint8_t optimc_reg_read(uint16_t addr, void *priv) { @@ -342,13 +679,46 @@ optimc_reg_read(uint16_t addr, void *priv) } optimc->reg_enabled = 0; } + optimc_log(optimc->log, "OPTi929 Read: addr = %02X, val = %02X\n", addr, temp); return temp; } +static void +opti930_passwd_write(uint16_t addr, uint8_t val, void *priv) +{ + optimc_t *optimc = (optimc_t *) priv; + + optimc_log(optimc->log, "OPTi930 Password Write: val = %02X\n", val); + optimc_log(optimc->log, "OPTi930 last pw value: %02X\n", optimc->lastpw); + if ((addr == 0xF8F) && (optimc->reg_enabled)) { + optimc_log(optimc->log, "OPTi930: Removing old address handler at %04X\n", optimc->cur_opti930_addr); + io_removehandler(optimc->cur_opti930_addr, 2, opti930_reg_read, NULL, NULL, opti930_reg_write, NULL, NULL, optimc); /* Relocatable MCBase */ + optimc->opti930_mcbase = val; + optimc->cur_opti930_addr = (((val & 0x1f) << 4) + 0xE0E); + optimc->passwd_enabled = (val & 0x80) ? 0 : 1; + optimc_log(optimc->log, "OPTi930 register base now %04X\n", optimc->cur_opti930_addr); + optimc_log(optimc->log, "OPTi930 password enable: %02X\n", optimc->passwd_enabled); + io_sethandler(optimc->cur_opti930_addr, 2, opti930_reg_read, NULL, NULL, opti930_reg_write, NULL, NULL, optimc); /* Relocatable MCBase */ + optimc_log(optimc->log, "OPTi930 Disabling reg access\n"); + optimc->reg_enabled = 0; + } + if ((addr == 0xF8F) && (val == optimc->type) && !(optimc->reg_enabled)) { + optimc_log(optimc->log, "OPTi930 Enabling reg access\n"); + optimc->reg_enabled = 1; + } + if ((addr == 0xF8F) && (val != optimc->type) && (optimc->lastpw != OPTI_930)) { + optimc_log(optimc->log, "OPTi930 Disabling reg access\n"); + optimc->reg_enabled = 0; + } + optimc->lastpw = val; +} + static void * optimc_init(const device_t *info) { optimc_t *optimc = calloc(1, sizeof(optimc_t)); + uint8_t c; + double attenuation; optimc->type = info->local & 0xFF; @@ -362,17 +732,39 @@ optimc_init(const device_t *info) optimc->cur_mpu401_addr = 0x330; optimc->cur_mpu401_enabled = 1; - optimc->regs[0] = 0x00; - optimc->regs[1] = 0x03; - optimc->regs[2] = 0x00; - optimc->regs[3] = 0x00; - optimc->regs[4] = 0x3F; - optimc->regs[5] = 0x83; + if (optimc->type == OPTI_929) { + optimc->regs[0] = 0x00; + optimc->regs[1] = 0x03; + optimc->regs[2] = 0x00; + optimc->regs[3] = 0x00; + optimc->regs[4] = 0x3F; + optimc->regs[5] = 0x83; + } + if (optimc->type == OPTI_930) { + optimc->regs[0] = 0x00; + optimc->regs[1] = 0x00; + optimc->regs[2] = 0x2A; + optimc->regs[3] = 0x10; + optimc->regs[4] = 0x00; + optimc->regs[5] = 0x81; + optimc->regs[6] = 0x00; + optimc->regs[7] = 0x00; + optimc->regs[8] = 0x00; + optimc->regs[9] = 0x00; + optimc->regs[10] = 0x00; + optimc->regs[11] = 0x00; + optimc->opti930_mcbase = 0x00; /* Password enable, MCBase E0Eh */ + optimc->cur_opti930_addr = 0xE0E; + } + + optimc->log = log_open("OPTIMC"); optimc->gameport = gameport_add(&gameport_pnp_device); gameport_remap(optimc->gameport, (optimc->regs[0] & 0x1) ? 0x00 : 0x200); - if (info->local & 0x100) + if (optimc->type == OPTI_930) + ad1848_init(&optimc->ad1848, AD1848_TYPE_OPTI930); + else if (info->local & 0x100) ad1848_init(&optimc->ad1848, AD1848_TYPE_CS4231); else ad1848_init(&optimc->ad1848, AD1848_TYPE_DEFAULT); @@ -381,7 +773,13 @@ optimc_init(const device_t *info) ad1848_setirq(&optimc->ad1848, optimc->cur_wss_irq); ad1848_setdma(&optimc->ad1848, optimc->cur_wss_dma); - io_sethandler(0xF8D, 6, optimc_reg_read, NULL, NULL, optimc_reg_write, NULL, NULL, optimc); + if (optimc->type == OPTI_929) { + io_sethandler(0xF8D, 6, optimc_reg_read, NULL, NULL, optimc_reg_write, NULL, NULL, optimc); + } + if (optimc->type == OPTI_930) { + io_sethandler(0xF8F, 1, NULL, NULL, NULL, opti930_passwd_write, NULL, NULL, optimc); /* Fixed password reg, write-only */ + io_sethandler(optimc->cur_opti930_addr, 2, opti930_reg_read, NULL, NULL, opti930_reg_write, NULL, NULL, optimc); /* Relocatable MCBase */ + } io_sethandler(optimc->cur_wss_addr, 0x0004, optimc_wss_read, NULL, NULL, optimc_wss_write, NULL, NULL, optimc); io_sethandler(optimc->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &optimc->ad1848); @@ -398,8 +796,14 @@ optimc_init(const device_t *info) sb_dsp_setdma8(&optimc->sb->dsp, optimc->cur_dma); sb_ct1345_mixer_reset(optimc->sb); - optimc->sb->opl_mixer = optimc; - optimc->sb->opl_mix = optimc_filter_opl; + if (optimc->type == OPTI_930) { + optimc->sb->opl_mixer = optimc; + optimc->sb->opl_mix = opti930_filter_opl; + } + else { + optimc->sb->opl_mixer = optimc; + optimc->sb->opl_mix = optimc_filter_opl; + } fm_driver_get(optimc->fm_type, &optimc->sb->opl); io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv); @@ -410,11 +814,17 @@ optimc_init(const device_t *info) io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb); - sound_add_handler(optimc_get_buffer, optimc); + if (optimc->type == OPTI_930) + sound_add_handler(opti930_get_buffer, optimc); + else + sound_add_handler(optimc_get_buffer, optimc); if (optimc->fm_type == FM_YMF278B) wavetable_add_handler(sb_get_music_buffer_sbpro, optimc->sb); else music_add_handler(sb_get_music_buffer_sbpro, optimc->sb); + if (optimc->type == OPTI_930) + ad1848_set_cd_audio_channel(&optimc->ad1848, AD1848_AUX1); + sound_set_cd_audio_filter(NULL, NULL); /* Seems to be necessary for the filter below to apply */ sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */ optimc->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); @@ -423,6 +833,30 @@ optimc_init(const device_t *info) if (device_get_config_int("receive_input")) midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &optimc->sb->dsp); + /* OPTi 930 DOS sound test utility starts DMA playback without setting a time constant likely making */ + /* an assumption about the power-on state of the OPTi 930's SBPro DSP, set the power-on default time */ + /* constant for 22KHz Mono so the sound test utility passes the SBPro test */ + if (optimc->type == OPTI_930) + optimc->sb->dsp.sb_timeo = 211; + + for (c = 0; c < 32; c++) { + attenuation = 0.0; + if (c & 0x01) + attenuation -= 1.5; + if (c & 0x02) + attenuation -= 3.0; + if (c & 0x04) + attenuation -= 6.0; + if (c & 0x08) + attenuation -= 12.0; + if (c & 0x10) + attenuation -= 24.0; + + attenuation = pow(10, attenuation / 10); + + opti930_vols_5bits[c] = (attenuation * 65536); + } + return optimc; } @@ -431,6 +865,11 @@ optimc_close(void *priv) { optimc_t *optimc = (optimc_t *) priv; + if (optimc->log != NULL) { + log_close(optimc->log); + optimc->log = NULL; + } + sb_close(optimc->sb); free(optimc->mpu); free(priv); @@ -483,7 +922,7 @@ const device_t acermagic_s20_device = { .name = "AcerMagic S20", .internal_name = "acermagic_s20", .flags = DEVICE_ISA16, - .local = 0xE3 | OPTIMC_CS4231, + .local = OPTI_929 | OPTIMC_CS4231, .init = optimc_init, .close = optimc_close, .reset = NULL, @@ -497,7 +936,7 @@ const device_t mirosound_pcm10_device = { .name = "miroSOUND PCM10", .internal_name = "mirosound_pcm10", .flags = DEVICE_ISA16, - .local = 0xE3 | OPTIMC_OPL4, + .local = OPTI_929 | OPTIMC_OPL4, .init = optimc_init, .close = optimc_close, .reset = NULL, @@ -506,3 +945,18 @@ const device_t mirosound_pcm10_device = { .force_redraw = NULL, .config = optimc_config }; + +const device_t opti_82c930_device = { + .name = "OPTi 82c930", + .internal_name = "opti_82c930", + .flags = DEVICE_ISA16, + .local = OPTI_930 | OPTIMC_CS4231, + .init = optimc_init, + .close = optimc_close, + .reset = NULL, + .available = NULL, + .speed_changed = optimc_speed_changed, + .force_redraw = NULL, + .config = optimc_config +}; + diff --git a/src/sound/snd_ymf71x.c b/src/sound/snd_ymf71x.c index 116a0966d5a..c79263ce0ea 100644 --- a/src/sound/snd_ymf71x.c +++ b/src/sound/snd_ymf71x.c @@ -6,7 +6,7 @@ * * This file is part of the 86Box distribution. * - * Yamaha YMF-71x (OPL3-SA2/3) audio controller emulation. + * Yamaha YMF71x (OPL3-SA2/3) audio controller emulation. * * Authors: Cacodemon345 * Eluan Costa Miranda @@ -74,7 +74,7 @@ static const uint8_t ymf71x_init_key[32] = { 0xB1, 0xD8, 0x6C, 0x36, 0x9B, 0x4D, 0x33, 0x19, 0x8C, 0x46, 0xA3, 0x51, 0xA8, 0x54 }; /* Reversed attenuation values borrowed from snd_sb.c */ -/* YMF-71x master volume attenuation is -30dB when all bits are 1, 0dB when all bits are 0 */ +/* YMF71x master volume attenuation is -30dB when all bits are 1, 0dB when all bits are 0 */ static const double ymf71x_att_2dbstep_4bits[] = { 32767.0, 26027.0, 20674.0, 16422.0, 13044.0, 10362.0, 8230.0, 6537.0, 5192.0, 4125.0, 3276.0, 2602.0, 2067.0, 1641.0, 1304.0, 164.0 @@ -836,7 +836,7 @@ static const device_config_t ymf71x_config[] = { }; const device_t ymf715_onboard_device = { - .name = "Yamaha YMF-715 Onboard (OPL3-SA3)", + .name = "Yamaha YMF715 (OPL3-SA3) (On-Board)", .internal_name = "ymf715_onboard", .flags = DEVICE_ISA16, .local = 0x102, @@ -850,7 +850,7 @@ const device_t ymf715_onboard_device = { }; const device_t ymf718_device = { - .name = "Yamaha YMF-718 (OPL3-SA2)", + .name = "Yamaha YMF718 (OPL3-SA2)", .internal_name = "ymf718", .flags = DEVICE_ISA16, .local = 0x01, @@ -864,7 +864,7 @@ const device_t ymf718_device = { }; const device_t ymf719_device = { - .name = "Yamaha YMF-719 (OPL3-SA3)", + .name = "Yamaha YMF719 (OPL3-SA3)", .internal_name = "ymf719", .flags = DEVICE_ISA16, .local = 0x02, diff --git a/src/sound/sound.c b/src/sound/sound.c index 9373f067e45..d9db398a49f 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -140,6 +140,7 @@ static const SOUND_CARD sound_cards[] = { { &azt2316a_device }, { &azt1605_device }, { &sb_goldfinch_device }, + { &cs4232_device }, { &cs4235_device }, { &cs4236b_device }, { &gus_device }, @@ -147,6 +148,7 @@ static const SOUND_CARD sound_cards[] = { { &gus_max_device }, { &gus_ace_device }, { &mirosound_pcm10_device }, + { &opti_82c930_device }, { &pas16_device }, { &pas16d_device }, { &sb_16_device }, @@ -186,6 +188,9 @@ static const SOUND_CARD sound_cards[] = { /* AC97 */ { &ad1881_device }, { &cs4297a_device }, +#ifdef USE_SOFTMODEM + { &si3036_device }, +#endif { NULL } // clang-format on }; @@ -849,4 +854,4 @@ sound_fdd_thread_end(void) sound_fdd_start_event = NULL; } } -} \ No newline at end of file +} diff --git a/src/unix/CMakeLists.txt b/src/unix/CMakeLists.txt index 724ab041f35..1d428fa2b41 100644 --- a/src/unix/CMakeLists.txt +++ b/src/unix/CMakeLists.txt @@ -44,6 +44,7 @@ endif() add_library(ui OBJECT unix_sdl.c + unix_osd.c unix_cdrom.c dummy_cdrom_ioctl.c ) diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 27805a9e4d9..35916ffff1c 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,10 +12,10 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* -%global romver 4.1 +%global romver 5.2 Name: 86Box -Version: 5.2 +Version: 6.0 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Sat Aug 31 Jasmine Iwanek 5.2-1 +* Sat Aug 31 Jasmine Iwanek 6.0-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index fd633d4263b..1e929412c24 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/src/unix/unix.c b/src/unix/unix.c index ee13284fdc5..ce644cac686 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -41,6 +41,7 @@ #include <86box/device.h> #include <86box/gameport.h> #include <86box/unix_sdl.h> +#include <86box/unix_osd.h> #include "cpu.h" #include <86box/timer.h> #include <86box/nvr.h> @@ -52,6 +53,8 @@ #define __USE_GNU 1 /* shouldn't be done, yet it is */ #include +extern SDL_Window *sdl_win; + static int first_use = 1; static uint64_t StartingTime; static uint64_t Frequency; @@ -72,6 +75,10 @@ SDL_threadID eventthread; static int exit_event = 0; static int fullscreen_pending = 0; +// Two keys to be pressed together to open the OSD, variables to make them configurable in future +static uint16_t osd_open_first_key = SDL_SCANCODE_RCTRL; +static uint16_t osd_open_second_key = SDL_SCANCODE_F11; + static const uint16_t sdl_to_xt[0x200] = { [SDL_SCANCODE_ESCAPE] = 0x01, [SDL_SCANCODE_1] = 0x02, @@ -291,7 +298,7 @@ plat_get_string(int i) case STRING_MONITOR_SLEEP: return L"Monitor in sleep mode"; case STRING_EDID_TOO_LARGE: - return "EDID file \"%ls\" is too large."; + return L"EDID file \"%ls\" is too large."; } return L""; } @@ -480,22 +487,24 @@ plat_remove(char *path) remove(path); } -void -ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state)) +void ui_sb_update_icon_state(int tag, int state) { - /* No-op. */ + osd_ui_sb_update_icon_state(tag, state); } -void -ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) +void ui_sb_update_icon(int tag, int active) { - /* No-op. */ + osd_ui_sb_update_icon(tag, active); } -void -ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active)) +void ui_sb_update_icon_write(int tag, int active) { - /* No-op. */ + osd_ui_sb_update_icon_write(tag, active); +} + +void ui_sb_update_icon_wp(int tag, int state) +{ + osd_ui_sb_update_icon_wp(tag, state); } void @@ -541,7 +550,6 @@ path_get_dirname(char *dest, const char *path) *dest++ = *path++; *dest = '\0'; } -volatile int cpu_thread_run = 1; void ui_sb_set_text_w(UNUSED(wchar_t *wstr)) @@ -561,6 +569,8 @@ strnicmp(const char *s1, const char *s2, size_t n) return strncasecmp(s1, s2, n); } +volatile int cpu_thread_run = 1; + void main_thread(UNUSED(void *param)) { @@ -574,15 +584,20 @@ main_thread(UNUSED(void *param)) // title_update = 1; old_time = SDL_GetTicks(); drawits = frames = 0; - while (!is_quit && cpu_thread_run) { + while (!is_quit && cpu_thread_run) + { /* See if it is time to run a frame of code. */ new_time = SDL_GetTicks(); + #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) drawits = 10; else -#endif drawits += (new_time - old_time); +#else + drawits += (new_time - old_time); +#endif + old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -599,15 +614,18 @@ main_thread(UNUSED(void *param)) nvr_dosave = 0; frames = 0; } - } else /* Just so we dont overload the host OS. */ + } + else /* Just so we dont overload the host OS. */ SDL_Delay(1); /* If needed, handle a screen resize. */ if (atomic_load(&doresize_monitors[0]) && !video_fullscreen && !is_quit) { + if (vid_resize & 2) plat_resize(fixed_size_x, fixed_size_y, 0); else plat_resize(scrnsz_x, scrnsz_y, 0); + atomic_store(&doresize_monitors[0], 1); } } @@ -760,8 +778,6 @@ ui_sb_set_ready(UNUSED(int ready)) /* No-op. */ } -char *xargv[512]; - // From musl. char * local_strsep(char **str, const char *sep) @@ -880,6 +896,82 @@ plat_init_rom_paths(void) rom_add_path(default_rom_path); #endif } + +void +plat_init_asset_paths(void) +{ +#ifndef __APPLE__ + const char *xdg_data_home = getenv("XDG_DATA_HOME"); + if (xdg_data_home) { + char xdg_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(xdg_asset_path, sizeof(xdg_asset_path), "%s/", xdg_data_home); + if (used < sizeof(xdg_asset_path)) + used += snprintf(xdg_asset_path + used, sizeof(xdg_asset_path) - used, "86Box/"); + if (used < sizeof(xdg_asset_path) && !plat_dir_check(xdg_asset_path)) + plat_dir_create(xdg_asset_path); + if (used < sizeof(xdg_asset_path)) + used += snprintf(xdg_asset_path + used, sizeof(xdg_asset_path) - used, "assets/"); + if (used < sizeof(xdg_asset_path) && !plat_dir_check(xdg_asset_path)) + plat_dir_create(xdg_asset_path); + if (used < sizeof(xdg_asset_path)) + asset_add_path(xdg_asset_path); + } else { + const char *home = getenv("HOME"); + if (!home) { + struct passwd *pw = getpwuid(getuid()); + if (pw) + home = pw->pw_dir; + } + + if (home) { + char home_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(home_asset_path, sizeof(home_asset_path), + "%s/.local/share/86Box/", home); + if (used < sizeof(home_asset_path) && !plat_dir_check(home_asset_path)) + plat_dir_create(home_asset_path); + if (used < sizeof(home_asset_path)) + used += snprintf(home_asset_path + used, + sizeof(home_asset_path) - used, "assets/"); + if (used < sizeof(home_asset_path) && !plat_dir_check(home_asset_path)) + plat_dir_create(home_asset_path); + if (used < sizeof(home_asset_path)) + asset_add_path(home_asset_path); + } + } + + const char *xdg_data_dirs = getenv("XDG_DATA_DIRS"); + if (xdg_data_dirs) { + char *xdg_asset_paths = strdup(xdg_data_dirs); + if (xdg_asset_paths) { + // Trim trailing colons + size_t len = strlen(xdg_asset_paths); + while (len > 0 && xdg_asset_paths[len - 1] == ':') + xdg_asset_paths[--len] = '\0'; + + char *saveptr = NULL; + char *cur_xdg = strtok_r(xdg_asset_paths, ":", &saveptr); + while (cur_xdg) { + char real_xdg_asset_path[TMP_PATH_BUFSIZE] = {0}; + size_t used = snprintf(real_xdg_asset_path, + sizeof(real_xdg_asset_path), + "%s/86Box/assets/", cur_xdg); + if (used < sizeof(real_xdg_asset_path)) + asset_add_path(real_xdg_asset_path); + cur_xdg = strtok_r(NULL, ":", &saveptr); + } + + free(xdg_asset_paths); + } + } else { + asset_add_path("/usr/local/share/86Box/assets/"); + asset_add_path("/usr/share/86Box/assets/"); + } +#else + char default_asset_path[TMP_PATH_BUFSIZE] = {0}; + getDefaultROMPath(default_asset_path); + asset_add_path(default_asset_path); +#endif +} #undef TMP_PATH_BUFSIZE void @@ -922,7 +1014,7 @@ plat_get_vmm_dir(char *outbuf, const size_t len) } bool -process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) +process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, char **xargv, int cmdargc) { bool err = false; @@ -958,6 +1050,7 @@ process_media_commands_3(uint8_t *id, char *fn, uint8_t *wp, int cmdargc) fn[strlen(fn) - 1] = '\0'; return err; } + char *(*f_readline)(const char *) = NULL; int (*f_add_history)(const char *) = NULL; void (*f_rl_callback_handler_remove)(void) = NULL; @@ -968,11 +1061,6 @@ void (*f_rl_callback_handler_remove)(void) = NULL; # define LIBEDIT_LIBRARY "libedit.so" #endif -void ui_sb_update_icon_wp(int tag, int state) -{ - /* No-op */ -} - uint32_t timer_onesec(uint32_t interval, UNUSED(void *param)) { @@ -981,67 +1069,50 @@ timer_onesec(uint32_t interval, UNUSED(void *param)) } void -monitor_thread(UNUSED(void *param)) +unix_executeLine(char *line) { -#ifndef USE_CLI - if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { - char *line = NULL; - size_t n; + if (line) { + char *xargv[512]; + int cmdargc = 0; + char *linecpy, *linespn; - printf("86Box monitor console.\n"); - while (!exit_event) { - if (feof(stdin)) + linecpy = linespn = strdup(line); + linecpy[strcspn(linecpy, "\r\n")] = 0; + + if (!linecpy) { + return; + } + + if (f_add_history) + f_add_history(linecpy); + + memset(xargv, 0, sizeof(xargv)); + while (1) { + xargv[cmdargc++] = local_strsep(&linespn, " "); + if (xargv[cmdargc - 1] == NULL || cmdargc >= 512) break; -#ifdef ENABLE_READLINE - if (f_readline) - line = f_readline("(86Box) "); - else { -#endif - printf("(86Box) "); - (void) !getline(&line, &n, stdin); -#ifdef ENABLE_READLINE - } -#endif - if (line) { - int cmdargc = 0; - char *linecpy; - - line[strcspn(line, "\r\n")] = '\0'; - linecpy = strdup(line); - if (!linecpy) { - free(line); - line = NULL; - continue; - } - if (f_add_history) - f_add_history(line); - memset(xargv, 0, sizeof(xargv)); - while (1) { - xargv[cmdargc++] = local_strsep(&linecpy, " "); - if (xargv[cmdargc - 1] == NULL || cmdargc >= 512) - break; - } - cmdargc--; - if (strncasecmp(xargv[0], "help", 4) == 0) { - printf( - "fddload - Load floppy disk image into drive .\n" - "cdload - Load CD-ROM image into drive .\n" - "rdiskload - Load removable disk image into removable disk drive .\n" - "cartload - Load cartridge image into cartridge drive .\n" - "moload - Load MO image into MO drive .\n\n" - "fddeject - eject disk from floppy drive .\n" - "cdeject - eject disc from CD-ROM drive .\n" - "rdiskeject - eject removable disk image from removable disk drive .\n" - "carteject - eject cartridge from drive .\n" - "moeject - eject image from MO drive .\n\n" - "hardreset - hard reset the emulated system.\n" - "pause - pause the the emulated system.\n" - "fullscreen - toggle fullscreen.\n" - "version - print version and license information.\n" - "exit - exit 86Box.\n"); - } else if (strncasecmp(xargv[0], "exit", 4) == 0) { - exit_event = 1; - } else if (strncasecmp(xargv[0], "version", 7) == 0) { + } + cmdargc--; + if (strncasecmp(xargv[0], "help", 4) == 0) { + printf( + "fddload - Load floppy disk image into drive .\n" + "cdload - Load CD-ROM image into drive .\n" + "rdiskload - Load removable disk image into removable disk drive .\n" + "cartload - Load cartridge image into cartridge drive .\n" + "moload - Load MO image into MO drive .\n\n" + "fddeject - eject disk from floppy drive .\n" + "cdeject - eject disc from CD-ROM drive .\n" + "rdiskeject - eject removable disk image from removable disk drive .\n" + "carteject - eject cartridge from drive .\n" + "moeject - eject image from MO drive .\n\n" + "hardreset - hard reset the emulated system.\n" + "pause - pause the the emulated system.\n" + "fullscreen - toggle fullscreen.\n" + "version - print version and license information.\n" + "exit - exit 86Box.\n"); + } else if (strncasecmp(xargv[0], "exit", 4) == 0) { + exit_event = 1; + } else if (strncasecmp(xargv[0], "version", 7) == 0) { # ifndef EMU_GIT_HASH # define EMU_GIT_HASH "0000000" # endif @@ -1064,169 +1135,191 @@ monitor_thread(UNUSED(void *param)) # define DYNAREC_STR "no dynarec" # endif - printf( - "%s v%s [%s] [%s, %s]\n\n" - "An emulator of old computers\n" - "Authors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), " - "Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), " - "Tiseno100, reenigne, and others.\n" - "With previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n" - "Released under the GNU General Public License version 2 or later. See LICENSE for more information.\n", - EMU_NAME, EMU_VERSION_FULL, EMU_GIT_HASH, ARCH_STR, DYNAREC_STR); - } else if (strncasecmp(xargv[0], "fullscreen", 10) == 0) { - video_fullscreen = video_fullscreen ? 0 : 1; - fullscreen_pending = 1; - } else if (strncasecmp(xargv[0], "pause", 5) == 0) { - plat_pause(dopause ^ 1); - printf("%s", dopause ? "Paused.\n" : "Unpaused.\n"); - } else if (strncasecmp(xargv[0], "hardreset", 9) == 0) { - pc_reset_hard(); - } else if (strncasecmp(xargv[0], "cdload", 6) == 0 && cmdargc >= 3) { - uint8_t id; - bool err = false; - char fn[PATH_MAX]; - - if (!xargv[2] || !xargv[1]) { - free(line); - free(linecpy); - line = NULL; - continue; - } - id = atoi(xargv[1]); - memset(fn, 0, sizeof(fn)); - if (xargv[2][0] == '\'' || xargv[2][0] == '"') { - int curarg = 2; - - for (curarg = 2; curarg < cmdargc; curarg++) { - if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { - err = true; - fprintf(stderr, "Path name too long.\n"); - } - strcat(fn, xargv[curarg] + (xargv[curarg][0] == '\'' || xargv[curarg][0] == '"')); - if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') { - break; - } - strcat(fn, " "); - } - } else { - if (strlen(xargv[2]) < PATH_MAX) { - strcpy(fn, xargv[2]); - } else { - fprintf(stderr, "Path name too long.\n"); - } - } - if (!err) { - - if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') - fn[strlen(fn) - 1] = '\0'; - printf("Inserting disc into CD-ROM drive %hhu: %s\n", id, fn); - cdrom_mount(id, fn); - } - } else if (strncasecmp(xargv[0], "fddeject", 8) == 0 && cmdargc >= 2) { - floppy_eject(atoi(xargv[1])); - } else if (strncasecmp(xargv[0], "cdeject", 8) == 0 && cmdargc >= 2) { - cdrom_mount(atoi(xargv[1]), ""); - } else if (strncasecmp(xargv[0], "moeject", 8) == 0 && cmdargc >= 2) { - mo_eject(atoi(xargv[1])); - } else if (strncasecmp(xargv[0], "carteject", 8) == 0 && cmdargc >= 2) { - cartridge_eject(atoi(xargv[1])); - } else if (strncasecmp(xargv[0], "rdiskeject", 8) == 0 && cmdargc >= 2) { - rdisk_eject(atoi(xargv[1])); - } else if (strncasecmp(xargv[0], "fddload", 7) == 0 && cmdargc >= 4) { - uint8_t id; - uint8_t wp; - bool err = false; - char fn[PATH_MAX]; - - memset(fn, 0, sizeof(fn)); - - if (!xargv[2] || !xargv[1]) { - free(line); - free(linecpy); - line = NULL; - continue; - } - err = process_media_commands_3(&id, fn, &wp, cmdargc); - if (!err) { - if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') - fn[strlen(fn) - 1] = '\0'; - printf("Inserting disk into floppy drive %c: %s\n", id + 'A', fn); - floppy_mount(id, fn, wp); - } - } else if (strncasecmp(xargv[0], "moload", 7) == 0 && cmdargc >= 4) { - uint8_t id; - uint8_t wp; - bool err = false; - char fn[PATH_MAX]; - - memset(fn, 0, sizeof(fn)); - - if (!xargv[2] || !xargv[1]) { - free(line); - free(linecpy); - line = NULL; - continue; - } - err = process_media_commands_3(&id, fn, &wp, cmdargc); - if (!err) { - if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') - fn[strlen(fn) - 1] = '\0'; - printf("Inserting into mo drive %hhu: %s\n", id, fn); - mo_mount(id, fn, wp); - } - } else if (strncasecmp(xargv[0], "cartload", 7) == 0 && cmdargc >= 4) { - uint8_t id; - uint8_t wp; - bool err = false; - char fn[PATH_MAX]; - - memset(fn, 0, sizeof(fn)); - - if (!xargv[2] || !xargv[1]) { - free(line); - free(linecpy); - line = NULL; - continue; - } - err = process_media_commands_3(&id, fn, &wp, cmdargc); - if (!err) { - if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') - fn[strlen(fn) - 1] = '\0'; - printf("Inserting tape into cartridge holder %hhu: %s\n", id, fn); - cartridge_mount(id, fn, wp); - } - } else if (strncasecmp(xargv[0], "rdiskload", 7) == 0 && cmdargc >= 4) { - uint8_t id; - uint8_t wp; - bool err = false; - char fn[PATH_MAX]; - - memset(fn, 0, sizeof(fn)); - - if (!xargv[2] || !xargv[1]) { - free(line); - free(linecpy); - line = NULL; - continue; + printf( + "%s v%s [%s] [%s, %s]\n\n" + "An emulator of old computers\n" + "Authors: Miran GrÄa (OBattler), RichardG867, Jasmine Iwanek, TC1995, coldbrewed, Teemu Korhonen (Manaatti), " + "Joakim L. Gilje, Adrien Moulin (elyosh), Daniel Balsom (gloriouscow), Cacodemon345, Fred N. van Kempen (waltje), " + "Tiseno100, reenigne, and others.\n" + "With previous core contributions from Sarah Walker, leilei, JohnElliott, greatpsycho, and others.\n\n" + "Released under the GNU General Public License version 2 or later. See LICENSE for more information.\n", + EMU_NAME, EMU_VERSION_FULL, EMU_GIT_HASH, ARCH_STR, DYNAREC_STR); + } else if (strncasecmp(xargv[0], "fullscreen", 10) == 0) { + video_fullscreen = video_fullscreen ? 0 : 1; + fullscreen_pending = 1; + } else if (strncasecmp(xargv[0], "pause", 5) == 0) { + plat_pause(dopause ^ 1); + printf("%s", dopause ? "Paused.\n" : "Unpaused.\n"); + } else if (strncasecmp(xargv[0], "hardreset", 9) == 0) { + pc_reset_hard(); + } else if (strncasecmp(xargv[0], "cdload", 6) == 0 && cmdargc >= 3) { + uint8_t id; + bool err = false; + char fn[PATH_MAX]; + + if (!xargv[2] || !xargv[1]) { + free(linecpy); + return; + } + id = atoi(xargv[1]); + memset(fn, 0, sizeof(fn)); + if (xargv[2][0] == '\'' || xargv[2][0] == '"') { + int curarg = 2; + + for (curarg = 2; curarg < cmdargc; curarg++) { + if (strlen(fn) + strlen(xargv[curarg]) >= PATH_MAX) { + err = true; + fprintf(stderr, "Path name too long.\n"); } - err = process_media_commands_3(&id, fn, &wp, cmdargc); - if (!err) { + else + { + strcat(fn, xargv[curarg] + (xargv[curarg][0] == '\'' || xargv[curarg][0] == '"')); if (fn[strlen(fn) - 1] == '\'' - || fn[strlen(fn) - 1] == '"') - fn[strlen(fn) - 1] = '\0'; - printf("Inserting disk into removable disk drive %c: %s\n", id + 'A', fn); - rdisk_mount(id, fn, wp); + || fn[strlen(fn) - 1] == '"') { + break; + } + strcat(fn, " "); } } - free(line); + } else { + if (strlen(xargv[2]) < PATH_MAX) { + strncpy(fn, xargv[2], PATH_MAX-1); + } else { + fprintf(stderr, "Path name too long.\n"); + } + } + if (!err) { + + if (fn[strlen(fn) - 1] == '\'' + || fn[strlen(fn) - 1] == '"') + fn[strlen(fn) - 1] = '\0'; + printf("Inserting disc into CD-ROM drive %hhu: %s\n", id, fn); + cdrom_mount(id, fn); + } + } else if (strncasecmp(xargv[0], "fddeject", 8) == 0 && cmdargc >= 2) { + floppy_eject(atoi(xargv[1])); + } else if (strncasecmp(xargv[0], "cdeject", 8) == 0 && cmdargc >= 2) { + cdrom_mount(atoi(xargv[1]), ""); + } else if (strncasecmp(xargv[0], "moeject", 8) == 0 && cmdargc >= 2) { + mo_eject(atoi(xargv[1])); + } else if (strncasecmp(xargv[0], "carteject", 8) == 0 && cmdargc >= 2) { + cartridge_eject(atoi(xargv[1])); + } else if (strncasecmp(xargv[0], "rdiskeject", 8) == 0 && cmdargc >= 2) { + rdisk_eject(atoi(xargv[1])); + } else if (strncasecmp(xargv[0], "fddload", 7) == 0 && cmdargc >= 4) { + uint8_t id; + uint8_t wp; + bool err = false; + char fn[PATH_MAX]; + + memset(fn, 0, sizeof(fn)); + + if (!xargv[2] || !xargv[1]) { + free(linecpy); + return; + } + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); + if (!err) { + if (fn[strlen(fn) - 1] == '\'' + || fn[strlen(fn) - 1] == '"') + fn[strlen(fn) - 1] = '\0'; + printf("Inserting disk into floppy drive %c: %s\n", id + 'A', fn); + floppy_mount(id, fn, wp); + } + } else if (strncasecmp(xargv[0], "moload", 7) == 0 && cmdargc >= 4) { + uint8_t id; + uint8_t wp; + bool err = false; + char fn[PATH_MAX]; + + memset(fn, 0, sizeof(fn)); + + if (!xargv[2] || !xargv[1]) { free(linecpy); - line = NULL; + return; } + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); + if (!err) { + if (fn[strlen(fn) - 1] == '\'' + || fn[strlen(fn) - 1] == '"') + fn[strlen(fn) - 1] = '\0'; + printf("Inserting into mo drive %hhu: %s\n", id, fn); + mo_mount(id, fn, wp); + } + } else if (strncasecmp(xargv[0], "cartload", 7) == 0 && cmdargc >= 4) { + uint8_t id; + uint8_t wp; + bool err = false; + char fn[PATH_MAX]; + + memset(fn, 0, sizeof(fn)); + + if (!xargv[2] || !xargv[1]) { + free(linecpy); + return; + } + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); + if (!err) { + if (fn[strlen(fn) - 1] == '\'' + || fn[strlen(fn) - 1] == '"') + fn[strlen(fn) - 1] = '\0'; + printf("Inserting tape into cartridge holder %hhu: %s\n", id, fn); + cartridge_mount(id, fn, wp); + } + } else if (strncasecmp(xargv[0], "rdiskload", 7) == 0 && cmdargc >= 4) { + uint8_t id; + uint8_t wp; + bool err = false; + char fn[PATH_MAX]; + + memset(fn, 0, sizeof(fn)); + + if (!xargv[2] || !xargv[1]) { + free(linecpy); + return; + } + err = process_media_commands_3(&id, fn, &wp, xargv, cmdargc); + if (!err) { + if (fn[strlen(fn) - 1] == '\'' + || fn[strlen(fn) - 1] == '"') + fn[strlen(fn) - 1] = '\0'; + printf("Inserting disk into removable disk drive %c: %s\n", id + 'A', fn); + rdisk_mount(id, fn, wp); + } + } + free(linecpy); + } +} + +void +monitor_thread(UNUSED(void *param)) +{ +#ifndef USE_CLI + if (isatty(fileno(stdin)) && isatty(fileno(stdout))) { + char *line = NULL; + size_t n; + + printf("86Box monitor console.\n"); + while (!exit_event) + { + if (feof(stdin)) + break; + +#ifdef ENABLE_READLINE + if (f_readline) + line = f_readline("(86Box) "); + else { +#endif + printf("(86Box) "); + (void) !getline(&line, &n, stdin); +#ifdef ENABLE_READLINE + } +#endif + + unix_executeLine(line); + + free(line); + line = NULL; } } #endif @@ -1283,118 +1376,234 @@ main(int argc, char **argv) plat_pause(0); /* Initialize the rendering window, or fullscreen. */ - do_start(); + #ifndef USE_CLI thread_create(monitor_thread, NULL); #endif + SDL_AddTimer(1000, timer_onesec, NULL); - while (!is_quit) { + while (!is_quit) + { static int mouse_inside = 0; + static int osd_first_key_pressed = 0; + static int flag_osd_open = 0; + + while (SDL_PollEvent(&event)) + { + if (flag_osd_open == 1) + { + // route almost everything to the OSD + switch (event.type) + { + case SDL_QUIT: + { + exit_event = 1; + break; + } + case SDL_RENDER_DEVICE_RESET: + case SDL_RENDER_TARGETS_RESET: + { + extern void sdl_reinit_texture(void); - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - exit_event = 1; - break; - case SDL_MOUSEWHEEL: + printf("reinit tex\n"); + sdl_reinit_texture(); + break; + } + case SDL_WINDOWEVENT: { - if (mouse_capture || video_fullscreen) { - if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { - event.wheel.x *= -1; - event.wheel.y *= -1; - } - SDL_LockMutex(mousemutex); - mouse_set_z(event.wheel.y); - SDL_UnlockMutex(mousemutex); + switch (event.window.event) { + case SDL_WINDOWEVENT_ENTER: + mouse_inside = 1; + break; + case SDL_WINDOWEVENT_LEAVE: + mouse_inside = 0; + break; } break; } - case SDL_MOUSEMOTION: + default: { - if (mouse_capture || video_fullscreen) { - SDL_LockMutex(mousemutex); - mouse_scale(event.motion.xrel, event.motion.yrel); - SDL_UnlockMutex(mousemutex); + // route everything else + flag_osd_open = osd_handle(event); + + if (flag_osd_open == 0) + { + // close it + osd_close(event); } + 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); + } + } + else + { + switch (event.type) + { + case SDL_QUIT: + exit_event = 1; + break; + case SDL_MOUSEWHEEL: + { + if (mouse_capture || video_fullscreen) { + if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { + event.wheel.x *= -1; + event.wheel.y *= -1; + } + SDL_LockMutex(mousemutex); + mouse_set_z(event.wheel.y); + SDL_UnlockMutex(mousemutex); + } break; } - if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) { - plat_mouse_capture(0); + case SDL_MOUSEMOTION: + { + if (mouse_capture || video_fullscreen) { + SDL_LockMutex(mousemutex); + mouse_scale(event.motion.xrel, event.motion.yrel); + SDL_UnlockMutex(mousemutex); + } + break; + } + /* Touch events */ + case SDL_FINGERDOWN: + { + // Trap these but ignore them for now + break; + } + case SDL_FINGERUP: + { + // Trap these but ignore them for now + break; + } + case SDL_FINGERMOTION: + { + // See SDL_TouchFingerEvent + if (mouse_capture || video_fullscreen) { + SDL_LockMutex(mousemutex); + + // Real multiplier is the window size + int w, h; + SDL_GetWindowSize(sdl_win, &w, &h); + + mouse_scale((int)(event.tfinger.dx * w), (int)(event.tfinger.dy * h)); + SDL_UnlockMutex(mousemutex); + } 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; + 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; + case SDL_BUTTON_X1: + buttonmask = 8; + break; + case SDL_BUTTON_X2: + buttonmask = 16; + break; + default: + printf("Unknown mouse button %d\n", event.button.button); + } + SDL_LockMutex(mousemutex); + if (event.button.state == SDL_PRESSED) + mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); + else + mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); + SDL_UnlockMutex(mousemutex); + } + break; + } + case SDL_RENDER_DEVICE_RESET: + case SDL_RENDER_TARGETS_RESET: + { + extern void sdl_reinit_texture(void); + + sdl_reinit_texture(); + break; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + uint16_t xtkey = 0; + + if (event.key.keysym.scancode == osd_open_first_key) + { + if (event.type == SDL_KEYDOWN) + osd_first_key_pressed = 1; + else + osd_first_key_pressed = 0; + } + else if (osd_first_key_pressed && event.type == SDL_KEYDOWN && event.key.keysym.scancode == osd_open_second_key) + { + // open OSD! + flag_osd_open = osd_open(event); + + // we can assume alt-gr has been released, tell this also to the virtual machine + osd_first_key_pressed = 0; + keyboard_input(0, sdl_to_xt[osd_open_first_key]); + break; + } + else + { + // invalidate osd_first_key_pressed is something happens between its keydown and keydown for G + osd_first_key_pressed = 0; + } + + switch (event.key.keysym.scancode) { + default: + xtkey = sdl_to_xt[event.key.keysym.scancode]; break; - case SDL_BUTTON_X1: - buttonmask = 8; + } + + 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_BUTTON_X2: - buttonmask = 16; + case SDL_WINDOWEVENT_LEAVE: + mouse_inside = 0; break; } - SDL_LockMutex(mousemutex); - if (event.button.state == SDL_PRESSED) - mouse_set_buttons_ex(mouse_get_buttons_ex() | buttonmask); - else - mouse_set_buttons_ex(mouse_get_buttons_ex() & ~buttonmask); - SDL_UnlockMutex(mousemutex); + break; } - break; - } - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: + default: { - extern void sdl_reinit_texture(void); - - sdl_reinit_texture(); + // printf("Unhandled SDL event: %d\n", event.type); 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); - } - case SDL_WINDOWEVENT: - { - switch (event.window.event) { - case SDL_WINDOWEVENT_ENTER: - mouse_inside = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - mouse_inside = 0; - break; - } - } + } } } + if (blitreq) { extern void sdl_blit(int x, int y, int w, int h); sdl_blit(params.x, params.y, params.w, params.h); diff --git a/src/unix/unix_cdrom.c b/src/unix/unix_cdrom.c index daf13cb9a85..35ce92a9fd6 100644 --- a/src/unix/unix_cdrom.c +++ b/src/unix/unix_cdrom.c @@ -43,13 +43,14 @@ cassette_mount(char *fn, uint8_t wp) memset(cassette_fname, 0, sizeof(cassette_fname)); cassette_ui_writeprot = wp; pc_cas_set_fname(cassette, fn); + if (fn != NULL) memcpy(cassette_fname, fn, MIN(511, strlen(fn))); + ui_sb_update_icon_state(SB_CASSETTE, (fn == NULL) ? 1 : 0); -#if 0 - media_menu_update_cassette(); -#endif + ui_sb_update_tip(SB_CASSETTE); + config_save(); } @@ -58,11 +59,11 @@ cassette_eject(void) { pc_cas_set_fname(cassette, NULL); memset(cassette_fname, 0x00, sizeof(cassette_fname)); + ui_sb_update_icon_state(SB_CASSETTE, 1); -#if 0 - media_menu_update_cassette(); -#endif + ui_sb_update_tip(SB_CASSETTE); + config_save(); } @@ -71,11 +72,11 @@ cartridge_mount(uint8_t id, char *fn, UNUSED(uint8_t wp)) { cart_close(id); cart_load(id, fn); + ui_sb_update_icon_state(SB_CARTRIDGE | id, strlen(cart_fns[id]) ? 0 : 1); -#if 0 - media_menu_update_cartridge(id); -#endif + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); } @@ -83,11 +84,11 @@ void cartridge_eject(uint8_t id) { cart_close(id); + ui_sb_update_icon_state(SB_CARTRIDGE | id, 1); -#if 0 - media_menu_update_cartridge(id); -#endif + ui_sb_update_tip(SB_CARTRIDGE | id); + config_save(); } @@ -97,11 +98,11 @@ floppy_mount(uint8_t id, char *fn, uint8_t wp) fdd_close(id); ui_writeprot[id] = wp; fdd_load(id, fn); + ui_sb_update_icon_state(SB_FLOPPY | id, strlen(floppyfns[id]) ? 0 : 1); -#if 0 - media_menu_update_floppy(id); -#endif + ui_sb_update_tip(SB_FLOPPY | id); + config_save(); } @@ -109,11 +110,11 @@ void floppy_eject(uint8_t id) { fdd_close(id); + ui_sb_update_icon_state(SB_FLOPPY | id, 1); -#if 0 - media_menu_update_floppy(id); -#endif + ui_sb_update_tip(SB_FLOPPY | id); + config_save(); } @@ -128,34 +129,16 @@ plat_cdrom_ui_update(uint8_t id, UNUSED(uint8_t reload)) ui_sb_update_icon_state(SB_CDROM | id, 0); } -#if 0 - media_menu_update_cdrom(id); -#endif ui_sb_update_tip(SB_CDROM | id); } void cdrom_mount(uint8_t id, char *fn) { - strcpy(cdrom[id].prev_image_path, cdrom[id].image_path); - if (cdrom[id].ops && cdrom[id].ops->close) - cdrom[id].ops->close(cdrom[id].local); - cdrom[id].ops = NULL; - memset(cdrom[id].image_path, 0, sizeof(cdrom[id].image_path)); - if ((fn != NULL) && (strlen(fn) >= 1) && (fn[strlen(fn) - 1] == '\\')) - fn[strlen(fn) - 1] = '/'; - image_open(&(cdrom[id]), fn); - /* Signal media change to the emulated machine. */ - if (cdrom[id].insert) - cdrom[id].insert(cdrom[id].priv); - if (cdrom[id].image_path[0] == 0x00) - ui_sb_update_icon_state(SB_CDROM | id, 0); - else - ui_sb_update_icon_state(SB_CDROM | id, 1); -#if 0 - media_menu_update_cdrom(id); -#endif - ui_sb_update_tip(SB_CDROM | id); + int ret = cdrom_load( &(cdrom[id]), fn, 0); + + plat_cdrom_ui_update(id, 0); + config_save(); } @@ -171,9 +154,7 @@ mo_eject(uint8_t id) } ui_sb_update_icon_state(SB_MO | id, 1); -#if 0 - media_menu_update_mo(id); -#endif + ui_sb_update_tip(SB_MO | id); config_save(); } @@ -188,9 +169,7 @@ mo_mount(uint8_t id, char *fn, uint8_t wp) mo_load(dev, fn, 0); ui_sb_update_icon_state(SB_MO | id, strlen(mo_drives[id].image_path) ? 0 : 1); -#if 0 - media_menu_update_mo(id); -#endif + ui_sb_update_tip(SB_MO | id); config_save(); @@ -208,9 +187,6 @@ mo_reload(uint8_t id) ui_sb_update_icon_state(SB_MO | id, 0); } -#if 0 - media_menu_update_mo(id); -#endif ui_sb_update_tip(SB_MO | id); config_save(); @@ -228,10 +204,9 @@ rdisk_eject(uint8_t id) } ui_sb_update_icon_state(SB_RDISK | id, 1); -#if 0 - media_menu_update_rdisk(id); -#endif + ui_sb_update_tip(SB_RDISK | id); + config_save(); } @@ -245,9 +220,7 @@ rdisk_mount(uint8_t id, char *fn, uint8_t wp) rdisk_load(dev, fn, 0); ui_sb_update_icon_state(SB_RDISK | id, strlen(rdisk_drives[id].image_path) ? 0 : 1); -#if 0 - media_menu_update_rdisk(id); -#endif + ui_sb_update_tip(SB_RDISK | id); config_save(); @@ -265,9 +238,6 @@ rdisk_reload(uint8_t id) ui_sb_update_icon_state(SB_RDISK | id, 0); } -#if 0 - media_menu_update_rdisk(id); -#endif ui_sb_update_tip(SB_RDISK | id); config_save(); diff --git a/src/unix/unix_osd.c b/src/unix/unix_osd.c new file mode 100644 index 00000000000..61597242f6d --- /dev/null +++ b/src/unix/unix_osd.c @@ -0,0 +1,563 @@ +#include +#include + +#include +#include +#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/device.h> +#include <86box/plat.h> +#include <86box/plat_dynld.h> +#include <86box/video.h> +#include <86box/ui.h> +#include <86box/version.h> +#include <86box/unix_sdl.h> +#include <86box/unix_osd.h> +#include <86box/unix_osd_font.h> + +static int SCREEN_W = 640; +static int SCREEN_H = 480; +static int BOX_W = 240; +static int BOX_H = 160; +#define LINE_HEIGHT 16 +#define TITLE_HEIGHT 16 +#define CHAR_W 8 +#define CHAR_H 8 + +// this makes the osd embeddable in the 86box main sdl loop +#define OSD_INSIDE_MAIN_LOOP + +// interface to SDL environment +extern SDL_Window *sdl_win; +extern SDL_Renderer *sdl_render; +extern SDL_mutex *sdl_mutex; + +// interface back to main unix monitor implementation +extern void unix_executeLine(char *line); + +// interface to the currently set window title, this can't be seen normally in a fullscreen setup +extern wchar_t sdl_win_title[512]; +char sdl_win_title_mb[512] = ""; + +static SDL_Texture *font_texture = NULL; + +typedef enum { + STATE_MENU, + STATE_FILESELECT_FLOPPY, + STATE_FILESELECT_CD, + STATE_FILESELECT_RDISK, + STATE_FILESELECT_CART, + STATE_FILESELECT_MO +} AppState; + +static const char *menu_items[] = { + "fddload - Load floppy disk image", + "cdload - Load CD-ROM image", + "rdiskload - Load removable disk image", + "cartload - Load cartridge image", + "moload - Load MO image", + "fddeject - eject disk from floppy drive", + "cdeject - eject disc from CD-ROM drive", + "rdiskeject - eject removable disk", + "carteject - eject cartridge", + "moeject - eject image from MO drive", + "hardreset - hard reset the emulated system", + // "pause - pause the the emulated system", + "fullscreen - toggle fullscreen", + "version - print version and license information", + "exit - exit 86Box", + "close OSD" +}; +#define MENU_ITEMS (sizeof(menu_items) / sizeof(menu_items[0])) + +// chars per cols and rows +static int font_cols = 16; + +static int selected = 0; +static int file_selected = 0; +static int scroll_offset = 0; + +static int osd_is_open = 0; +static AppState state = STATE_MENU; + +static char files[100][1024]; +static int file_count = 0; + +static int max_visible = 0; + +void reset_iso_files(void) +{ + file_selected = 0; + scroll_offset = 0; + + file_count = 0; + memset(files, 0, sizeof(files)); +} + +static int endswith(char *s1, char *mask) +{ + int ss = strlen(s1); + int sm = strlen(mask); + return ss >= sm && strncasecmp(s1+ss-sm, mask, sm) == 0; +} + +int load_iso_files(char *basedir, char files[][1024], int max_files, char *mask) +{ + DIR *d; + struct dirent *dir; + int count = file_count; + d = opendir(basedir); + if (!d) + return file_count; + + while ((dir = readdir(d)) != NULL && count < max_files) + { + if (endswith(dir->d_name, mask)) + { + strcpy(files[count], basedir); + strcat(files[count], "/"); + strcat(files[count], dir->d_name); + + count++; + } + } + + closedir(d); + + return count; +} + +void draw_text(SDL_Renderer *renderer, const char *text, int x, int y, SDL_Color color) +{ + if (!font_texture) + return; + + SDL_SetTextureColorMod(font_texture, color.r, color.g, color.b); + + int i = 0; + while (text[i]) + { + unsigned char c = text[i]; + int tx = (c % font_cols) * CHAR_W; + int ty = (c / font_cols) * CHAR_H; + SDL_Rect src = {tx, ty, CHAR_W, CHAR_H}; + SDL_Rect dst = {x + i * CHAR_W, y, CHAR_W, CHAR_H}; + SDL_RenderCopy(renderer, font_texture, &src, &dst); + i++; + } +} + +void draw_box_with_border(SDL_Renderer *renderer, SDL_Rect box) +{ + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderDrawRect(renderer, &box); + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_Rect inner = {box.x + 2, box.y + 2, box.w - 4, box.h - 4}; + SDL_RenderDrawRect(renderer, &inner); + + SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255); + SDL_RenderFillRect(renderer, &inner); +} + + +void draw_menu(SDL_Renderer *renderer, int selected) +{ + int x0 = (SCREEN_W - BOX_W) / 2; + int y0 = (SCREEN_H - BOX_H) / 2; + SDL_Rect box = {x0, y0, BOX_W, BOX_H}; + draw_box_with_border(renderer, box); + + draw_text(renderer, "MAIN MENU", x0 + 20, y0 + 5, (SDL_Color){255,255,255,255}); + + wcstombs(sdl_win_title_mb, sdl_win_title, 256); + draw_text(renderer, sdl_win_title_mb, x0 + 120, y0 + 5, (SDL_Color){255,255,255,255}); + + for (int i = 0; i < MENU_ITEMS; i++) + { + int tx = x0 + 20; + int ty = y0 + TITLE_HEIGHT + i * LINE_HEIGHT; + + SDL_Color textColor; + SDL_Rect bgRect = {tx - 5, ty - 2, BOX_W - 20, LINE_HEIGHT}; + + if (i == selected) { + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderFillRect(renderer, &bgRect); + textColor = (SDL_Color){0, 0, 0, 255}; + } else { + textColor = (SDL_Color){255, 255, 0, 255}; + } + + draw_text(renderer, menu_items[i], tx, ty, textColor); + } + +#ifndef OSD_INSIDE_MAIN_LOOP + SDL_RenderPresent(renderer); +#endif +} + +void draw_file_selector(SDL_Renderer *renderer, + char *title, + char files[][1024], int file_count, + int selected, int scroll_offset, int max_visible) +{ + int x0 = (SCREEN_W - BOX_W) / 2; + int y0 = (SCREEN_H - BOX_H) / 2; + SDL_Rect box = {x0, y0, BOX_W, BOX_H}; + draw_box_with_border(renderer, box); + + draw_text(renderer, title, x0 + 20, y0 + 5, (SDL_Color){255,255,255,255}); + + if (file_count == 0) { + draw_text(renderer, "No files.", + x0 + 20, y0 + TITLE_HEIGHT + 10, + (SDL_Color){255, 255, 0, 255}); + } else { + for (int i = 0; i < max_visible && (i + scroll_offset) < file_count; i++) { + int index = i + scroll_offset; + int tx = x0 + 20; + int ty = y0 + TITLE_HEIGHT + i * LINE_HEIGHT; + + SDL_Color textColor; + SDL_Rect bgRect = {tx - 5, ty - 2, 200, LINE_HEIGHT}; + + if (index == selected) { + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderFillRect(renderer, &bgRect); + textColor = (SDL_Color){0, 0, 0, 255}; + } else { + textColor = (SDL_Color){255, 255, 0, 255}; + } + + draw_text(renderer, files[index], tx, ty, textColor); + } + } + +#ifndef OSD_INSIDE_MAIN_LOOP + SDL_RenderPresent(renderer); +#endif +} + +void osd_init(void) +{ + // debug: fprintf(stderr, "OSD INIT\n"); + + if (font_texture == NULL) + { + // debug: fprintf(stderr, "OSD INIT FONT\n"); + + // Carica font bitmap (font.bmp 128x128, 16x16 caratteri, 8x8 ciascuno) + SDL_RWops *rwop = SDL_RWFromConstMem(_________font_bmp, _________font_bmp_len); + if (!rwop) + { + fprintf(stderr, "Cannot create a new SDL RW stream: %s\n", SDL_GetError()); + return; + } + + // auto-closes the stream + SDL_Surface *font_surface = SDL_LoadBMP_RW(rwop, 1); + if (!font_surface) { + fprintf(stderr, "Cannot create a surface using RW stream: %s\n", SDL_GetError()); + return; + } + + // Imposta trasparenza sul nero puro + SDL_SetColorKey(font_surface, SDL_TRUE, SDL_MapRGB(font_surface->format, 0, 0, 0)); + font_texture = SDL_CreateTextureFromSurface(sdl_render, font_surface); + SDL_FreeSurface(font_surface); + } +} + +void osd_deinit(void) +{ + // nothing to do + // debug: fprintf(stderr, "OSD DEINIT\n"); + + // will be implicitly freed on exit + // SDL_DestroyTexture(font_texture); + + font_texture = NULL; +} + +int osd_open(SDL_Event event) +{ + // ok opened + // debug: fprintf(stderr, "OSD OPEN\n"); + + SDL_GetWindowSize(sdl_win, &SCREEN_W, &SCREEN_H); + BOX_W = (SCREEN_W / 4) * 3; + BOX_H = (SCREEN_H / 4) * 3; + + max_visible = (BOX_H - TITLE_HEIGHT) / LINE_HEIGHT; + + osd_is_open = 1; + + return 1; +} + +int osd_close(SDL_Event event) +{ + // ok closed + // debug: fprintf(stderr, "OSD CLOSE\n"); + + osd_is_open = 0; + + return 1; +} + +static void osd_cmd_run(char *c) +{ + char *l = calloc(strlen(c)+2, 1); + strcpy(l, c); + unix_executeLine(l); + free(l); +} + +void osd_present(void) +{ + // shortcut + if (!osd_is_open) + return; + +#ifndef OSD_INSIDE_MAIN_LOOP + SDL_LockMutex(sdl_mutex); +#endif + + if (state == STATE_MENU) { + draw_menu(sdl_render, selected); + } + else if (state == STATE_FILESELECT_FLOPPY) { + draw_file_selector(sdl_render, "SELECT FLOPPY IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + else if (state == STATE_FILESELECT_CD) { + draw_file_selector(sdl_render, "SELECT CD ISO IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + else if (state == STATE_FILESELECT_RDISK) { + draw_file_selector(sdl_render, "SELECT REMOVABLE DISK IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + else if (state == STATE_FILESELECT_CART) { + draw_file_selector(sdl_render, "SELECT CARTRIDGE IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + else if (state == STATE_FILESELECT_MO) { + draw_file_selector(sdl_render, "SELECT MO IMAGE", files, file_count, file_selected, scroll_offset, max_visible); + } + + +#ifndef OSD_INSIDE_MAIN_LOOP + SDL_UnlockMutex(sdl_mutex); +#endif +} + +int osd_handle(SDL_Event event) +{ + // debug: fprintf(stderr, "OSD HANDLE\n"); + + if (event.type == SDL_KEYUP) + { + if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) + { + if (state == STATE_MENU) + { + // Close the OSD + // debug: fprintf(stderr, "OSD HANDLE: escape\n"); + return 0; + } + else + { + // Back to Main and keep it open + state = STATE_MENU; + return 1; + } + } + + if (state == STATE_MENU) + { + switch (event.key.keysym.sym) + { + case SDLK_UP: + selected = (selected - 1 + MENU_ITEMS) % MENU_ITEMS; + break; + + case SDLK_DOWN: + selected = (selected + 1) % MENU_ITEMS; + break; + + case SDLK_RETURN: + case SDLK_KP_ENTER: + switch (selected) + { + case 0 : // "fddload - Load floppy disk image", + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".img"); + file_count = load_iso_files("/mnt", files, 100, ".img"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".img"); + state = STATE_FILESELECT_FLOPPY; + break; + + case 1 : // "cdload - Load CD-ROM image", + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".iso"); + file_count = load_iso_files("/mnt", files, 100, ".iso"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".iso"); + state = STATE_FILESELECT_CD; + break; + + case 2 : // "rdiskload - Load removable disk image", + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".img"); + file_count = load_iso_files("/mnt", files, 100, ".img"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".img"); + state = STATE_FILESELECT_RDISK; + break; + + case 3 : // "cartload - Load cartridge image", + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".img"); + file_count = load_iso_files("/mnt", files, 100, ".img"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".img"); + state = STATE_FILESELECT_CART; + break; + + case 4 : // "moload - Load MO image", + reset_iso_files(); + file_count = load_iso_files(".", files, 100, ".img"); + file_count = load_iso_files("/mnt", files, 100, ".img"); + file_count = load_iso_files("/mnt/usbkey", files, 100, ".img"); + state = STATE_FILESELECT_MO; + break; + + case 5 : // "fddeject - eject disk from floppy drive", + osd_cmd_run("fddeject 0"); + return 0; + + case 6 : // "cdeject - eject disc from CD-ROM drive", + osd_cmd_run("cdeject 0"); + return 0; + + case 7 : // "rdiskeject - eject removable disk", + osd_cmd_run("rdiskeject 0"); + return 0; + + case 8 : // "carteject - eject cartridge", + osd_cmd_run("carteject 0"); + return 0; + + case 9 : // "moeject - eject image from MO drive", + osd_cmd_run("moeject 0"); + return 0; + + case 10 : // "hardreset - hard reset the emulated system", + osd_cmd_run("hardreset"); + return 0; + + /* better not pause ourself, we will be unable to get out of it + case 11 : // "pause - pause the the emulated system", + osd_cmd_run("pause"); + return 0; + */ + + case 11 : // "fullscreen - toggle fullscreen", + osd_cmd_run("fullscreen"); + return 0; + + case 12 : // "version - print version and license information", + osd_cmd_run("version"); + return 0; + + case 13 : // "exit - exit 86Box", + osd_cmd_run("exit"); + return 0; + + case 14 : // "close OSD" + // return zero does directly close the OSD + return 0; + } + break; + } + } + else if (state == STATE_FILESELECT_FLOPPY || state == STATE_FILESELECT_CD || state == STATE_FILESELECT_RDISK || state == STATE_FILESELECT_CART || state == STATE_FILESELECT_MO) + { + if (file_count == 0) + { + // no files, there is nothing else to do + if (event.key.keysym.sym == SDLK_ESCAPE) { + state = STATE_MENU; + } + } + else + { + switch (event.key.keysym.sym) { + case SDLK_UP: + if (file_selected > 0) { + file_selected--; + if (file_selected < scroll_offset) { + scroll_offset--; + } + } + break; + case SDLK_DOWN: + if (file_selected < file_count - 1) { + file_selected++; + if (file_selected >= scroll_offset + max_visible) { + scroll_offset++; + } + } + break; + + case SDLK_RETURN: + case SDLK_KP_ENTER: + { + char cmd[1280] = ""; + + if (state == STATE_FILESELECT_FLOPPY) + sprintf(cmd, "fddload 0 %s 0", files[file_selected]); + if (state == STATE_FILESELECT_CD) + sprintf(cmd, "cdload 0 %s", files[file_selected]); + if (state == STATE_FILESELECT_RDISK) + sprintf(cmd, "rdiskload 0 %s 0", files[file_selected]); + if (state == STATE_FILESELECT_CART) + sprintf(cmd, "cartload 0 %s 0", files[file_selected]); + if (state == STATE_FILESELECT_MO) + sprintf(cmd, "moload 0 %s 0", files[file_selected]); + + unix_executeLine(cmd); + state = STATE_MENU; + } + return 0; + + case SDLK_ESCAPE: + state = STATE_MENU; + break; + } + } + } + } + + // Keep it open + return 1; +} + +void osd_ui_sb_update_icon_state(UNUSED(int tag), UNUSED(int state)) +{ +} + +void osd_ui_sb_update_icon(UNUSED(int tag), UNUSED(int active)) +{ +} + +void osd_ui_sb_update_icon_write(UNUSED(int tag), UNUSED(int active)) +{ +} + +void osd_ui_sb_update_icon_wp(UNUSED(int tag), UNUSED(int state)) +{ +} diff --git a/src/unix/unix_sdl.c b/src/unix/unix_sdl.c index 651822335a1..8d3a71002c5 100644 --- a/src/unix/unix_sdl.c +++ b/src/unix/unix_sdl.c @@ -16,6 +16,7 @@ #include <86box/video.h> #include <86box/ui.h> #include <86box/version.h> +#include <86box/unix_osd.h> #include <86box/unix_sdl.h> #define RENDERER_FULL_SCREEN 1 @@ -45,7 +46,7 @@ static int cur_wy = 0; static int cur_ww = 0; static int cur_wh = 0; static volatile int sdl_enabled = 1; -static SDL_mutex *sdl_mutex = NULL; +SDL_mutex *sdl_mutex = NULL; int mouse_capture; int title_set = 0; int resize_pending = 0; @@ -189,6 +190,9 @@ sdl_real_blit(SDL_Rect *r_src) if (ret) fprintf(stderr, "SDL: unable to copy texture to renderer (%s)\n", SDL_GetError()); + // give the osd an opportunity to draw itself + osd_present(); + SDL_RenderPresent(sdl_render); } @@ -214,6 +218,7 @@ sdl_blit(int x, int y, int w, int h) sdl_resize(resize_w, resize_h); resize_pending = 0; } + r_src.x = x; r_src.y = y; r_src.w = w; @@ -314,6 +319,7 @@ sdl_select_best_hw_driver(void) void sdl_reinit_texture(void) { + osd_deinit(); sdl_destroy_texture(); if (sdl_flags & RENDERER_HARDWARE) { @@ -324,6 +330,7 @@ sdl_reinit_texture(void) sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 2048, 2048); + osd_init(); } void @@ -412,6 +419,10 @@ sdl_init_common(int flags) return (0); } + // Ensure mouse and touchpads behaves the same for us, dunno if these really do something + SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "1"); + SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1"); + if (flags & RENDERER_HARDWARE) { if (flags & RENDERER_OPENGL) { SDL_SetHint(SDL_HINT_RENDER_DRIVER, "OpenGL"); diff --git a/src/utils/crc32.c b/src/utils/crc32.c index 6993654aea5..a8d5dde26a8 100644 --- a/src/utils/crc32.c +++ b/src/utils/crc32.c @@ -22,7 +22,9 @@ #include #include -#define __USE_LARGEFILE64 +#ifndef __USE_LARGEFILE64 +#define __USE_LARGEFILE64 1 +#endif #include #if (defined(__HAIKU__) || defined(__unix__) || defined(__APPLE__)) && !defined(__linux__) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 98a9cb38554..201ef4a40b3 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -38,9 +38,12 @@ add_library(vid OBJECT # Clock generator chips clockgen/vid_clockgen_av9194.c + clockgen/vid_clockgen_icd2047.c clockgen/vid_clockgen_icd2061.c + clockgen/vid_clockgen_ics1494.c clockgen/vid_clockgen_ics2494.c clockgen/vid_clockgen_ics2595.c + clockgen/vid_clockgen_ics90c64a.c # DDC / monitor identification stuff vid_ddc.c diff --git a/src/video/clockgen/vid_clockgen_icd2047.c b/src/video/clockgen/vid_clockgen_icd2047.c new file mode 100644 index 00000000000..cc2e003bf6d --- /dev/null +++ b/src/video/clockgen/vid_clockgen_icd2047.c @@ -0,0 +1,131 @@ +/* + * 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. + * + * ICD2047 clock generator emulation. + * + * Used by the V7 chips. + * + * Authors: TheCollector1995. + * + * Copyright 2025 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> + +typedef struct icd2047_t { + float freq[32]; +} icd2047_t; + +#ifdef ENABLE_ICD2047_LOG +int icd2047_do_log = ENABLE_ICD2047_LOG; + +static void +icd2047_log(const char *fmt, ...) +{ + va_list ap; + + if (icd2047_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define icd2047_log(fmt, ...) +#endif + +float +icd2047_getclock(int clock, void *priv) +{ + const icd2047_t *icd2047 = (icd2047_t *) priv; + + if (clock > 31) + clock = 31; + + return icd2047->freq[clock]; +} + +static void * +icd2047_init(const device_t *info) +{ + icd2047_t *icd2047 = (icd2047_t *) malloc(sizeof(icd2047_t)); + memset(icd2047, 0, sizeof(icd2047_t)); + + switch (info->local) { + case 20: + /* ICD2047-20 for Headland series */ + icd2047->freq[0x00] = 25175000.0; + icd2047->freq[0x01] = 28322000.0; + icd2047->freq[0x02] = 40000000.0; + icd2047->freq[0x03] = 32500000.0; + icd2047->freq[0x04] = 50350000.0; + icd2047->freq[0x05] = 65000000.0; + icd2047->freq[0x06] = 38000000.0; + icd2047->freq[0x07] = 44900000.0; + icd2047->freq[0x08] = 25175000.0; + icd2047->freq[0x09] = 28322000.0; + icd2047->freq[0x0a] = 80000000.0; + icd2047->freq[0x0b] = 32500000.0; + icd2047->freq[0x0c] = 50350000.0; + icd2047->freq[0x0d] = 65000000.0; + icd2047->freq[0x0e] = 76000000.0; + icd2047->freq[0x0f] = 44900000.0; + icd2047->freq[0x10] = 25175000.0; + icd2047->freq[0x11] = 44900000.0; + icd2047->freq[0x12] = 28322000.0; + icd2047->freq[0x13] = 38000000.0; + icd2047->freq[0x14] = 40000000.0; + icd2047->freq[0x15] = 46000000.0; + icd2047->freq[0x16] = 48000000.0; + icd2047->freq[0x17] = 60000000.0; + icd2047->freq[0x18] = 65000000.0; + icd2047->freq[0x19] = 72000000.0; + icd2047->freq[0x1a] = 74000000.0; + icd2047->freq[0x1b] = 76000000.0; + icd2047->freq[0x1c] = 78000000.0; + icd2047->freq[0x1d] = 80000000.0; + icd2047->freq[0x1e] = 100000000.0; + icd2047->freq[0x1f] = 110000000.0; + break; + + default: + break; + } + + return icd2047; +} + +static void +icd2047_close(void *priv) +{ + icd2047_t *icd2047 = (icd2047_t *) priv; + + if (icd2047) + free(icd2047); +} + +const device_t icd2047_20_device = { + .name = "ICD2047-20 Clock Generator", + .internal_name = "icd2047_20", + .flags = 0, + .local = 20, + .init = icd2047_init, + .close = icd2047_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/clockgen/vid_clockgen_ics1494.c b/src/video/clockgen/vid_clockgen_ics1494.c new file mode 100644 index 00000000000..62af66bcd49 --- /dev/null +++ b/src/video/clockgen/vid_clockgen_ics1494.c @@ -0,0 +1,157 @@ +/* + * 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. + * + * ICS1494 clock generator emulation. + * + * Used by the V7 and PVGA chips. + * + * Authors: TheCollector1995. + * + * Copyright 2025 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> + +typedef struct ics1494_t { + float freq[32]; +} ics1494_t; + +#ifdef ENABLE_ICS1494_LOG +int ics1494_do_log = ENABLE_ICS1494_LOG; + +static void +ics1494_log(const char *fmt, ...) +{ + va_list ap; + + if (ics1494_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ics1494_log(fmt, ...) +#endif + +float +ics1494_getclock(int clock, void *priv) +{ + const ics1494_t *ics1494 = (ics1494_t *) priv; + + if (clock > 31) + clock = 31; + + return ics1494->freq[clock]; +} + +static void * +ics1494_init(const device_t *info) +{ + ics1494_t *ics1494 = (ics1494_t *) malloc(sizeof(ics1494_t)); + memset(ics1494, 0, sizeof(ics1494_t)); + + switch (info->local) { + case 540: + /* ICS1494(M)-540 for Radius series */ + ics1494->freq[0x00] = 57283000.0; + ics1494->freq[0x01] = 12273000.0; + ics1494->freq[0x02] = 14500000.0; + ics1494->freq[0x03] = 15667000.0; + ics1494->freq[0x04] = 112000000.0; + ics1494->freq[0x05] = 126000000.0; + ics1494->freq[0x06] = 30240000.0; + ics1494->freq[0x07] = 91200000.0; + ics1494->freq[0x08] = 120000000.0; + ics1494->freq[0x09] = 48000000.0; + ics1494->freq[0x0a] = 50675000.0; + ics1494->freq[0x0b] = 55300000.0; + ics1494->freq[0x0c] = 64000000.0; + ics1494->freq[0x0d] = 68750000.0; + ics1494->freq[0x0e] = 88500000.0; + ics1494->freq[0x0f] = 51270000.0; + ics1494->freq[0x10] = 100000000.0; + ics1494->freq[0x11] = 95200000.0; + ics1494->freq[0x12] = 55000000.0; + ics1494->freq[0x13] = 60000000.0; + ics1494->freq[0x14] = 63000000.0; + ics1494->freq[0x15] = 99522000.0; + ics1494->freq[0x16] = 130000000.0; + ics1494->freq[0x17] = 80000000.0; + ics1494->freq[0x18] = 25175000.0; + ics1494->freq[0x19] = 28322000.0; + ics1494->freq[0x1a] = 48000000.0; + ics1494->freq[0x1b] = 76800000.0; + ics1494->freq[0x1c] = 38400000.0; + ics1494->freq[0x1d] = 43200000.0; + ics1494->freq[0x1e] = 61440000.0; + ics1494->freq[0x1f] = 0.0; + break; + + case 541: + /* ICS1494(M)-540 for Radius HT209 */ + ics1494->freq[0x00] = 25175000.0; + ics1494->freq[0x01] = 28322000.0; + ics1494->freq[0x02] = 61440000.0; /*FCLK*/ + ics1494->freq[0x03] = 74000000.0; /*XRESM*/ + ics1494->freq[0x04] = 50350000.0; + ics1494->freq[0x05] = 65000000.0; + ics1494->freq[0x06] = 37575000.0; /*FCLK*/ + ics1494->freq[0x07] = 40000000.0; + break; + + default: + break; + } + + return ics1494; +} + +static void +ics1494_close(void *priv) +{ + ics1494_t *ics1494 = (ics1494_t *) priv; + + if (ics1494) + free(ics1494); +} + +const device_t ics1494m_540_device = { + .name = "ICS2494M-540 Clock Generator", + .internal_name = "ics1494m_540", + .flags = 0, + .local = 540, + .init = ics1494_init, + .close = ics1494_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t ics1494m_540_radius_ht209_device = { + .name = "ICS2494M-540 (Radius HT209) Clock Generator", + .internal_name = "ics1494m_540_radius_ht209", + .flags = 0, + .local = 541, + .init = ics1494_init, + .close = ics1494_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/clockgen/vid_clockgen_ics2494.c b/src/video/clockgen/vid_clockgen_ics2494.c index f9f4fbcb1f5..0776d97cab1 100644 --- a/src/video/clockgen/vid_clockgen_ics2494.c +++ b/src/video/clockgen/vid_clockgen_ics2494.c @@ -290,7 +290,7 @@ ics2494_init(const device_t *info) ics2494->freq[15] = 65000000.0; break; case 305: - /* ICS2494A(N)-205 for S3 86C924 */ + /* ICS2494A(N)-305 for S3 86C924 */ ics2494->freq[0x0] = 25175000.0; ics2494->freq[0x1] = 28322000.0; ics2494->freq[0x2] = 40000000.0; @@ -308,6 +308,25 @@ ics2494_init(const device_t *info) ics2494->freq[0xe] = 75000000.0; ics2494->freq[0xf] = 94500000.0; break; + case 324: + /* ICS2494A(N)-324 for Tseng ET4000/W32 series */ + ics2494->freq[0x0] = 50000000.0; + ics2494->freq[0x1] = 56644000.0; + ics2494->freq[0x2] = 65000000.0; + ics2494->freq[0x3] = 72000000.0; + ics2494->freq[0x4] = 80000000.0; + ics2494->freq[0x5] = 89800000.0; + ics2494->freq[0x6] = 63000000.0; + ics2494->freq[0x7] = 75000000.0; + ics2494->freq[0x8] = 83078000.0; + ics2494->freq[0x9] = 93463000.0; + ics2494->freq[0xa] = 100000000.0; + ics2494->freq[0xb] = 104000000.0; + ics2494->freq[0xc] = 108000000.0; + ics2494->freq[0xd] = 120000000.0; + ics2494->freq[0xe] = 130000000.0; + ics2494->freq[0xf] = 134700000.0; + break; default: break; @@ -339,6 +358,20 @@ const device_t ics2494an_305_device = { .config = NULL }; +const device_t ics2494an_324_device = { + .name = "ICS2494AN-324 Clock Generator", + .internal_name = "ics2494an_324", + .flags = 0, + .local = 324, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t ati18810_28800_device = { .name = "ATI 18810 (ATI 28800) Clock Generator", .internal_name = "ati18810_28800", diff --git a/src/video/clockgen/vid_clockgen_ics90c64a.c b/src/video/clockgen/vid_clockgen_ics90c64a.c new file mode 100644 index 00000000000..f0573f16128 --- /dev/null +++ b/src/video/clockgen/vid_clockgen_ics90c64a.c @@ -0,0 +1,116 @@ +/* + * 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. + * + * ICS90C64A clock generator emulation. + * + * Used by the PVGA chips. + * + * Authors: TheCollector1995. + * + * Copyright 2025 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> + +typedef struct ics90c64a_t { + float freq[17]; +} ics90c64a_t; + +#ifdef ENABLE_ICS90C64A_LOG +int ics90c64a_do_log = ENABLE_ICS90C64A_LOG; + +static void +ics90c64a_log(const char *fmt, ...) +{ + va_list ap; + + if (ics90c64a_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ics90c64a_log(fmt, ...) +#endif + +float +ics90c64a_vclk_getclock(int clock, void *priv) +{ + const ics90c64a_t *ics90c64a = (ics90c64a_t *) priv; + + if (clock > 16) + clock = 16; + + return ics90c64a->freq[clock]; +} + +static void * +ics90c64a_init(const device_t *info) +{ + ics90c64a_t *ics90c64a = (ics90c64a_t *) malloc(sizeof(ics90c64a_t)); + memset(ics90c64a, 0, sizeof(ics90c64a_t)); + + switch (info->local) { + case 903: + /* ICS90C64A-903 for PVGA chip series, also per debian svgatext mode textconfig */ + ics90c64a->freq[0] = 25175000.0; + ics90c64a->freq[1] = 28322000.0; + ics90c64a->freq[2] = 65000000.0; + ics90c64a->freq[3] = 36000000.0; + ics90c64a->freq[4] = 40000000.0; + ics90c64a->freq[5] = 50000000.0; + ics90c64a->freq[6] = 32000000.0; + ics90c64a->freq[7] = 45000000.0; + ics90c64a->freq[8] = 31500000.0; + ics90c64a->freq[9] = 35500000.0; + ics90c64a->freq[0x0a] = 74500000.0; + ics90c64a->freq[0x0b] = 72000000.0; + ics90c64a->freq[0x0c] = 30000000.0; + ics90c64a->freq[0x0d] = 77000000.0; + ics90c64a->freq[0x0e] = 86000000.0; + ics90c64a->freq[0x0f] = 80000000.0; + ics90c64a->freq[0x10] = 60000000.0; + break; + + default: + break; + } + + return ics90c64a; +} + +static void +ics90c64a_close(void *priv) +{ + ics90c64a_t *ics90c64a = (ics90c64a_t *) priv; + + if (ics90c64a) + free(ics90c64a); +} + +const device_t ics90c64a_903_device = { + .name = "ICS90C64A-903 Clock Generator", + .internal_name = "ics90c64a_903", + .flags = 0, + .local = 903, + .init = ics90c64a_init, + .close = ics90c64a_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/ramdac/vid_ramdac_att20c49x.c b/src/video/ramdac/vid_ramdac_att20c49x.c index 2d8d6a3044d..3776e661600 100644 --- a/src/video/ramdac/vid_ramdac_att20c49x.c +++ b/src/video/ramdac/vid_ramdac_att20c49x.c @@ -42,12 +42,6 @@ att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga) att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; ramdac->ctrl = val; switch ((ramdac->ctrl >> 5) & 7) { - case 0: - case 1: - case 2: - case 3: - svga->bpp = 8; - break; case 4: case 5: svga->bpp = 15; @@ -60,10 +54,12 @@ att49x_ramdac_control(uint8_t val, void *priv, svga_t *svga) break; default: + svga->bpp = 8; break; } if (ramdac->type == ATT_490 || ramdac->type == ATT_491) svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); + svga_recalctimings(svga); } diff --git a/src/video/ramdac/vid_ramdac_att2xc498.c b/src/video/ramdac/vid_ramdac_att2xc498.c index 141ffa4b459..21c6770a3f0 100644 --- a/src/video/ramdac/vid_ramdac_att2xc498.c +++ b/src/video/ramdac/vid_ramdac_att2xc498.c @@ -45,7 +45,7 @@ att498_ramdac_control(uint8_t val, void *priv, svga_t *svga) svga->bpp = 8; break; case 1: - if (ramdac->ctrl & 4) + if (ramdac->ctrl & 0x04) svga->bpp = 15; else svga->bpp = 8; @@ -63,7 +63,7 @@ att498_ramdac_control(uint8_t val, void *priv, svga_t *svga) break; } - svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); + svga_set_ramdac_type(svga, (ramdac->ctrl & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT); svga_recalctimings(svga); } @@ -132,7 +132,7 @@ att498_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) ramdac->state++; break; case 6: - temp = ramdac->ctrl; + temp = 0x98; ramdac->state = 0; break; default: diff --git a/src/video/ramdac/vid_ramdac_bt48x.c b/src/video/ramdac/vid_ramdac_bt48x.c index be6499990c3..2133e02a03c 100644 --- a/src/video/ramdac/vid_ramdac_bt48x.c +++ b/src/video/ramdac/vid_ramdac_bt48x.c @@ -56,9 +56,9 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) { if ((!(ramdac->cmd_r2 & 0x20)) || ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x60))) svga->bpp = 8; - else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x40)) + else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x20)) svga->bpp = 24; - else + else { switch (ramdac->cmd_r1 & 0x60) { case 0x00: svga->bpp = 32; @@ -71,14 +71,18 @@ bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) break; case 0x40: svga->bpp = 8; + svga->gdcreg[5] &= ~0x60; + svga->gdcreg[5] |= 0x40; break; case 0x60: svga->bpp = 4; + svga->gdcreg[5] &= ~0x60; break; default: break; } + } svga_recalctimings(svga); } @@ -366,15 +370,14 @@ bt48x_recalctimings(void *priv, svga_t *svga) svga->clock_multiplier = 0; svga->multiplexing_rate = 0; svga->true_color_bypass = 0; - if (ramdac->cmd_r3 & 0x08) { /* x2 clock multiplier */ - //pclog("2x multiplier.\n"); + if (ramdac->cmd_r3 & 0x08) /* x2 clock multiplier */ svga->clock_multiplier = 1; - } + svga->multiplexing_rate = (ramdac->cmd_r1 & 0x60) >> 5; if (svga->bpp >= 15) svga->true_color_bypass = !!(ramdac->cmd_r1 & 0x10); - //pclog("CR0=%02x, CR1=%02x, CR2=%02x.\n", ramdac->cmd_r0, ramdac->cmd_r1, ramdac->cmd_r2); + pclog("CR0=%02x, CR1=%02x, CR2=%02x.\n", ramdac->cmd_r0, ramdac->cmd_r1, ramdac->cmd_r2); } void diff --git a/src/video/ramdac/vid_ramdac_ibm_rgb528.c b/src/video/ramdac/vid_ramdac_ibm_rgb528.c index bded466d1b8..09cabeb0a1f 100644 --- a/src/video/ramdac/vid_ramdac_ibm_rgb528.c +++ b/src/video/ramdac/vid_ramdac_ibm_rgb528.c @@ -60,6 +60,7 @@ typedef union ibm_rgb528_pixel32_t { } ibm_rgb528_pixel32_t; typedef struct ibm_rgb528_ramdac_t { + int type; PALETTE extpal; uint32_t extpallook[256]; uint8_t indexed_data[2048]; @@ -627,19 +628,21 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *s case 0x02a: case 0x02c: case 0x02e: - if (ramdac->indexed_data[0x0002] & 0x01) { - switch (ramdac->indexed_data[0x0010] & 0x07) { - case 0x00: - case 0x02: - ramdac->pix_f[ramdac->index - 0x0020] = val; - break; - case 0x01: - case 0x03: - ramdac->pix_m[(ramdac->index - 0x0020) >> 1] = val; - break; - default: - break; - } + switch (ramdac->indexed_data[0x0010] & 0x03) { + case 0x00: + ramdac->pix_f[(ramdac->index - 0x0020)] = val; + break; + case 0x01: + ramdac->pix_m[(ramdac->index - 0x0020) >> 1] = val; + break; + case 0x02: + ramdac->pix_f[(ramdac->index - 0x0020)] = val; + break; + case 0x03: + ramdac->pix_m[(ramdac->index - 0x0020) >> 1] = val; + break; + default: + break; } break; case 0x021: @@ -650,19 +653,21 @@ ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *s case 0x02b: case 0x02d: case 0x02f: - if (ramdac->indexed_data[0x0002] & 0x01) { - switch (ramdac->indexed_data[0x010] & 0x07) { - case 0x00: - case 0x02: - ramdac->pix_f[ramdac->index - 0x0020] = val; - break; - case 0x01: - case 0x03: - ramdac->pix_n[(ramdac->index - 0x0020) >> 1] = val; - break; - default: - break; - } + switch (ramdac->indexed_data[0x0010] & 0x03) { + case 0x00: + ramdac->pix_f[(ramdac->index - 0x0020)] = val; + break; + case 0x01: + ramdac->pix_n[(ramdac->index - 0x0020) >> 1] = val; + break; + case 0x02: + ramdac->pix_f[(ramdac->index - 0x0020)] = val; + break; + case 0x03: + ramdac->pix_n[(ramdac->index - 0x0020) >> 1] = val; + break; + default: + break; } break; @@ -868,7 +873,52 @@ ibm_rgb528_recalctimings(void *priv, svga_t *svga) { const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; - svga->interlace = ramdac->indexed_data[0x071] & 0x20; + svga->interlace = !!(ramdac->indexed_data[0x071] & 0x20); + //pclog("MiscClockControl idx002=%02x, SystemClockControl idx008=%02x, Misc2 idx071=%02x, Misc1 idx070=%02x, Misc4 idx073=%02x.\n", + // ramdac->indexed_data[0x002], ramdac->indexed_data[0x008], ramdac->indexed_data[0x071], ramdac->indexed_data[0x070], ramdac->indexed_data[0x073]); + + if (ramdac->indexed_data[0x071] & 0x01) { + if ((ramdac->indexed_data[0x070] & 0x03) == 0x03) { + switch ((ramdac->indexed_data[0x002] & 0x0e) >> 1) { + case 0x00: + default: + svga->clock_multiplier = 0; + break; + case 0x01: + svga->clock_multiplier = 1; + break; + case 0x02: + svga->clock_multiplier = 2; + break; + case 0x03: + svga->clock_multiplier = 3; + break; + case 0x04: + svga->clock_multiplier = 4; + break; + } + } else if ((ramdac->indexed_data[0x070] & 0x03) == 0x01) { + switch ((ramdac->indexed_data[0x002] & 0x0e) >> 1) { + case 0x00: + default: + svga->clock_multiplier = 1; + svga->clock *= 2.0; + break; + case 0x01: + svga->clock_multiplier = 1; + break; + case 0x02: + svga->clock_multiplier = 2; + break; + case 0x03: + svga->clock_multiplier = 3; + break; + case 0x04: + svga->clock_multiplier = 4; + break; + } + } + } if (svga->scrblank || !svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { @@ -904,49 +954,47 @@ ibm_rgb528_recalctimings(void *priv, svga_t *svga) float ibm_rgb528_getclock(int clock, void *priv) { - const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; - int pll_vco_div_cnt; - int pll_df; - int pll_ref_div_cnt; - int ddot_divs[8] = { 1, 2, 4, 8, 16, 1, 1, 1 }; - int ddot_div = ddot_divs[(ramdac->indexed_data[0x0002] >> 1) & 0x07]; - float f_pll; - - clock &= 0x03; - - if (ramdac->indexed_data[0x0002] & 0x01) { - switch (ramdac->indexed_data[0x0010] & 0x07) { - case 0x00: - default: - pll_vco_div_cnt = ramdac->pix_f[clock] & 0x3f; - pll_df = 8 >> (ramdac->pix_f[clock] >> 6); - pll_ref_div_cnt = ramdac->pix_f_ref_div & 0x1f; - break; - case 0x01: - pll_vco_div_cnt = ramdac->pix_m[clock] & 0x3f; - pll_df = 8 >> (ramdac->pix_m[clock] >> 6); - pll_ref_div_cnt = ramdac->pix_n[clock] & 0x1f; - break; - case 0x02: - pll_vco_div_cnt = ramdac->pix_f[ramdac->indexed_data[0x0011] & 0x0f] & 0x3f; - pll_df = 8 >> (ramdac->pix_f[ramdac->indexed_data[0x0011] & 0x0f] >> 6); - pll_ref_div_cnt = ramdac->pix_f_ref_div & 0x1f; - break; - case 0x03: - pll_vco_div_cnt = ramdac->pix_m[ramdac->indexed_data[0x0011] & 0x07] & 0x3f; - pll_df = 8 >> (ramdac->pix_m[ramdac->indexed_data[0x0011] & 0x07] >> 6); - pll_ref_div_cnt = ramdac->pix_n[ramdac->indexed_data[0x0011] & 0x07] & 0x1f; - break; - } - } else { - pll_vco_div_cnt = ramdac->indexed_data[0x0016] & 0x3f; - pll_df = 8 >> (ramdac->indexed_data[0x0016] >> 6); - pll_ref_div_cnt = ramdac->indexed_data[0x0015] & 0x1f; + const ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; + int pll_vco_div_cnt; + int pll_df; + int pll_ref_div_cnt; + int ddot_divs[8] = { 1, 2, 4, 8, 16, 1, 1, 1 }; + int ddot_div = ddot_divs[(ramdac->indexed_data[0x0002] >> 1) & 0x07]; + float f_pll; + + if (clock == 0) + return 25175000.0f; + if (clock == 1) + return 28322000.0f; + + switch (ramdac->indexed_data[0x0010] & 0x03) { + case 0x00: + default: + pll_vco_div_cnt = ramdac->pix_f[clock & 0x03] & 0x3f; + pll_df = 8 >> (ramdac->pix_f[clock & 0x03] >> 6); + pll_ref_div_cnt = ramdac->pix_f_ref_div & 0x1f; + break; + case 0x01: + pll_vco_div_cnt = ramdac->pix_m[clock & 0x03] & 0x3f; + pll_df = 8 >> (ramdac->pix_m[clock & 0x03] >> 6); + pll_ref_div_cnt = ramdac->pix_n[clock & 0x03] & 0x1f; + break; + case 0x02: + pll_vco_div_cnt = ramdac->pix_f[ramdac->indexed_data[0x0011] & 0x0f] & 0x3f; + pll_df = 8 >> (ramdac->pix_f[ramdac->indexed_data[0x0011] & 0x0f] >> 6); + pll_ref_div_cnt = ramdac->pix_f_ref_div & 0x1f; + break; + case 0x03: + pll_vco_div_cnt = ramdac->pix_m[ramdac->indexed_data[0x0011] & 0x0f] & 0x3f; + pll_df = 8 >> (ramdac->pix_m[ramdac->indexed_data[0x0011] & 0x0f] >> 6); + pll_ref_div_cnt = ramdac->pix_n[ramdac->indexed_data[0x0011] & 0x0f] & 0x1f; + break; } - f_pll = ramdac->ref_clock * (float) (pll_vco_div_cnt + 65) / (float) (pll_ref_div_cnt * pll_df); f_pll /= (float) ddot_div; + //pclog("PIXCTRL1=%02x, clock=%d, m=%d, df=%d, n=%d, ctrl2=%02x, miscclock=%02x, sysclock=%02x, f_pll=%f.\n", + // ramdac->indexed_data[0x010], clock, pll_vco_div_cnt, pll_df, pll_ref_div_cnt, ramdac->indexed_data[0x011], ramdac->indexed_data[0x002], ramdac->indexed_data[0x008], f_pll); return f_pll; } @@ -1073,19 +1121,11 @@ ibm_rgb528_ramdac_init(UNUSED(const device_t *info)) ramdac->smlc_part = 0x0100; ramdac->ref_clock = 14318184.0f; + ramdac->pix_f_ref_div = 0x07; /*Per datasheet regarding the reference clock value.*/ ramdac->indexed_data[0x0008] = 0x0001; - ramdac->indexed_data[0x0014] = 0x0005; ramdac->indexed_data[0x0015] = 0x0008; ramdac->indexed_data[0x0016] = 0x0041; - ramdac->indexed_data[0x0020] = 0x0005; - ramdac->indexed_data[0x0021] = 0x000e; - - ramdac->pix_f_ref_div = 0x0005; - ramdac->pix_f[0] = 0x0005; - ramdac->pix_f[1] = 0x000e; - ramdac->pix_m[0] = 0x0005; - ramdac->pix_n[0] = 0x000e; return ramdac; } diff --git a/src/video/ramdac/vid_ramdac_sdac.c b/src/video/ramdac/vid_ramdac_sdac.c index 2b2890307cc..a88cdcaef83 100644 --- a/src/video/ramdac/vid_ramdac_sdac.c +++ b/src/video/ramdac/vid_ramdac_sdac.c @@ -49,6 +49,7 @@ typedef struct sdac_ramdac_t { int rs2; uint8_t type; uint8_t command; + float ref_clock; } sdac_ramdac_t; static void @@ -275,11 +276,21 @@ sdac_getclock(int clock, void *priv) n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; n2 = ((ramdac->regs[clock] >> 13) & 0x07); n2 = (1 << n2); - t = (14318184.0f * (float) m) / (float) (n1 * n2); + t = (ramdac->ref_clock * (float) m) / (float) (n1 * n2); + //pclog("SDACClock=%d, regs val=%04x.\n", clock, ramdac->regs[clock]); return t; } +void +sdac_set_ref_clock(void *priv, float ref_clock) +{ + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; + + if (ramdac != NULL) + ramdac->ref_clock = ref_clock; +} + void * sdac_ramdac_init(const device_t *info) { @@ -288,6 +299,7 @@ sdac_ramdac_init(const device_t *info) ramdac->type = info->local; + ramdac->ref_clock = 14318184.0f; ramdac->regs[0] = 0x6128; ramdac->regs[1] = 0x623d; diff --git a/src/video/ramdac/vid_ramdac_stg1702.c b/src/video/ramdac/vid_ramdac_stg1702.c index 8a2d008dd82..6c094570486 100644 --- a/src/video/ramdac/vid_ramdac_stg1702.c +++ b/src/video/ramdac/vid_ramdac_stg1702.c @@ -31,6 +31,7 @@ typedef struct stg_ramdac_t { int magic_count, index; uint8_t regs[256]; uint8_t command; + int type; } stg_ramdac_t; static int stg_state_read[2][8] = { @@ -46,6 +47,8 @@ stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) switch (ramdac->regs[3]) { default: case 0: + svga->bpp = 8; + break; case 5: case 7: svga->bpp = 8; @@ -176,7 +179,7 @@ stg_ramdac_in(uint16_t addr, void *priv, svga_t *svga) temp = 0x44; break; case 1: - temp = 0x03; + temp = ramdac->type; break; case 7: temp = 0x88; @@ -216,22 +219,24 @@ stg_getclock(int clock, void *priv) float t; int m; int n; - int n2; - const uint16_t *c; + int d; + int d2; + uint16_t c; if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; - m = (*c & 0xff) + 2; /* B+2 */ - n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ - n2 = ((*c >> 13) & 0x07); /* D */ - n2 = (1 << n2); - t = (14318184.0f * (float) m) / (float) (n * n2); + c = ramdac->regs[0x20 + (clock << 1)]; + c |= (ramdac->regs[0x21 + (clock << 1)] << 8); + m = (c & 0xff) + 2; /* B+2 */ + n = ((c >> 8) & 0x1f) + 2; /* N1+2 */ + d = ((c >> 13) & 0x07); /* D */ + d2 = (1 << d); + t = (14318184.0f * (float) m) / (float) (n * d2); + //pclog("RAMDAC vclk val=0x%02x, vclk v=%d low, D=%d, t=%f.\n", ramdac->regs[0x20 + (clock << 1)], clock, d2, t); return t; } @@ -241,6 +246,8 @@ stg_ramdac_init(UNUSED(const device_t *info)) stg_ramdac_t *ramdac = (stg_ramdac_t *) malloc(sizeof(stg_ramdac_t)); memset(ramdac, 0, sizeof(stg_ramdac_t)); + ramdac->type = info->local & 0xff; + return ramdac; } @@ -253,11 +260,25 @@ stg_ramdac_close(void *priv) free(ramdac); } -const device_t stg_ramdac_device = { - .name = "SGS-Thompson STG170x RAMDAC", +const device_t stg1702_ramdac_device = { + .name = "SGS-Thompson STG1702 RAMDAC", + .internal_name = "stg_ramdac", + .flags = 0, + .local = 2, + .init = stg_ramdac_init, + .close = stg_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + +const device_t stg1703_ramdac_device = { + .name = "SGS-Thompson STG1703 RAMDAC", .internal_name = "stg_ramdac", .flags = 0, - .local = 0, + .local = 3, .init = stg_ramdac_init, .close = stg_ramdac_close, .reset = NULL, diff --git a/src/video/ramdac/vid_ramdac_tvp3026.c b/src/video/ramdac/vid_ramdac_tvp3026.c index 1958fa5880d..73af99075a5 100644 --- a/src/video/ramdac/vid_ramdac_tvp3026.c +++ b/src/video/ramdac/vid_ramdac_tvp3026.c @@ -9,7 +9,6 @@ * Emulation of the Texas Instruments TVP3026 true colour RAMDAC * family. * - * TODO: Clock and other parts. * * Authors: TheCollector1995, * @@ -49,6 +48,7 @@ typedef struct tvp3026_ramdac_t { uint8_t mode; uint8_t pll_addr; uint8_t clock_sel; + uint8_t color_key_ctrl; struct { uint8_t m; uint8_t n; @@ -171,25 +171,24 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; + //pclog("0x09: DACEna=%02x, MainEna=%02x.\n", svga->dac_hwcursor.ena, svga->hwcursor.ena); } break; case 0x0a: /* Indexed Data (RS value = 1010) */ switch (ramdac->ind_idx) { case 0x06: /* Indirect Cursor Control */ ramdac->ccr = val; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; if (!(ramdac->ccr & 0x80)) { - svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_hwcursor.ena = !!(val & 0x03); ramdac->mode = val & 0x03; } else { - svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; svga->dac_hwcursor.ena = !!(ramdac->dcc & 0x03); ramdac->mode = ramdac->dcc & 0x03; } + //pclog("0x0a, indirect 0x06: DACEna=%02x, MainEna=%02x.\n", svga->dac_hwcursor.ena, svga->hwcursor.ena); break; case 0x0f: /* Latch Control */ ramdac->latch_cntl = val; @@ -279,6 +278,9 @@ tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svg } ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); break; + case 0x38: /* Color-Key Control */ + ramdac->color_key_ctrl = val; + break; case 0x39: /* MCLK/Loop Clock Control */ ramdac->mclk = val; break; @@ -470,6 +472,9 @@ tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) break; } break; + case 0x38: /* Color-Key Control */ + temp = ramdac->color_key_ctrl; + break; case 0x39: /* MCLK/Loop Clock Control */ temp = ramdac->mclk; break; @@ -516,11 +521,39 @@ tvp3026_recalctimings(void *priv, svga_t *svga) svga->interlace = !!(ramdac->ccr & 0x40); /* TODO: Figure out gamma correction for 15/16 bpp color. */ svga->lut_map = !!((svga->bpp >= 15 && (svga->bpp != 24)) && (ramdac->true_color & 0xf0) != 0x00); + svga->clock_multiplier = 0; + + //pclog("RAMDAC CLOCKSEL=%02x, MCR=%02x, LoopMCLK=%02x, Latch=%02x.\n", ramdac->clock_sel, ramdac->mcr, ramdac->mclk, ramdac->latch_cntl); if (!(ramdac->clock_sel & 0x70)) { if (ramdac->mcr != 0x98) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; + switch ((ramdac->clock_sel >> 4) & 7) { + case 0: + svga->clock_multiplier = 1; + break; + case 1: + svga->clock_multiplier = 2; + break; + case 2: + svga->clock_multiplier = 4; + break; + case 3: + svga->clock_multiplier = 8; + break; + case 4: + svga->clock_multiplier = 16; + break; + case 5: + svga->clock_multiplier = 32; + break; + case 6: + svga->clock_multiplier = 64; + break; + case 7: + default: + svga->clock_multiplier = 0; + break; + } } } } diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 84cbffedb94..8baa723518a 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -54,9 +54,8 @@ ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn, int mca) strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); fp = nvr_fopen(eeprom->fn, "rb"); size = 128; - if (!fp) { + if (fp == NULL) { if (mca) { - (void) fseek(fp, 2L, SEEK_SET); memset(eeprom->data + 2, 0xff, size - 2); fp = nvr_fopen(eeprom->fn, "wb"); fwrite(eeprom->data, 1, size, fp); diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index f809a6c0ee2..9aa8b687db8 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -547,6 +547,7 @@ mach64_recalctimings(svga_t *svga) svga->rowcount = mach64->crtc_gen_cntl & 1; svga->lut_map = (mach64->type >= MACH64_VT); svga->rowoffset <<= 1; + svga->attrregs[0x13] &= ~0x0f; if (mach64->type == MACH64_GX) ati68860_ramdac_set_render(svga->ramdac, svga); @@ -4897,7 +4898,7 @@ mach64_common_init(const device_t *info) mach64_io_set(mach64); if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot); + pci_add_card((info->local & (1 << 19)) ? PCI_ADD_VIDEO : PCI_ADD_NORMAL, mach64_pci_read, mach64_pci_write, mach64, &mach64->pci_slot); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -4989,11 +4990,13 @@ mach64ct_init(const device_t *info) ati_eeprom_load(&mach64->eeprom, "mach64ct.nvr", 1); - rom_init(&mach64->bios_rom, BIOS_ROMCT_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (!(info->local & (1 << 19))) + rom_init(&mach64->bios_rom, BIOS_ROMCT_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; + svga->adv_flags |= FLAG_PANNING_ATI; return mach64; } @@ -5025,6 +5028,7 @@ mach64vt_init(const device_t *info) mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; + svga->adv_flags |= FLAG_PANNING_ATI; return mach64; } @@ -5056,6 +5060,7 @@ mach64vt2_init(const device_t *info) mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; + svga->adv_flags |= FLAG_PANNING_ATI; return mach64; } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index b0642c0de10..b9092881b60 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -3114,7 +3114,7 @@ mach_recalctimings(svga_t *svga) svga->ati_4color = 0; } - mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, crtlo=%04x, crthi=%04x, vgahdisp=%d.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, mach->accel.crt_offset_lo, mach->accel.crt_offset_hi, svga->hdisp); + mach_log("ON=%d, override=%d, gelo=%04x, gehi=%04x, crtlo=%04x, crthi=%04x, vgahdisp=%d, ibmon=%x, ation=%x, graph1=%x.\n", dev->on, svga->override, mach->accel.ge_offset_lo, mach->accel.ge_offset_hi, mach->accel.crt_offset_lo, mach->accel.crt_offset_hi, svga->hdisp, dev->accel.advfunc_cntl & 0x01, mach->accel.clock_sel & 0x01, svga->gdcreg[6] & 0x01); if (dev->on) { dev->memaddr_latch = 0; /*(mach->accel.crt_offset_lo | (mach->accel.crt_offset_hi << 16)) << 2;*/ @@ -3322,29 +3322,28 @@ mach_recalctimings(svga_t *svga) if (!svga->scrblank && svga->attr_palette_enable) { mach_log("GDCREG5=%02x, ATTR10=%02x, ATI B0 bit 5=%02x, ON=%d.\n", svga->gdcreg[5] & 0x60, svga->attrregs[0x10] & 0x40, mach->regs[0xb0] & 0x20, dev->on); - if (ATI_MACH32) - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); - else - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel ^ 0x08, svga->clock_gen); - - switch ((mach->regs[0xb8] >> 6) & 3) { - case 0: - default: - break; - case 1: - svga->clock *= 2.0; - break; - case 2: - svga->clock *= 3.0; - break; - case 3: - svga->clock *= 4.0; - break; - } mach_log("VGA clock sel=%02x, divide reg=%02x, miscout bits2-3=%x, machregbe bit4=%02x, machregb9 bit1=%02x, charwidth=%d, htotal=%02x, hdisptime=%02x, seqregs1 bit 3=%02x.\n", clock_sel, (mach->regs[0xb8] >> 6) & 3, svga->miscout & 0x0c, mach->regs[0xbe] & 0x10, mach->regs[0xb9] & 0x02, svga->char_width, svga->htotal, svga->hdisp_time, svga->seqregs[1] & 8); if ((svga->gdcreg[6] & 0x01) || (svga->attrregs[0x10] & 0x01)) { if ((svga->gdcreg[5] & 0x40) || (svga->attrregs[0x10] & 0x40) || (mach->regs[0xb0] & 0x20)) { + if (ATI_MACH32) + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel ^ 0x08, svga->clock_gen); + + switch ((mach->regs[0xb8] >> 6) & 3) { + case 1: + svga->clock *= 2.0; + break; + case 2: + svga->clock *= 3.0; + break; + case 3: + svga->clock *= 4.0; + break; + default: + break; + } svga->map8 = svga->pallook; mach_log("Lowres=%x, seqreg[1]bit3=%x.\n", svga->lowres, svga->seqregs[1] & 8); if (svga->lowres) @@ -3357,6 +3356,26 @@ mach_recalctimings(svga_t *svga) } } } + } else { + if (ATI_MACH32) + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel, svga->clock_gen); + else + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clock_sel ^ 0x08, svga->clock_gen); + + switch ((mach->regs[0xb8] >> 6) & 3) { + case 0: + default: + break; + case 1: + svga->clock *= 2.0; + break; + case 2: + svga->clock *= 3.0; + break; + case 3: + svga->clock *= 4.0; + break; + } } } } @@ -4046,6 +4065,10 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u } if (!(dev->accel.advfunc_cntl & 0x01)) dev->on = mach->accel.clock_sel & 0x01; + else { + if (!(mach->regs[0xb0] & 0x20) && !(mach->accel.clock_sel & 0x01)) + dev->on = 0; + } dev->vendor_mode = 1; dev->mode = ATI_MODE; diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index ea0b8872b7b..0a41bec2d5a 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -319,7 +319,7 @@ bochs_vbe_recalctimings(svga_t* svga) svga->vtotal = mode.vtotal; svga->htotal = mode.htotal; svga->hblankstart = mode.hdisplay; - svga->hblankend = mode.hdisplay + (mode.htotal - mode.hdisplay - 1); + svga->hblankend = mode.htotal - 1; svga->vblankstart = svga->dispend; /* no vertical overscan. */ svga->rowcount = 0; svga->hoverride = 1; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index abdde1622a7..95f9e7bf6ca 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -1824,6 +1824,9 @@ gd54xx_recalctimings(svga_t *svga) uint8_t clocksel; uint8_t rdmask; uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + uint8_t m = 0; + int d = 0; + int n = 0; svga->hblankstart = svga->crtc[2]; @@ -1865,6 +1868,34 @@ gd54xx_recalctimings(svga_t *svga) svga->interlace = 0; } + clocksel = (svga->miscout >> 2) & 3; + + if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) + svga->clock = (cpuclock * (float) (1ULL << 32)) / + ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); + else { + n = gd54xx->vclk_n[clocksel] & 0x7f; + d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; + m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; + float freq = (14318184.0F * ((float) n / ((float) d * m))); + if (gd54xx_is_5422(svga)) { + switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) { + case 2: + freq /= 2.0F; + break; + case 4: + if (!gd54xx_is_5434(svga)) + freq /= 3.0F; + break; + + default: + break; + } + } + svga->clock = (cpuclock * (double) (1ULL << 32)) / freq; + } + + svga->bpp = 8; svga->map8 = svga->pallook; if (svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) { if (linedbl) @@ -1874,6 +1905,7 @@ gd54xx_recalctimings(svga_t *svga) if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; + svga->clock *= 2.0; } } } else if (svga->gdcreg[5] & 0x40) @@ -1881,8 +1913,6 @@ gd54xx_recalctimings(svga_t *svga) svga->memaddr_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); - svga->bpp = 8; - if (gd54xx->ramdac.ctrl & 0x80) { if (gd54xx->ramdac.ctrl & 0x40) { if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) @@ -2023,33 +2053,6 @@ gd54xx_recalctimings(svga_t *svga) } } - clocksel = (svga->miscout >> 2) & 3; - - if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = (cpuclock * (float) (1ULL << 32)) / - ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); - else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - uint8_t m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0F * ((float) n / ((float) d * m))); - if (gd54xx_is_5422(svga)) { - switch (svga->seqregs[0x07] & (gd54xx_is_5434(svga) ? 0xe : 6)) { - case 2: - freq /= 2.0F; - break; - case 4: - if (!gd54xx_is_5434(svga)) - freq /= 3.0F; - break; - - default: - break; - } - } - svga->clock = (cpuclock * (double) (1ULL << 32)) / freq; - } - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) diff --git a/src/video/vid_ddc_edid_custom.c b/src/video/vid_ddc_edid_custom.c index 4442fac1027..ae427d7de05 100644 --- a/src/video/vid_ddc_edid_custom.c +++ b/src/video/vid_ddc_edid_custom.c @@ -64,7 +64,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) // Check the beginning of the file for the EDID header. uint64_t header; - fread(&header, sizeof(header), 1, fp); + (void) !fread(&header, sizeof(header), 1, fp); if (header == EDID_HEADER) { // Binary format. Read as is diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 1a8a767e26f..937623689a6 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -639,6 +639,7 @@ static void et4000_recalctimings(svga_t *svga) { const et4000_t *dev = (et4000_t *) svga->priv; + int clk_sel = ((svga->miscout >> 2) & 0x03) | ((svga->crtc[0x34] << 1) & 0x04)| ((svga->crtc[0x31] >> 3) & 0x08); svga->memaddr_latch |= (svga->crtc[0x33] & 3) << 16; @@ -665,26 +666,19 @@ et4000_recalctimings(svga_t *svga) svga->dots_per_clock <<= 1; } - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { - case 0: - case 1: - break; - case 3: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 40000000.0; - break; - case 5: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; - default: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + svga->clock *= 2.0; + } else { + if ((svga->bpp <= 8) || ((svga->gdcreg[5] & 0x60) <= 0x20)) + svga->clock *= 2.0; } switch (svga->bpp) { case 15: case 16: - svga->hdisp /= 2; - svga->dots_per_clock /= 2; + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; break; case 24: @@ -901,6 +895,9 @@ et4000_init(const device_t *info) if (dev->type >= ET4000_TYPE_ISA) dev->svga.ramdac = device_add(&sc1502x_ramdac_device); + dev->svga.clock_gen = device_add(&ics2494an_324_device); + dev->svga.getclock = ics2494_getclock; + if (dev->type == ET4000_TYPE_TC6058AF) dev->svga.adv_flags |= FLAG_PRECISETIME; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 05de0dbea8a..4abb9a76768 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -10,6 +10,8 @@ * * Known bugs: Accelerator doesn't work in planar modes * + * + * * Authors: Sarah Walker, * Miran Grca, * @@ -35,30 +37,46 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define BIOS_ROM_PATH_DIAMOND "roms/video/et4000w32/et4000w32.bin" -#define BIOS_ROM_PATH_CARDEX "roms/video/et4000w32/cardex.vbi" -#define BIOS_ROM_PATH_W32 "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" -#define BIOS_ROM_PATH_W32I_ISA "roms/video/et4000w32/ET4KW32I.VBI" -#define BIOS_ROM_PATH_W32I_VLB "roms/video/et4000w32/tseng.u41.bin" -#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.bin" -#define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN" -#define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN" +#define BIOS_ROM_PATH_W32_MACHSPEED_VGA_GUI_2400S "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" +#define BIOS_ROM_PATH_W32I_REVB_AXIS_MICRODEVICE "roms/video/et4000w32/ET4KW32I.VBI" +#define BIOS_ROM_PATH_W32I_REVB_HERCULES_DYNAMITE_VLB_PRO "roms/video/et4000w32/Hercules Dynamite VL Pro v8.00 c 1993 Hercules.bin" +#define BIOS_ROM_PATH_W32P_REVB_VIDEOMAGIC "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.BIN" +#define BIOS_ROM_PATH_W32P_REVC_CARDEX "roms/video/et4000w32/et4000w32pcardex.BIN" +#define BIOS_ROM_PATH_W32P_REVD "roms/video/et4000w32/ET4K_W32.BIN" +#define BIOS_ROM_PATH_W32P_REVD_CARDEX "roms/video/et4000w32/cardex.vbi" +#define BIOS_ROM_PATH_W32P_REVD_DIAMOND "roms/video/et4000w32/et4000w32.bin" #define ACL_WRST 1 #define ACL_RDST 2 #define ACL_XYST 4 #define ACL_SSO 8 +typedef enum { + ET4000W32 = 0, + ET4000W32I_REVB = 3, + ET4000W32P_REVB = 5, + ET4000W32P_REVC = 7, + ET4000W32P_REVD = 6 +} et4000w32_chip_type; + enum { - ET4000W32, - ET4000W32I, - ET4000W32P_REVC, - ET4000W32P_VIDEOMAGIC_REVB, - ET4000W32P, - ET4000W32P_CARDEX, - ET4000W32P_DIAMOND + MACHSPEED_VGA_GUI_2400S = 0, + AXIS_MICRODEVICE_ET4W32_5, + HERCULES_DYNAMITE_PRO_VLB, + VIDEOMAGIC_ETW32PVS, + CARDEX_REVC, + GENERIC_REVD, + CARDEX_REVD, + DIAMOND_STEALTH_32 }; +typedef enum { + BUILT_IN = 0, + ATT49X, + STG170X, + ET4K_SDAC +} et4000w32_ramdac_type; + typedef struct et4000w32p_t { mem_mapping_t linear_mapping; mem_mapping_t mmu_mapping; @@ -68,15 +86,22 @@ typedef struct et4000w32p_t { svga_t svga; uint8_t banking, banking2, adjust_cursor, rev, pci_slot; + uint8_t adjust_cursor_x; uint8_t regs[256], pci_regs[256]; int index, vlb, pci, interleaved, - bank, type; + bank; + int onboard_vid; + int vram_size; uint32_t linearbase; uint32_t vram_mask; + int card_type; + et4000w32_chip_type chip_type; + et4000w32_ramdac_type ramdac_type; + /* Accelerator */ struct { struct { @@ -135,6 +160,7 @@ static void et4000w32_blit_start(et4000w32p_t *et4000); static void et4000w32p_blit_start(et4000w32p_t *et4000); static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000); static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); +void et4000w32p_out(uint16_t addr, uint8_t val, void *priv); uint8_t et4000w32p_in(uint16_t addr, void *priv); #ifdef ENABLE_ET4000W32_LOG @@ -168,18 +194,28 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c2: - if (et4000->type == ET4000W32P_DIAMOND) - icd2061_write(svga->clock_gen, (val >> 2) & 3); + if (svga->getclock == icd2061_getclock) + icd2061_write(svga->clock_gen, ((val >> 2) & 0x03) | ((svga->crtc[0x34] << 1) & 0x04)| ((svga->crtc[0x31] >> 3) & 0x08)); break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (et4000->type <= ET4000W32P_REVC) - sdac_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - stg_ramdac_out(addr, val, svga->ramdac, svga); + switch (et4000->ramdac_type) { + case ATT49X: + att49x_ramdac_out(addr, !!(svga->crtc[0x31] & 0x40), val, svga->ramdac, svga); + break; + case STG170X: + stg_ramdac_out(addr, val, svga->ramdac, svga); + break; + case ET4K_SDAC: + sdac_ramdac_out(addr, !!(svga->crtc[0x31] & 0x40), val, svga->ramdac, svga); + break; + default: + svga_out(addr, val, svga); + break; + } return; case 0x3cb: /* Banking extension */ @@ -244,13 +280,13 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) } } if (svga->crtcreg == 0x30) { - if (et4000->pci && (et4000->rev != 5)) + if (et4000->pci && (et4000->rev != ET4000W32P_REVB)) et4000->linearbase = (et4000->linearbase & 0xc0000000) | ((val & 0xfc) << 22); else et4000->linearbase = val << 22; et4000w32p_recalcmapping(et4000); } - if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) + if ((svga->crtcreg == 0x32) || (svga->crtcreg == 0x36)) et4000w32p_recalcmapping(et4000); break; @@ -264,6 +300,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) case 0x217a: et4000->index = val; return; + case 0x210b: case 0x211b: case 0x212b: @@ -278,18 +315,27 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); svga->hwcursor.xoff = et4000->regs[0xE2]; svga->hwcursor.yoff = et4000->regs[0xE6]; - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && (et4000->regs[0xe2] >= 0x1f) && (et4000->regs[0xe6] >= 0x1f))) ? 128 : 64; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->rev == ET4000W32) && (et4000->regs[0xe2] >= 0x1f) && (et4000->regs[0xe6] >= 0x1f))) ? 128 : 64; - if (et4000->type == ET4000W32) { + if (et4000->rev == ET4000W32) { if ((svga->bpp == 15) || (svga->bpp == 16)) { svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 128; + if (et4000->adjust_cursor_x == 1) + svga->hwcursor.x += 0x100; + else if (et4000->adjust_cursor_x == 2) + svga->hwcursor.x += 8; + } + } else if (et4000->rev == ET4000W32I_REVB) { + if (((svga->bpp == 15) || (svga->bpp == 16))) { + if (et4000->adjust_cursor_x == 2) + svga->hwcursor.x += 8; } } - if ((et4000->type == ET4000W32) && (svga->hwcursor.cur_xsize == 128)) { + if ((et4000->rev == ET4000W32) && (svga->hwcursor.cur_xsize == 128)) { switch (svga->bpp) { case 8: - svga->hwcursor.xoff += 32; + svga->hwcursor.xoff += 0x20; break; default: @@ -300,16 +346,14 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *priv) if (svga->hwcursor.cur_xsize == 128) { svga->hwcursor.xoff &= 0x7f; svga->hwcursor.yoff &= 0x7f; - if (et4000->type > ET4000W32P_REVC) { - if (svga->bpp == 24) { + if ((et4000->rev > ET4000W32P_REVC) || (et4000->rev == ET4000W32P_REVB)) { + if (svga->bpp == 24) et4000->adjust_cursor = 2; - } } } else { - if (et4000->type > ET4000W32P_REVC) { - if ((svga->bpp == 24) && et4000->adjust_cursor) { + if ((et4000->rev > ET4000W32P_REVC) || (et4000->rev == ET4000W32P_REVB)) { + if ((svga->bpp == 24) && et4000->adjust_cursor) et4000->adjust_cursor = 0; - } } svga->hwcursor.xoff &= 0x3f; svga->hwcursor.yoff &= 0x3f; @@ -332,6 +376,7 @@ et4000w32p_in(uint16_t addr, void *priv) { et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; + uint8_t temp = 0x00; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -346,10 +391,17 @@ et4000w32p_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - if (et4000->type <= ET4000W32P_REVC) - return sdac_ramdac_in(addr, 0, svga->ramdac, svga); - else - return stg_ramdac_in(addr, svga->ramdac, svga); + switch (et4000->ramdac_type) { + case ATT49X: + return att49x_ramdac_in(addr, !!(svga->crtc[0x31] & 0x40), svga->ramdac, svga); + case STG170X: + return stg_ramdac_in(addr, svga->ramdac, svga); + case ET4K_SDAC: + return sdac_ramdac_in(addr, !!(svga->crtc[0x31] & 0x40), svga->ramdac, svga); + default: + return svga_in(addr, svga); + } + break; case 0x3cb: return et4000->banking2; @@ -358,9 +410,22 @@ et4000w32p_in(uint16_t addr, void *priv) case 0x3d4: return svga->crtcreg; case 0x3d5: - if (et4000->type == ET4000W32) { - if (svga->crtcreg == 0x37) - return 0x09; + if ((et4000->card_type == MACHSPEED_VGA_GUI_2400S) || + (et4000->card_type == AXIS_MICRODEVICE_ET4W32_5)) { + if (svga->crtcreg == 0x37) { + temp = svga->crtc[0x37]; + temp &= ~0x09; + switch (et4000->vram_size) { + case 1: + temp |= 0x09; + break; + case 2: + break; + default: + break; + } + return temp; + } } return svga->crtc[svga->crtcreg]; @@ -368,15 +433,18 @@ et4000w32p_in(uint16_t addr, void *priv) uint8_t ret = 0xff; svga->attrff = 0; - /*Bit 1 of the Input Status Register is required by the OS/2 and NT ET4000W32/I drivers to be set otherwise - the guest will loop infinitely upon reaching the GUI*/ if (svga->cgastat & 0x01) - svga->cgastat &= ~0x32; + svga->cgastat &= ~0x30; else - svga->cgastat ^= 0x32; + svga->cgastat ^= 0x30; ret = svga->cgastat; + /*Bit 1 of the Input Status Register is required by the OS/2 and NT ET4000W32/I drivers to be set otherwise + the guest will loop infinitely upon reaching the GUI*/ + if (svga->hdisp_on) + ret |= 0x02; + if ((svga->fcr & 0x08) && svga->dispon) ret |= 0x08; @@ -384,6 +452,7 @@ et4000w32p_in(uint16_t addr, void *priv) ret &= 0x7f; else ret |= 0x80; + return ret; } @@ -396,17 +465,18 @@ et4000w32p_in(uint16_t addr, void *priv) case 0x216a: case 0x217a: return et4000->index; - case 0x210B: - case 0x211B: - case 0x212B: - case 0x213B: - case 0x214B: - case 0x215B: - case 0x216B: - case 0x217B: - if (et4000->index == 0xec) { + + case 0x210b: + case 0x211b: + case 0x212b: + case 0x213b: + case 0x214b: + case 0x215b: + case 0x216b: + case 0x217b: + if (et4000->index == 0xec) return (et4000->regs[0xec] & 0xf) | (et4000->rev << 4); - } + if (et4000->index == 0xee) { if (svga->bpp == 8) { if ((svga->gdcreg[5] & 0x60) >= 0x40) @@ -415,7 +485,7 @@ et4000w32p_in(uint16_t addr, void *priv) return 1; else return 2; - } else if (svga->bpp == 15 || svga->bpp == 16) + } else if ((svga->bpp == 15) || (svga->bpp == 16)) return 4; else break; @@ -439,10 +509,12 @@ void et4000w32p_recalctimings(svga_t *svga) { et4000w32p_t *et4000 = (et4000w32p_t *) svga->priv; + int clk_sel = ((svga->miscout >> 2) & 0x03) | ((svga->crtc[0x34] << 1) & 0x04)| ((svga->crtc[0x31] >> 3) & 0x08); svga->memaddr_latch |= (svga->crtc[0x33] & 0x7) << 16; - svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) + svga->hblankstart = (((svga->crtc[0x3f] & 0x4) >> 2) << 8) + svga->crtc[2]; if (svga->crtc[0x35] & 0x01) svga->vblankstart |= 0x400; @@ -456,45 +528,128 @@ et4000w32p_recalctimings(svga_t *svga) svga->split |= 0x400; if (svga->crtc[0x3F] & 0x80) svga->rowoffset |= 0x100; - if (svga->crtc[0x3F] & 0x01) + if ((svga->crtc[0x3F] & 0x01) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) svga->htotal |= 0x100; if (svga->attrregs[0x16] & 0x20) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; } - svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); - - if (et4000->type != ET4000W32P_DIAMOND && et4000->type != ET4000W32P_VIDEOMAGIC_REVB && et4000->type != ET4000W32P_CARDEX && et4000->type != ET4000W32P) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->gdcreg[5] & 0x40) { + et4000->adjust_cursor = 0; + et4000->adjust_cursor_x = 0; + + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); + if (svga->seqregs[7] & 0x01) + svga->clock *= 4.0; + else if (svga->seqregs[7] & 0x40) + svga->clock *= 2.0; + + if ((svga->getclock != ics2494_getclock) && + (svga->getclock != icd2061_getclock)) { + if (clk_sel <= 1) + svga->clock /= 2.0; + } + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + et4000w32_log("Graphics Mode clk_sel=%d, cr35 bit7=%02x, seq7=%02x, clksel=%d, htotal=%03x.\n", clk_sel, svga->crtc[0x35] & 0x80, svga->seqregs[7] & 0x41, clk_sel, svga->htotal); + if ((svga->gdcreg[5] & 0x60) >= 0x40) { + if (et4000->rev == ET4000W32) { switch (svga->bpp) { case 8: - svga->clock *= 2; - break; - case 15: - case 16: - svga->clock *= 3; - break; - case 24: - svga->clock *= 4; + if ((svga->hdisp == 640) || (svga->hdisp == 800) || (svga->hdisp == 1024)) + break; + svga->hdisp -= 24; + if (svga->hdisp == 632) + svga->hdisp += 8; + else if (svga->hdisp == 1256) + svga->hdisp += 24; break; default: break; } } + switch (svga->bpp) { + case 15: + case 16: + et4000w32_log("ClkSel=%d, bpp=%d, seq7=%02x, cr35=%02x.\n", clk_sel, svga->bpp, svga->seqregs[7] & 0x41, svga->crtc[0x35] & 0x80); + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + if (et4000->rev <= ET4000W32P_REVC) { + if (et4000->rev != ET4000W32P_REVB) { + if (et4000->rev == ET4000W32P_REVC) { + if (svga->hdisp != 1024) + et4000->adjust_cursor = 1; + } else { + if (et4000->rev <= ET4000W32I_REVB) { + et4000->adjust_cursor = 1; + if (svga->hdisp == 800) + et4000->adjust_cursor_x = 1; + else if (svga->hdisp == 640) + et4000->adjust_cursor_x = 2; + } + } + } + } + break; + case 24: + svga->hdisp /= 3; + svga->dots_per_clock /= 3; + if (et4000->rev <= ET4000W32P_REVC) { + if (et4000->rev != ET4000W32P_REVB) + et4000->adjust_cursor = 2; + } + if ((et4000->card_type == DIAMOND_STEALTH_32) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) + svga->hdisp = 640; + break; + default: + break; + } + et4000w32_log("ClkSel=%d, crtc34 bits 0-1=%02x, crtc31 bits 6-7=%02x, seq7=%02x, interlace=%02x.\n", clk_sel, svga->crtc[0x34] & 0x03, svga->crtc[0x31] & 0xc0, svga->seqregs[7], svga->crtc[0x35] & 0x80); } - } + } else + et4000w32_log("CLOCK text clk=%d, htotal=%03x.\n", clk_sel, svga->htotal); - if (et4000->type == ET4000W32) { + if (!svga->scrblank && svga->attr_palette_enable) { if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if (svga->gdcreg[5] & 0x40) { + et4000w32_log("bpp=%d, lowres=%x.\n", svga->bpp, svga->lowres); switch (svga->bpp) { case 8: - if (svga->hdisp == 640 || svga->hdisp == 800 || svga->hdisp == 1024) - break; - svga->hdisp -= 24; + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 17: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_mix_highres; + break; + case 24: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; break; default: @@ -504,113 +659,6 @@ et4000w32p_recalctimings(svga_t *svga) } } - et4000->adjust_cursor = 0; - - switch (svga->bpp) { - case 15: - case 16: - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } - if (et4000->type <= ET4000W32P_REVC) { - if (et4000->type == ET4000W32P_REVC) { - if (svga->hdisp != 1024) - et4000->adjust_cursor = 1; - } else - et4000->adjust_cursor = 1; - } - break; - case 24: - svga->hdisp /= 3; - svga->dots_per_clock /= 3; - if (et4000->type <= ET4000W32P_REVC) - et4000->adjust_cursor = 2; - if ((et4000->type == ET4000W32P_DIAMOND) && ((svga->hdisp == (640 / 2)) || (svga->hdisp == 1232))) { - svga->hdisp = 640; - } - break; - - default: - break; - } - - svga->render = svga_render_blank; - if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ - if (svga->seqregs[1] & 8) /* 40 column */ - svga->render = svga_render_text_40; - else - svga->render = svga_render_text_80; - } else { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /* Low res (320) */ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /* 4 colours */ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /* 256+ colours */ - if (et4000->type <= ET4000W32P_REVC) - svga->clock /= 2; - - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 17: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_mix_highres; - break; - case 24: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - - default: - break; - } - break; - - default: - break; - } - } - } - if (svga->render == svga_render_4bpp_highres) svga->render = svga_render_4bpp_tseng_highres; } @@ -638,6 +686,7 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000) map |= 4; if (svga->crtc[0x36] & 0x08) map |= 8; + mem_mapping_disable(&et4000->linear_mapping); switch (map) { case 0x0: @@ -742,13 +791,13 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | (val << 8); break; case 0x8e: - if (et4000->type >= ET4000W32P_REVC) + if (et4000->rev >= ET4000W32P_REVB) et4000->acl.queued.pixel_depth = val & 0x30; else et4000->acl.queued.vbus = val & 0x03; break; case 0x8f: - if (et4000->type >= ET4000W32P_REVC) + if (et4000->rev >= ET4000W32P_REVB) et4000->acl.queued.xy_dir = val & 0xb7; else et4000->acl.queued.xy_dir = val & 0x03; @@ -772,7 +821,7 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | (val << 8); break; case 0x9c: - if (et4000->type >= ET4000W32P_REVC) + if (et4000->rev >= ET4000W32P_REVB) et4000->acl.queued.ctrl_routing = val & 0xdb; else et4000->acl.queued.ctrl_routing = val & 0xb7; @@ -798,14 +847,14 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) case 0xa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffffff) | (val << 24); et4000->acl.internal = et4000->acl.queued; - if (et4000->type >= ET4000W32P_REVC) { + if (et4000->rev >= ET4000W32P_REVB) { et4000w32p_blit_start(et4000); et4000w32_log("Destination Address write and start XY Block, xcnt = %i, ycnt = %i\n", et4000->acl.x_count + 1, et4000->acl.y_count + 1); if (!(et4000->acl.queued.ctrl_routing & 0x43)) { - et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); + et4000w32p_blit(-1, 0xffffffff, 0, 0, et4000); } if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { - et4000w32p_blit(4, ~0, 0, 0, et4000); + et4000w32p_blit(4, 0xffffffff, 0, 0, et4000); } } else { et4000w32_blit_start(et4000); @@ -862,7 +911,7 @@ et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) static void et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uint8_t bank) { - if (et4000->type >= ET4000W32P_REVC) { + if (et4000->rev >= ET4000W32P_REVB) { if (!(et4000->acl.status & ACL_XYST)) { et4000w32_log("XY MMU block not started\n"); return; @@ -872,7 +921,7 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin if ((et4000->acl.internal.ctrl_routing & 3) == 2) /*CPU data is Mix data*/ et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); else if ((et4000->acl.internal.ctrl_routing & 3) == 1) /*CPU data is Source data*/ - et4000w32p_blit(1, ~0, val, 2, et4000); + et4000w32p_blit(1, 0xffffffff, val, 2, et4000); } } else { if (!(et4000->acl.status & ACL_XYST)) { @@ -885,9 +934,8 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uin if (!(et4000->acl.queued.ctrl_routing & 0x37)) { et4000->acl.mmu_start = 1; et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); - } else { + } else et4000->acl.mmu_start = 0; - } } if (et4000->acl.internal.ctrl_routing & 7) { @@ -932,9 +980,9 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) case 0x2000: /* MMU 1 */ case 0x4000: /* MMU 2 */ et4000->bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << et4000->bank)) { + if (et4000->mmu.ctrl & (1 << et4000->bank)) et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val, et4000->bank); - } else { + else { if (((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) < svga->vram_max) { svga->vram[((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask] = val; svga->changedvram[(((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask) >> 12] = changeframecount; @@ -942,9 +990,9 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *priv) } break; case 0x6000: - if ((addr & 0xff) >= 0x80) { + if ((addr & 0xff) >= 0x80) et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val); - } else { + else { switch (addr & 0xff) { case 0x00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xffffff00) | val; @@ -1069,6 +1117,7 @@ et4000w32p_mmu_read(uint32_t addr, void *priv) et4000->acl.fifo_queue = 0; } else et4000->acl.status &= ~ACL_RDST; + return et4000->acl.status; case 0x80: @@ -1100,8 +1149,9 @@ et4000w32p_mmu_read(uint32_t addr, void *priv) case 0x8d: return et4000->acl.internal.dest_off >> 8; case 0x8e: - if (et4000->type >= ET4000W32P_REVC) + if (et4000->rev >= ET4000W32P_REVB) return et4000->acl.internal.pixel_depth; + return et4000->acl.internal.vbus; case 0x8f: return et4000->acl.internal.xy_dir; @@ -1172,9 +1222,9 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.pattern_back = et4000->acl.pattern_addr; if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ + if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) /*This is to avoid a division by zero crash*/ et4000->acl.pattern_y = (et4000->acl.pattern_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - } else + else et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } @@ -1187,9 +1237,9 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.source_back = et4000->acl.source_addr; if (!(et4000->acl.internal.source_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ + if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) /*This is to avoid a division by zero crash*/ et4000->acl.source_y = (et4000->acl.source_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - } else + else et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } @@ -1265,6 +1315,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000) et4000w32_max_x[2] = (et4000->acl.internal.pixel_depth == 0x20) ? 3 : 4; et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; + et4000->acl.x_count = et4000->acl.internal.count_x; et4000->acl.cpu_dat_pos = 0; et4000->acl.cpu_dat = 0; @@ -2278,9 +2329,8 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4 return; } - if (cpu_input) { + if (cpu_input) return; - } } } } @@ -2293,7 +2343,7 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 uint8_t pattern; uint8_t source; uint8_t dest; - uint8_t out; + uint8_t out = 0; uint8_t rop; int mixdat; @@ -2307,14 +2357,15 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 while (count--) { et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + et4000w32_log("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask, (et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask); if (cpu_input == 2) { source = sdat & 0xff; sdat >>= 8; - } + } else + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - out = 0; et4000w32_log("%06X ", et4000->acl.dest_addr); if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); @@ -2416,7 +2467,7 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 } } else { et4000w32_log("BitBLT: count = %i\n", count); - while (count-- && et4000->acl.y_count >= 0) { + while (count-- && (et4000->acl.y_count >= 0)) { pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; if (cpu_input == 2) { @@ -2426,8 +2477,6 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - out = 0; - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); } else { @@ -2455,6 +2504,8 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 et4000->acl.x_count--; if (et4000->acl.x_count == 0xffff) { + et4000->acl.x_count = et4000->acl.internal.count_x; + if (et4000->acl.internal.xy_dir & 2) { et4000w32_decy(et4000); et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); @@ -2469,7 +2520,6 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 et4000->acl.source_x = et4000->acl.source_x_back; et4000->acl.y_count--; - et4000->acl.x_count = et4000->acl.internal.count_x; if (et4000->acl.y_count == 0xffff) { et4000w32_log("BitBLT end\n"); et4000->acl.status &= ~(ACL_XYST | ACL_SSO); @@ -2481,7 +2531,7 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 if (et4000->acl.internal.ctrl_routing & 0x40) { if (et4000->acl.cpu_dat_pos & 3) - et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); + et4000->acl.cpu_dat_pos += (4 - (et4000->acl.cpu_dat_pos & 3)); return; } } @@ -2505,7 +2555,7 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine) offset = svga->hwcursor_latch.xoff; - if ((et4000->type == ET4000W32) && (pitch == 32)) { + if ((et4000->rev == ET4000W32) && (pitch == 32)) { switch (svga->bpp) { case 8: minus_width = 0; @@ -2606,11 +2656,6 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) { const et4000w32p_t *et4000 = (et4000w32p_t *) priv; - if (func > 0) - return 0xff; - - addr &= 0xff; - switch (addr) { case 0x00: return 0x0c; /* Tseng Labs */ @@ -2648,13 +2693,13 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) return (et4000->linearbase >> 24); case 0x30: - return et4000->pci_regs[0x30] & 0x01; /* BIOS ROM address */ + return et4000->onboard_vid ? 0x00 : (et4000->pci_regs[0x30] & 0x01); /* BIOS ROM address */ case 0x31: return 0x00; case 0x32: - return et4000->pci_regs[0x32]; + return et4000->onboard_vid ? 0x00 : et4000->pci_regs[0x32]; case 0x33: - return et4000->pci_regs[0x33]; + return et4000->onboard_vid ? 0x00 : et4000->pci_regs[0x33]; default: break; @@ -2669,11 +2714,6 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; - if (func > 0) - return; - - addr &= 0xff; - switch (addr) { case PCI_REG_COMMAND: et4000->pci_regs[PCI_REG_COMMAND] = (val & 0x23) | 0x80; @@ -2681,6 +2721,7 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) et4000w32p_io_set(et4000); else et4000w32p_io_remove(et4000); + et4000w32p_recalcmapping(et4000); break; @@ -2695,11 +2736,14 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) case 0x30: case 0x32: case 0x33: + if (et4000->onboard_vid) + return; + et4000->pci_regs[addr] = val; if (et4000->pci_regs[0x30] & 0x01) { - uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); - et4000w32_log("ET4000 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); + uint32_t biosaddr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); + et4000w32_log("ET4000 bios_rom enabled at %08x\n", biosaddr); + mem_mapping_set_addr(&et4000->bios_rom.mapping, biosaddr, 0x8000); } else { et4000w32_log("ET4000 bios_rom disabled\n"); mem_mapping_disable(&et4000->bios_rom.mapping); @@ -2714,21 +2758,16 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) void * et4000w32p_init(const device_t *info) { - int vram_size; et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); memset(et4000, 0, sizeof(et4000w32p_t)); et4000->pci = (info->flags & DEVICE_PCI) ? 0x80 : 0x00; et4000->vlb = (info->flags & DEVICE_VLB) ? 0x40 : 0x00; - /*The ET4000/W32i ISA BIOS seems to not support 2MB of VRAM*/ - if ((info->local == ET4000W32) || ((info->local == ET4000W32I) && !(et4000->vlb))) - vram_size = 1; - else - vram_size = device_get_config_int("memory"); + et4000->card_type = info->local & 0xff; + et4000->onboard_vid = (info->local >> 8) & 0xff; - /*The interleaved VRAM was introduced by the ET4000/W32i*/ - et4000->interleaved = ((vram_size == 2) && (info->local != ET4000W32)) ? 1 : 0; + et4000->vram_size = device_get_config_int("memory"); if (info->flags & DEVICE_PCI) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_pci); @@ -2737,122 +2776,158 @@ et4000w32p_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_isa); - svga_init(info, &et4000->svga, et4000, vram_size << 20, + svga_init(info, &et4000->svga, et4000, et4000->vram_size << 20, et4000w32p_recalctimings, et4000w32p_in, et4000w32p_out, et4000w32p_hwcursor_draw, NULL); - et4000->vram_mask = (vram_size << 20) - 1; - et4000->svga.decode_mask = (vram_size << 20) - 1; + et4000->vram_mask = (et4000->vram_size << 20) - 1; + et4000->svga.decode_mask = (et4000->vram_size << 20) - 1; - et4000->type = info->local; + et4000->ramdac_type = BUILT_IN; + et4000->svga.crtc[0x31] = 0x40; + et4000->svga.miscout = 0x01; + et4000->svga.bpp = 8; - switch (et4000->type) { - case ET4000W32: + switch (et4000->card_type) { + case MACHSPEED_VGA_GUI_2400S: /* ET4000/W32 */ - et4000->rev = 0; + et4000->rev = ET4000W32; + if (et4000->onboard_vid) { + et4000->ramdac_type = ATT49X; + et4000->svga.ramdac = device_add(&att490_ramdac_device); + et4000->svga.clock_gen = device_add(&ics2494an_324_device); + et4000->svga.getclock = ics2494_getclock; + } else { + et4000->ramdac_type = ET4K_SDAC; + + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32_MACHSPEED_VGA_GUI_2400S, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); + + et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = sdac_getclock; + sdac_set_ref_clock(et4000->svga.ramdac, 14318184.0f); + svga_recalctimings(&et4000->svga); + } + break; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32, 0xc0000, 0x8000, 0x7fff, 0, + case AXIS_MICRODEVICE_ET4W32_5: + /* ET4000/W32i rev B */ + et4000->rev = ET4000W32I_REVB; + et4000->ramdac_type = ET4K_SDAC; + + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_REVB_AXIS_MICRODEVICE, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; + sdac_set_ref_clock(et4000->svga.ramdac, 14318184.0f); + svga_recalctimings(&et4000->svga); break; - case ET4000W32I: + case HERCULES_DYNAMITE_PRO_VLB: /* ET4000/W32i rev B */ - et4000->rev = 3; + et4000->rev = ET4000W32I_REVB; + et4000->ramdac_type = ATT49X; - if (et4000->vlb) { - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_VLB, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - } else { - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_ISA, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - } + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_REVB_HERCULES_DYNAMITE_VLB_PRO, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = sdac_getclock; + et4000->svga.ramdac = device_add(&att490_ramdac_device); + et4000->svga.clock_gen = device_add(&ics2494an_324_device); + et4000->svga.getclock = ics2494_getclock; break; - case ET4000W32P_VIDEOMAGIC_REVB: + case VIDEOMAGIC_ETW32PVS: /* ET4000/W32p rev B */ - et4000->rev = 5; + et4000->rev = ET4000W32P_REVB; + et4000->ramdac_type = STG170X; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB, 0xc0000, 0x8000, 0x7fff, 0, + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVB_VIDEOMAGIC, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.ramdac = device_add(&stg1703_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; break; - case ET4000W32P_REVC: + case CARDEX_REVC: /* ET4000/W32p rev C */ - et4000->rev = 7; + et4000->rev = ET4000W32P_REVC; + et4000->ramdac_type = ET4K_SDAC; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVC, 0xc0000, 0x8000, 0x7fff, 0, + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVC_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); et4000->svga.ramdac = device_add(&tseng_ics5341_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = sdac_getclock; + sdac_set_ref_clock(et4000->svga.ramdac, 14318184.0f); + svga_recalctimings(&et4000->svga); break; - case ET4000W32P: + case CARDEX_REVD: /* ET4000/W32p rev D */ - et4000->rev = 6; + et4000->rev = ET4000W32P_REVD; + et4000->ramdac_type = STG170X; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P, 0xc0000, 0x8000, 0x7fff, 0, + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVD_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.ramdac = device_add(&stg1703_ramdac_device); et4000->svga.clock_gen = et4000->svga.ramdac; et4000->svga.getclock = stg_getclock; break; - case ET4000W32P_CARDEX: + case DIAMOND_STEALTH_32: /* ET4000/W32p rev D */ - et4000->rev = 6; + et4000->rev = ET4000W32P_REVD; + et4000->ramdac_type = STG170X; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVD_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = stg_getclock; + et4000->svga.ramdac = device_add(&stg1702_ramdac_device); + et4000->svga.clock_gen = device_add(&icd2061_device); + et4000->svga.getclock = icd2061_getclock; + icd2061_set_ref_clock(et4000->svga.ramdac, 14318184.0f); + svga_recalctimings(&et4000->svga); break; - case ET4000W32P_DIAMOND: + case GENERIC_REVD: /* ET4000/W32p rev D */ - et4000->rev = 6; + et4000->rev = ET4000W32P_REVD; + et4000->ramdac_type = STG170X; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVD, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = device_add(&icd2061_device); - et4000->svga.getclock = icd2061_getclock; - icd2061_set_ref_clock(et4000->svga.ramdac, 14318184.0f); - svga_recalctimings(&et4000->svga); + et4000->svga.ramdac = device_add(&stg1703_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = stg_getclock; break; default: break; } - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&et4000->bios_rom.mapping); + /*The interleaved VRAM was introduced by the ET4000/W32i*/ + et4000->interleaved = ((et4000->vram_size == 2) && (et4000->rev != ET4000W32)) ? 1 : 0; + + if (info->flags & DEVICE_PCI) { + if (!et4000->onboard_vid) + mem_mapping_disable(&et4000->bios_rom.mapping); + } mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &et4000->svga); mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, et4000); et4000w32p_io_set(et4000); if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot); + pci_add_card(et4000->onboard_vid ? PCI_ADD_VIDEO : PCI_ADD_NORMAL, et4000w32p_pci_read, et4000w32p_pci_write, et4000, &et4000->pci_slot); /* Hardwired bits: 00000000 1xx0x0xx */ /* R/W bits: xx xxxx */ @@ -2870,56 +2945,57 @@ et4000w32p_init(const device_t *info) et4000->pci_regs[0x33] = 0xf0; et4000->svga.packed_chain4 = 1; + et4000->svga.adv_flags |= FLAG_PANNING_ATI; return et4000; } int -et4000w32_available(void) +et4000w32_machspeed_vga_gui_2400s_available(void) { - return rom_present(BIOS_ROM_PATH_W32); + return rom_present(BIOS_ROM_PATH_W32_MACHSPEED_VGA_GUI_2400S); } int -et4000w32i_isa_available(void) +et4000w32i_axis_microdevice_available(void) { - return rom_present(BIOS_ROM_PATH_W32I_ISA); + return rom_present(BIOS_ROM_PATH_W32I_REVB_AXIS_MICRODEVICE); } int -et4000w32i_vlb_available(void) +et4000w32i_hercules_dynamite_pro_vlb_available(void) { - return rom_present(BIOS_ROM_PATH_W32I_VLB); + return rom_present(BIOS_ROM_PATH_W32I_REVB_HERCULES_DYNAMITE_VLB_PRO); } int -et4000w32p_videomagic_revb_vlb_available(void) +et4000w32p_videomagic_revb_available(void) { - return rom_present(BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB); + return rom_present(BIOS_ROM_PATH_W32P_REVB_VIDEOMAGIC); } int -et4000w32p_revc_available(void) +et4000w32p_cardex_revc_available(void) { - return rom_present(BIOS_ROM_PATH_W32P_REVC); + return rom_present(BIOS_ROM_PATH_W32P_REVC_CARDEX); } int -et4000w32p_noncardex_available(void) +et4000w32p_diamond_revd_available(void) { - return rom_present(BIOS_ROM_PATH_W32P); + return rom_present(BIOS_ROM_PATH_W32P_REVD_DIAMOND); } int -et4000w32p_available(void) +et4000w32p_cardex_revd_available(void) { - return rom_present(BIOS_ROM_PATH_DIAMOND); + return rom_present(BIOS_ROM_PATH_W32P_REVD_CARDEX); } int -et4000w32p_cardex_available(void) +et4000w32p_generic_revd_available(void) { - return rom_present(BIOS_ROM_PATH_CARDEX); + return rom_present(BIOS_ROM_PATH_W32P_REVD); } void @@ -2969,197 +3045,197 @@ static const device_config_t et4000w32p_config[] = { // clang-format on }; -const device_t et4000w32_device = { - .name = "Tseng Labs ET4000/w32 ISA", +const device_t et4000w32_machspeed_vga_gui_2400s_isa_device = { + .name = "Tseng Labs ET4000/w32 ISA (MachSpeed VGA GUI 2400S)", .internal_name = "et4000w32", .flags = DEVICE_ISA16, - .local = ET4000W32, + .local = MACHSPEED_VGA_GUI_2400S, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32_available, + .available = et4000w32_machspeed_vga_gui_2400s_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, - .config = NULL + .config = et4000w32p_config }; -const device_t et4000w32_onboard_device = { - .name = "Tseng Labs ET4000/w32 (ISA) (On-Board)", - .internal_name = "et4000w32_onboard", - .flags = DEVICE_ISA16, - .local = ET4000W32, +const device_t et4000w32_machspeed_vga_gui_2400s_vlb_device = { + .name = "Tseng Labs ET4000/w32 VLB (MachSpeed VGA GUI 2400S)", + .internal_name = "et4000w32_vlb", + .flags = DEVICE_VLB, + .local = MACHSPEED_VGA_GUI_2400S, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32_available, + .available = et4000w32_machspeed_vga_gui_2400s_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, - .config = NULL + .config = et4000w32p_config }; -const device_t et4000w32i_isa_device = { - .name = "Tseng Labs ET4000/w32i Rev. B ISA", - .internal_name = "et4000w32i", +const device_t et4000w32_onboard_device = { + .name = "Tseng Labs ET4000/w32 ISA (On-Board)", + .internal_name = "et4000w32_onboard", .flags = DEVICE_ISA16, - .local = ET4000W32I, + .local = MACHSPEED_VGA_GUI_2400S | 0x100, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32i_isa_available, + .available = NULL, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, - .config = NULL + .config = et4000w32p_config }; -const device_t et4000w32i_vlb_device = { - .name = "Tseng Labs ET4000/w32i Rev. B VLB", - .internal_name = "et4000w32i_vlb", - .flags = DEVICE_VLB, - .local = ET4000W32I, +const device_t et4000w32i_axis_microdevice_isa_device = { + .name = "Tseng Labs ET4000/w32i Rev. B ISA (Axis MicroDevice)", + .internal_name = "et4000w32i", + .flags = DEVICE_ISA16, + .local = AXIS_MICRODEVICE_ET4W32_5, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32i_vlb_available, + .available = et4000w32i_axis_microdevice_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_videomagic_revb_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. B VLB (VideoMagic)", - .internal_name = "et4000w32p_videomagic_revb_vlb", +const device_t et4000w32i_hercules_dynamite_pro_vlb_device = { + .name = "Tseng Labs ET4000/w32i Rev. B VLB (Hercules Dynamite Pro)", + .internal_name = "et4000w32i_vlb", .flags = DEVICE_VLB, - .local = ET4000W32P_VIDEOMAGIC_REVB, + .local = HERCULES_DYNAMITE_PRO_VLB, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_videomagic_revb_vlb_available, + .available = et4000w32i_hercules_dynamite_pro_vlb_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_videomagic_revb_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. B PCI (VideoMagic)", - .internal_name = "et4000w32p_videomagic_revb_pci", - .flags = DEVICE_PCI, - .local = ET4000W32P_VIDEOMAGIC_REVB, +const device_t et4000w32p_videomagic_revb_vlb_device = { + .name = "Tseng Labs ET4000/w32p Rev. B VLB (VideoMagic ETW32PVS)", + .internal_name = "et4000w32p_videomagic_revb_vlb", + .flags = DEVICE_VLB, + .local = VIDEOMAGIC_ETW32PVS, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_videomagic_revb_vlb_available, + .available = et4000w32p_videomagic_revb_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_revc_vlb_device = { +const device_t et4000w32p_cardex_revc_vlb_device = { .name = "Tseng Labs ET4000/w32p Rev. C VLB (Cardex)", .internal_name = "et4000w32p_revc_vlb", .flags = DEVICE_VLB, - .local = ET4000W32P_REVC, + .local = CARDEX_REVC, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_revc_available, + .available = et4000w32p_cardex_revc_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_revc_pci_device = { +const device_t et4000w32p_cardex_revc_pci_device = { .name = "Tseng Labs ET4000/w32p Rev. C PCI (Cardex)", - .internal_name = "et4000w32p_revc_pci", + .internal_name = "et4000w32p_revc_vlb", .flags = DEVICE_PCI, - .local = ET4000W32P_REVC, + .local = CARDEX_REVC, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_revc_available, + .available = et4000w32p_cardex_revc_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_noncardex_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB", - .internal_name = "et4000w32p_nc_vlb", +const device_t et4000w32p_cardex_revd_vlb_device = { + .name = "Tseng Labs ET4000/w32p Rev. D VLB (Cardex)", + .internal_name = "et4000w32p_vlb", .flags = DEVICE_VLB, - .local = ET4000W32P, + .local = CARDEX_REVD, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_noncardex_available, + .available = et4000w32p_cardex_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_noncardex_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI", - .internal_name = "et4000w32p_nc_pci", +const device_t et4000w32p_cardex_revd_pci_device = { + .name = "Tseng Labs ET4000/w32p Rev. D PCI (Cardex)", + .internal_name = "et4000w32p_pci", .flags = DEVICE_PCI, - .local = ET4000W32P, + .local = CARDEX_REVD, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_noncardex_available, + .available = et4000w32p_cardex_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_cardex_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB (Cardex)", - .internal_name = "et4000w32p_vlb", +const device_t et4000w32p_diamond_revd_vlb_device = { + .name = "Tseng Labs ET4000/w32p Rev. D VLB (Diamond Stealth32)", + .internal_name = "stealth32_vlb", .flags = DEVICE_VLB, - .local = ET4000W32P_CARDEX, + .local = DIAMOND_STEALTH_32, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_cardex_available, + .available = et4000w32p_diamond_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_cardex_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI (Cardex)", - .internal_name = "et4000w32p_pci", +const device_t et4000w32p_diamond_revd_pci_device = { + .name = "Tseng Labs ET4000/w32p Rev. D PCI (Diamond Stealth32)", + .internal_name = "stealth32_pci", .flags = DEVICE_PCI, - .local = ET4000W32P_CARDEX, + .local = DIAMOND_STEALTH_32, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_cardex_available, + .available = et4000w32p_diamond_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB (Diamond Stealth32)", - .internal_name = "stealth32_vlb", +const device_t et4000w32p_generic_revd_vlb_device = { + .name = "Tseng Labs ET4000/w32p Rev. D VLB", + .internal_name = "et4000w32p_nc_vlb", .flags = DEVICE_VLB, - .local = ET4000W32P_DIAMOND, + .local = GENERIC_REVD, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_available, + .available = et4000w32p_generic_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config }; -const device_t et4000w32p_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI (Diamond Stealth32)", - .internal_name = "stealth32_pci", +const device_t et4000w32p_generic_revd_pci_device = { + .name = "Tseng Labs ET4000/w32p Rev. D PCI", + .internal_name = "et4000w32p_nc_pci", .flags = DEVICE_PCI, - .local = ET4000W32P_DIAMOND, + .local = GENERIC_REVD, .init = et4000w32p_init, .close = et4000w32p_close, .reset = NULL, - .available = et4000w32p_available, + .available = et4000w32p_generic_revd_available, .speed_changed = et4000w32p_speed_changed, .force_redraw = et4000w32p_force_redraw, .config = et4000w32p_config diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 005cc6dfaee..42a3376748d 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -49,6 +49,7 @@ typedef struct ht216_t { uint32_t vram_mask, linear_base; uint8_t adjust_cursor, monitor_type; + uint8_t clk_sel; int ext_reg_enable; int isabus; @@ -100,7 +101,10 @@ void ht216_out(uint16_t addr, uint8_t val, void *priv); uint8_t ht216_in(uint16_t addr, void *priv); #define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN" -#define BIOS_VIDEO7_VGA_1024I_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" +#define BIOS_VIDEO7_VGA_1024I_219_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" +#define BIOS_VIDEO7_VGA_1024I_700_PATH "roms/video/video7/Headland Video7 VGA 1024i v7.0 32x8 (IP) NMC27C256B@DIP28.BIN" +#define BIOS_VIDEO7_VGA_1024I_704_HP_LO_PATH "roms/video/video7/Headland Video 7 VGA 1024i even v7.04 27C256 LO.bin" +#define BIOS_VIDEO7_VGA_1024I_704_HP_HI_PATH "roms/video/video7/Headland Video 7 VGA 1024i odd v7.04 27C256 HI.bin" #define BIOS_RADIUS_SVGA_MULTIVIEW_PATH "roms/video/video7/U18.BIN" #define BIOS_HT216_32_PATH "roms/video/video7/HT21632.BIN" @@ -132,6 +136,7 @@ dword_remap(svga_t *svga, uint32_t in_addr) { if (svga->packed_chain4) return in_addr; + return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); } @@ -182,9 +187,9 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c2: /*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/ + ht216->clk_sel = (ht216->clk_sel & ~0x03) | ((val & 0x0c) >> 2); ht216->misc = val; - svga->miscout = val; - ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4); + ht216_log("HT216 misc val=%02x, mode=0, chain4=%x\n", val, svga->chain4); ht216_recalc_bank_regs(ht216, 0); ht216_remap(ht216); svga_recalctimings(svga); @@ -251,10 +256,11 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) ht216->ht_regs[0xfc], ht216->ht_regs[0xfd], ht216->ht_regs[0xfe], ht216->ht_regs[0xff]); return; #endif - } else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) { + } else if ((svga->seqaddr >= 0x80) && ht216->ext_reg_enable) { old = ht216->ht_regs[svga->seqaddr & 0xff]; ht216->ht_regs[svga->seqaddr & 0xff] = val; + ht216_log("SeqAddr=%02x, val=%02x.\n", svga->seqaddr & 0xff, val); switch (svga->seqaddr & 0xff) { case 0x83: svga->attraddr = val & 0x1f; @@ -291,7 +297,31 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) break; case 0xa4: + if (ht216->id == 0x7861) + ht216->clk_sel = (val >> 2) & 0x0f; + else { + if (svga->getclock == ics1494_getclock) { + if (val & 0x10) + val &= ~0x10; + else if (!(val & 0x10)) + val |= 0x10; + } + ht216->clk_sel = (val >> 2) & 0x07; + } + if (ht216->id >= 0x7152) + svga->miscout = (svga->miscout & ~0x0c) | ((ht216->clk_sel & 0x03) << 2); + + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; case 0xf8: + if (ht216->id != 0x7861) { + if ((val & 0x06) == 0x06) + ht216->clk_sel = (val >> 5) & 0x07; + } else { + if ((val & 0x05) == 0x05) + ht216->clk_sel = (val >> 4) & 0x0f; + } svga->fullchange = changeframecount; svga_recalctimings(svga); break; @@ -459,7 +489,7 @@ ht216_out(uint16_t addr, uint8_t val, void *priv) io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&ht216->linear_mapping); - if (val & 8) { + if (val & 0x08) { io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); mem_mapping_enable(&svga->mapping); ht216_remap(ht216); @@ -539,6 +569,12 @@ ht216_in(uint16_t addr, void *priv) ht216->bg_plane_sel = 0; break; + case 0xff: + ret = ht216->ht_regs[0xff]; + if (is286 && (ht216->id != 0x7861)) + ret |= 0x80; + break; + default: break; } @@ -555,6 +591,7 @@ ht216_in(uint16_t addr, void *priv) case 0x3c9: if (ht216->id == 0x7152) return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); case 0x3cb: @@ -563,13 +600,14 @@ ht216_in(uint16_t addr, void *priv) break; case 0x3cc: - return svga->miscout; + return ht216->misc; case 0x3D4: return svga->crtcreg; case 0x3D5: if (svga->crtcreg == 0x1f) return svga->crtc[0xc] ^ 0xea; + return svga->crtc[svga->crtcreg]; default: @@ -628,8 +666,9 @@ ht216_recalctimings(svga_t *svga) ht216_t *ht216 = (ht216_t *) svga->priv; ibm8514_t *dev = (ibm8514_t *) svga->dev8514; mach_t *mach = (mach_t *) svga->ext8514; - int high_res_256 = 0; - + int high_res_256 = 0; + int clock0_override = 0; + int clock_sel; if (ht216->id == 0x7861) { if (ht216->ht_regs[0xe0] & 0x20) { @@ -640,24 +679,55 @@ ht216_recalctimings(svga_t *svga) } } - switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | ((ht216->ht_regs[0xf8] << 1) & 8)) { - case 0: - case 1: - break; - case 4: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; - break; - case 5: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; - break; - case 7: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 40000000.0; - break; - default: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 36000000.0; - break; - } + if (ht216->id <= 0x7140) { + clock_sel = (ht216->ht_regs[0xa4] >> 2) & 0x07; + if (ht216->ht_regs[0xf8] & 0x01) { + if (!(ht216->ht_regs[0xf8] & 0x10) && (((ht216->misc >> 2) & 0x03) == 0x03)) + clock0_override = 1; + else if (!(ht216->ht_regs[0xf8] & 0x08) && (((ht216->misc >> 2) & 0x03) == 0x02)) + clock0_override = 2; + } + if (!clock0_override) { + if (ht216->ht_regs[0xf8] & 0x02) { + if (ht216->ht_regs[0xf8] & 0x04) + clock_sel = (ht216->ht_regs[0xf8] >> 5) & 0x07; + } + switch (clock_sel) { + case 1: + if (!(ht216->ht_regs[0xf8] & 0x01)) + svga->clock = (cpuclock * (double) (1ULL << 32)) / 48540000.0; + break; + case 2: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0; + break; + case 3: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 32500000.0; + break; + case 4: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 50350000.0; + break; + case 5: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 65000000.0; + break; + case 6: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0; + break; + case 7: + svga->clock = (cpuclock * (double) (1ULL << 32)) / 40000000.0; + break; + default: + break; + } + } else { + if (clock0_override == 2) + svga->clock = (cpuclock * (double) (1ULL << 32)) / 38000000.0; + } + pclog("HT208 Select=%d, clock0override=%d, CRTC17=%02x, MISC=%02x, A4=%02x, FC=%02x, F8=%02x, FF=%02x, reset=%02x.\n", clock_sel, clock0_override, svga->crtc[0x17], ht216->misc & 0x0c, ht216->ht_regs[0xa4], ht216->ht_regs[0xfc], ht216->ht_regs[0xf8], ht216->ht_regs[0xff], svga->seqregs[0] & 0x03); + } else { + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(ht216->clk_sel, svga->clock_gen); + ht216_log("ClkSel V7=%02x, regf8=%02x, rega4=%02x, miscout=%x, vidclock=%02x.\n", ht216->clk_sel, ht216->ht_regs[0xf8], ht216->ht_regs[0xa4], (svga->miscout >> 2) & 0x03, svga->vidclock); + } svga->memaddr_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); if (ht216->ht_regs[0xf6] & 0x80) @@ -697,7 +767,6 @@ ht216_recalctimings(svga_t *svga) if (high_res_256) { svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - svga->clock /= 2; ht216->adjust_cursor = 1; } svga->render = svga_render_8bpp_highres; @@ -705,9 +774,8 @@ ht216_recalctimings(svga_t *svga) if (high_res_256) { svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - svga->clock /= 2; ht216->adjust_cursor = 1; - svga->render = svga_render_8bpp_highres; + svga->render = svga_render_8bpp_highres; } else { ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4); svga->render = svga_render_8bpp_lowres; @@ -717,6 +785,7 @@ ht216_recalctimings(svga_t *svga) svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); if (!(svga->crtc[1] & 1)) svga->hdisp--; + svga->hdisp++; svga->hdisp *= svga->dots_per_clock; svga->rowoffset <<= 1; @@ -729,9 +798,9 @@ ht216_recalctimings(svga_t *svga) svga->rowoffset <<= 1; svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - svga->clock /= 2; if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ svga->crtc[0x17] |= 0x40; + svga->render = svga_render_15bpp_highres; } } @@ -1513,10 +1582,17 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) { ht216_t *ht216 = malloc(sizeof(ht216_t)); svga_t *svga; + const char *bios_ver = NULL; + const char *fn = NULL; + const char *fn2 = NULL; memset(ht216, 0, sizeof(ht216_t)); svga = &ht216->svga; + ht216->id = info->local; + ht216->isabus = (info->flags & DEVICE_ISA) || (info->flags & DEVICE_ISA16); + ht216->mca = (info->flags & DEVICE_MCA); + if (info->flags & DEVICE_VLB) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); else if (info->flags & DEVICE_MCA) @@ -1532,10 +1608,18 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) switch (has_rom) { case 1: - rom_init(&ht216->bios_rom, BIOS_G2_GC205_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + fn = BIOS_G2_GC205_PATH; + rom_init(&ht216->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; case 2: - rom_init(&ht216->bios_rom, BIOS_VIDEO7_VGA_1024I_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + bios_ver = (char *) device_get_config_bios("bios_ver"); + fn = (char *) device_get_bios_file(info, bios_ver, 0); + if (!strcmp(bios_ver, "v7_04_hp")) { + fn2 = (char *) device_get_bios_file(info, bios_ver, 1); + rom_init_interleaved(&ht216->bios_rom, fn, fn2, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } else + rom_init(&ht216->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); break; case 3: ht216->monitor_type = device_get_config_int("monitor_type"); @@ -1583,13 +1667,20 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) break; } + svga->bpp = 8; + svga->miscout = 1; svga->hwcursor.cur_ysize = 32; ht216->vram_mask = mem_size - 1; svga->decode_mask = mem_size - 1; - if (has_rom == 4) + if (ht216->id == 0x7152) { svga->ramdac = device_add(&sc11484_nors2_ramdac_device); - + svga->clock_gen = device_add(&ics1494m_540_radius_ht209_device); + svga->getclock = ics1494_getclock; + } else if (ht216->id == 0x7861) { + svga->clock_gen = device_add(&icd2047_20_device); + svga->getclock = icd2047_getclock; + } svga->read = ht216_read; svga->readw = NULL; svga->readl = NULL; @@ -1607,16 +1698,9 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom) mem_mapping_set_p(&svga->mapping, ht216); mem_mapping_disable(&ht216->linear_mapping); - ht216->id = info->local; - ht216->isabus = (info->flags & DEVICE_ISA) || (info->flags & DEVICE_ISA16); - ht216->mca = (info->flags & DEVICE_MCA); - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - svga->bpp = 8; - svga->miscout = 1; - if (ht216->id == 0x7861) ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ @@ -1681,7 +1765,7 @@ g2_gc205_available(void) static int v7_vga_1024i_available(void) { - return rom_present(BIOS_VIDEO7_VGA_1024I_PATH); + return rom_present(BIOS_VIDEO7_VGA_1024I_219_PATH); } static int @@ -1724,6 +1808,46 @@ ht216_force_redraw(void *priv) // clang-format off static const device_config_t v7_vga_1024i_config[] = { + { + .name = "bios_ver", + .description = "BIOS Revision", + .type = CONFIG_BIOS, + .default_string = "v2_19", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "Version 2.19", + .internal_name = "v2_19", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { BIOS_VIDEO7_VGA_1024I_219_PATH, "" } + }, + { + .name = "Version 7.00", + .internal_name = "v7_00", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 32768, + .files = { BIOS_VIDEO7_VGA_1024I_700_PATH, "" } + }, + { + .name = "Version 7.04 (HP)", + .internal_name = "v7_04_hp", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 32768, + .files = { BIOS_VIDEO7_VGA_1024I_704_HP_LO_PATH, BIOS_VIDEO7_VGA_1024I_704_HP_HI_PATH, "" } + }, + { .files_no = 0 } + } + }, { .name = "memory", .description = "Memory size", diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 5aadd71f6a4..68de89767f5 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -4492,7 +4492,7 @@ blit_line(mystique_t *mystique, int closed, int autoline) if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { pattern_y = ((mystique->dwgreg.funcnt % (mystique->dwgreg.stylelen + 1)) >> 4) & 0x7; pattern_x = (mystique->dwgreg.funcnt % (mystique->dwgreg.stylelen + 1)) & 0xf; - if (!transc || (transc && (mystique->dwgreg.pattern[pattern_y][pattern_x]))) + if (!transc || (mystique->dwgreg.pattern[pattern_y][pattern_x])) switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: src = mystique->dwgreg.pattern[pattern_y][pattern_x] ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; @@ -4813,7 +4813,7 @@ blit_trap(mystique_t *mystique) int pattern = mystique->dwgreg.pattern[yoff][xoff]; uint32_t dst; - if (!transc || (transc && pattern)) + if (!transc || pattern) switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; @@ -4885,7 +4885,7 @@ blit_trap(mystique_t *mystique) uint32_t dst; uint32_t old_dst; - if (!transc || (transc && pattern)) + if (!transc || pattern) switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 48796fcc71e..4d8442d7a66 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -487,6 +487,7 @@ void paradise_recalctimings(svga_t *svga) { paradise_t *paradise = (paradise_t *) svga->priv; + int clk_sel = 0; svga->lowres = !(svga->gdcreg[0x0e] & 0x01); @@ -526,6 +527,11 @@ paradise_recalctimings(svga_t *svga) break; } } else { + clk_sel = ((svga->miscout >> 2) & 0x03); + if (!(svga->gdcreg[0x0c] & 0x02)) + clk_sel |= 0x04; + + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { if ((svga->bpp >= 8) && !svga->lowres) { if (svga->bpp == 16) { @@ -777,6 +783,8 @@ paradise_init(const device_t *info, uint32_t memory) paradise->vram_mask = (memory << 10) - 1; svga->decode_mask = (memory << 10) - 1; svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ + svga->clock_gen = device_add(&ics90c64a_903_device); + svga->getclock = ics90c64a_vclk_getclock; break; default: diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index fe982980cea..d9259d53af9 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -269,7 +269,7 @@ vid_get_h_overscan_delta(pcjr_t *pcjr) break; } - ret = pcjr->crtc[0x02] - def; + ret = def - pcjr->crtc[0x02]; if (ret < -8) ret = -8; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 2333d68b76e..cc3841750e4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -60,7 +60,7 @@ #define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" #define ROM_MIROCRYSTAL20SD_864_VLB "roms/video/s3/Miro20SD.BIN" #define ROM_PHOENIX_86C80X "roms/video/s3/805.VBI" -#define ROM_WINNER1000_805 "roms/video/s3/v01_05_00-C.BIN" +#define ROM_WINNER1000_805 "roms/video/s3/W1000ISA 01.03.00-B.BIN" #define ROM_PARADISE_BAHAMAS64 "roms/video/s3/bahamas64.bin" #define ROM_PHOENIX_VISION864 "roms/video/s3/86c864p.bin" #define ROM_DIAMOND_STEALTH64_964 "roms/video/s3/964_107h.rom" @@ -138,6 +138,7 @@ enum { S3_86C928PCI = 0x06, S3_86C801 = 0x07, S3_86C805 = 0x08, + S3_86C805I = 0x09, S3_VISION964 = 0x18, S3_VISION968 = 0x20, S3_VISION864 = 0x28, @@ -250,6 +251,7 @@ typedef struct s3_t { uint32_t vram_mask; uint8_t data_available; + uint16_t port_82ec; int card_type; @@ -282,15 +284,19 @@ typedef struct s3_t { uint8_t frgd_mix; uint16_t multifunc_cntl; uint16_t multifunc[16]; + uint16_t height; uint8_t pix_trans[4]; uint8_t pix_trans_val[2048][2048]; int pix_trans_inc; int ssv_state; + int read_sel_reg; + int multifunc_phase; int16_t cx, cy; int16_t px, py; int16_t sx, sy; int16_t dx, dy; + int16_t sx_inc; uint32_t src, dest, pattern; int poly_cx, poly_cx2; @@ -314,17 +320,11 @@ typedef struct s3_t { int color_16bit_check; int color_16bit_check_pixtrans; int16_t minus; - int16_t minus_src_24bpp; + int16_t blit_24bpp; int rd_mask_16bit_check; int start; int mix_dat_upper; int overflow; - - /*For non-threaded FIFO*/ - int setup_fifo_slot; - int draw_fifo_slot; - int setup_fifo, setup_fifo2; - int draw_fifo, draw_fifo2; } accel; struct { @@ -528,8 +528,9 @@ s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) if (FIFO_FULL) { thread_reset_event(s3->fifo_not_full_event); - if (FIFO_FULL) + if (FIFO_FULL) { thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } } fifo->val = val; @@ -592,10 +593,11 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 3)) & s3->vram_mask] << 24); \ - } else { \ + } else if ((s3->bpp == 1) || s3->color_16bit) { \ temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ temp |= (vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx + 2)) & (s3->vram_mask >> 1)] << 16); \ - } + } else \ + temp = vram_l[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 2)]; static int s3_cpu_src(s3_t *s3) @@ -656,7 +658,7 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) s3->accel_start(8, 1, val | (val << 16), 0, s3); } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cur_x & 0x400) val = (val >> 8) | (val << 8); @@ -671,7 +673,7 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) s3->accel_start(1, 1, 0xffffffff, val | (val << 16), s3); } } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cur_x & 0x400) val = (val >> 8) | (val << 8); @@ -723,6 +725,7 @@ s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) case 0x400: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_log("WORD WritePIXTRANS 32=%04x, SX=%d, SY=%d.\n", val, s3->accel.sx, s3->accel.sy); if (s3->accel.cmd & 0x1000) val = (val >> 8) | (val << 8); @@ -794,8 +797,10 @@ s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) case 0x400: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_log("LONG WritePIXTRANS 32=%08x.\n", val); if (s3->accel.cmd & 0x1000) val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3->accel_start(32, 1, val, 0, s3); } else s3->accel_start(4, 1, 0xffffffff, val, s3); @@ -828,18 +833,18 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { svga_t *svga = &s3->svga; - s3_log("OUTB FIFO=%04x, val=%02x.\n", port, val); switch (port) { case 0x8148: case 0x82e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; s3->accel.poly_cy = s3->accel.cur_y; break; case 0x8149: case 0x82e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); s3->accel.poly_cy = s3->accel.cur_y; - s3_log("[%04X:%08X] OUT PORTB=%04x, valy=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_y); break; case 0x814a: case 0x82ea: @@ -854,18 +859,19 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0x8548: case 0x86e8: - s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); + s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff00) | val; - s3->accel.poly_cx = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; + s3->accel.poly_cx = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x8549: case 0x86e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); s3->accel.cur_x_overflow = (s3->accel.cur_x_overflow & 0xff) | (val << 8); s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - s3_log("[%04X:%08X] OUT PORTB=%04x, valx=%d, valxover=%d.\n", CS, cpu_state.pc, port - 1, s3->accel.cur_x, s3->accel.cur_x_overflow); + s3->accel.poly_x = s3->accel.poly_cx >> 20; break; case 0x854a: case 0x86ea: @@ -881,15 +887,18 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xcae8: case 0x8948: case 0x8ae8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; s3->accel.point_1_updated = 1; break; case 0xcae9: case 0x8949: case 0x8ae9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) s3->accel.desty_axstp |= ~0x3fff; + s3->accel.point_1_updated = 1; break; case 0x894a: @@ -902,21 +911,25 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); if (val & 0x20) s3->accel.desty_axstp2 |= ~0x3fff; + s3->accel.point_2_updated = 1; break; case 0x8d48: case 0x8ee8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff00) | val; s3->accel.point_1_updated = 1; break; case 0x8d49: case 0x8ee9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); s3->accel.destx_overflow = (s3->accel.destx_overflow & 0xff) | (val << 8); if (val & 0x20) s3->accel.destx_distp |= ~0x3fff; + s3->accel.point_1_updated = 1; break; case 0x8d4a: @@ -980,6 +993,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; if (s3->bpp == 3) { + s3_log("Command Misc1=%04x.\n", s3->accel.multifunc[0xe]); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] &= ~0x10; } @@ -1235,6 +1249,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xa94a: case 0xaaea: + s3_log("[%04X:%08X] OUT PORTB=%04x (Write Mask), val=%02x.\n", CS, cpu_state.pc, port, val); if (s3->chip >= S3_VISION964) { if (s3->accel.multifunc[0xe] & 0x200) s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); @@ -1341,7 +1356,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb148: case 0xb2e8: s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); - if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) { + if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_86C928)) { s3->accel.b2e8_pix = 0; if (s3->bpp == 3) { if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { @@ -1383,7 +1398,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb149: case 0xb2e9: s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); - if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_VISION964)) { + if ((s3->accel.multifunc[0xe] & 0x100) || (s3->chip >= S3_86C928)) { s3->accel.b2e8_pix = 0; if (s3->bpp == 3) { if ((s3->chip >= S3_86C928) && (s3->chip < S3_VISION964)) { @@ -1515,24 +1530,50 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xb548: case 0xb6e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.bkgd_mix = val; break; + case 0xb549: + case 0xb6e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); + break; + case 0xb948: case 0xbae8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.frgd_mix = val; break; + case 0xb949: + case 0xbae9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); + break; + case 0xbd48: case 0xbee8: + if ((s3->accel.multifunc_cntl >> 12) == 0x00) { + s3->accel.multifunc_phase = 1; + s3->accel.height = s3->accel.multifunc[0]; + } s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; break; case 0xbd49: case 0xbee9: - s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); - s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; - if ((s3->accel.multifunc_cntl >> 12) == 5) - s3_log("S3 multifunc_cntl = %d, val = %03x.\n", s3->accel.multifunc_cntl >> 12, s3->accel.multifunc_cntl & 0xfff); + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); + if ((val >> 4) == 0x0f) { + s3->accel.read_sel_reg = s3->accel.multifunc_cntl & 0xfff; + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%x, multifunc idx=%x, multifunc_val=%03x.\n", CS, cpu_state.pc, port - 1, val >> 4, s3->accel.multifunc_cntl >> 12, s3->accel.multifunc_cntl & 0xfff); + } else { + s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; + if (s3->accel.multifunc_phase == 2) { + if (s3->accel.height != s3->accel.multifunc[0]) + s3->accel.multifunc[0] = s3->accel.height; + + s3->accel.multifunc_phase = 0; + } + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%x, multifunc idx=%x, multifunc_val=%03x.\n", CS, cpu_state.pc, port - 1, val >> 4, s3->accel.multifunc_cntl >> 12, s3->accel.multifunc_cntl & 0xfff); + } break; case 0xd148: @@ -1598,18 +1639,22 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe948: case 0xeae8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port, s3->accel.cmd); s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val; break; case 0xe949: case 0xeae9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port, s3->accel.cmd); s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x0f) << 8); break; case 0xe94a: case 0xeaea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port, s3->accel.cmd); s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val; break; case 0xe94b: case 0xeaeb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%04x.\n", CS, cpu_state.pc, port, s3->accel.cmd); s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x0f) << 8); break; case 0xed48: @@ -1675,13 +1720,13 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) if (s3->accel.cmd & 0x100) { switch (s3->accel.cmd & 0x600) { case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) s3->accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); else s3->accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { s3->accel.pix_trans[1] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx - s3->accel.minus)) & s3->vram_mask]; if (s3->accel.cmd & 0x1000) { @@ -2177,7 +2222,9 @@ s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) s3_accel_out_fifo_w(s3, 0x9ee8, val); } else if (((addr & 0x1fffe) >= 0x8000) && (addr & 0x1fffe) < 0x10000) { if (((addr & 0x1fffe) == 0xe2e8) || ((addr & 0x1fffe) == 0xe2ea)) { - if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || (s3->chip == S3_86C928) || (s3->chip == S3_86C928PCI)) + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || + (s3->chip == S3_86C928) || + (s3->chip == S3_86C928PCI)) s3_accel_out_pixtrans_w(s3, val); else { s3_accel_write_fifo(s3, addr, val); @@ -2306,9 +2353,10 @@ s3_hwcursor_draw(svga_t *svga, int displine) case 15: fg = video_15to32[s3->hwc_fg_col & 0xffff]; bg = video_15to32[s3->hwc_bg_col & 0xffff]; - if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805)) { + if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805I)) { if (!s3->color_16bit) { - if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805)) { + if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805) && + (s3->card_type != S3_WINNER1000_805)) { if (!(svga->crtc[0x45] & 0x04)) { shift = 2; width = 8; @@ -2331,9 +2379,10 @@ s3_hwcursor_draw(svga_t *svga, int displine) case 16: fg = video_16to32[s3->hwc_fg_col & 0xffff]; bg = video_16to32[s3->hwc_bg_col & 0xffff]; - if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805)) { + if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805I)) { if (!s3->color_16bit) { - if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805)) { + if ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805) && + (s3->card_type != S3_WINNER1000_805)) { if (!(svga->crtc[0x45] & 0x04)) { shift = 2; width = 8; @@ -2357,7 +2406,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) break; case 24: - if (s3->chip <= S3_86C805) { + if (s3->chip <= S3_86C805I) { fg = svga->pallook[svga->crtc[0xe]]; bg = svga->pallook[svga->crtc[0xf]]; } else { @@ -2832,6 +2881,7 @@ static void s3_io_remove(s3_t *s3) { io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_removehandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2874,12 +2924,11 @@ s3_io_set_alt(s3_t *s3) if (!s3->translate) return; - if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { + if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) return; - } io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { io_sethandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2934,6 +2983,7 @@ s3_io_set(s3_t *s3) return; } + io_sethandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2993,6 +3043,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + s3_log("%04X:%08X: %03X: s3_out: val=%02x.\n", CS, cpu_state.pc, addr, val); + switch (addr) { case 0x3c2: if (svga->getclock == icd2061_getclock) { @@ -3127,11 +3179,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x40: s3->enable_8514 = val & 0x01; + s3_log("Enable 8514/A functions=%02x.\n", val & 0x01); break; case 0x50: s3->bpp = (svga->crtc[0x50] >> 4) & 3; - s3_log("S3 BPP=%d.\n", s3->bpp); + s3_log("S3 BPP=%d, VGA=%d, Misc1=%04x.\n", s3->bpp, svga->bpp, s3->accel.multifunc[0xe]); if (s3->bpp == 3) { if (!(s3->accel.multifunc[0xe] & 0x200)) /*On True Color mode change, reset bit 4 of Misc Index register*/ s3->accel.multifunc[0xe] &= ~0x10; @@ -3166,7 +3219,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x51: - if (s3->chip == S3_86C801 || s3->chip == S3_86C805) { + if ((s3->chip == S3_86C801) || (s3->chip == S3_86C805) || + (s3->chip == S3_86C805I)) { s3->bank = (s3->bank & 0x6f) | ((val & 0x4) << 2); s3->ma_ext = (s3->ma_ext & ~0x4) | ((val & 1) << 2); } else { @@ -3190,10 +3244,10 @@ s3_out(uint16_t addr, uint8_t val, void *priv) break; case 0x45: + s3_log("Write CRTC45=%02x.\n", val); if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968)) break; svga->hwcursor.ena = val & 1; - s3_log("Write CRTC45=%02x.\n", val); break; case 0x46: case 0x47: @@ -3295,11 +3349,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x43: if (s3->chip < S3_VISION964) { - if (s3->chip <= S3_86C805) + if (s3->chip <= S3_86C805I) svga_recalctimings(svga); s3_io_remove_alt(s3); s3->translate = !!(val & 0x10); + s3_log("Translate=%02x.\n", s3->translate); s3_io_set_alt(s3); } break; @@ -3349,6 +3404,12 @@ s3_out(uint16_t addr, uint8_t val, void *priv) } break; + case 0x82ec: + s3->port_82ec = (s3->port_82ec & 0xff00) | val; + break; + case 0x82ed: + s3->port_82ec = (s3->port_82ec & 0xff) | (val << 8); + break; default: break; } @@ -3363,10 +3424,13 @@ s3_in(uint16_t addr, void *priv) int rs2; int rs3; uint8_t temp; + uint8_t temp2; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + s3_log("%04X:%08X: %03X: s3_in.\n", CS, cpu_state.pc, addr); + switch (addr) { case 0x3c1: if (svga->attraddr > 0x14) @@ -3376,7 +3440,8 @@ s3_in(uint16_t addr, void *priv) case 0x3c2: if (s3->elsa_eeprom) { temp = nmc93cxx_eeprom_read(s3->eeprom) ? 0x10 : 0x00; - return (svga_in(addr, svga) & 0xef) | temp; + temp2 = (svga_in(addr, svga) & 0xef) | temp; + return temp2; } if (s3->chip <= S3_86C924) return svga_in(addr, svga) | 0x10; @@ -3423,8 +3488,8 @@ s3_in(uint16_t addr, void *priv) temp = att498_ramdac_in(addr, rs2, svga->ramdac, svga); break; case BT48X: - if (s3->chip == S3_86C928) - rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + if (s3->card_type == S3_METHEUS_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode in the Metheus card*/ else rs3 = !!(svga->crtc[0x55] & 0x02); @@ -3446,6 +3511,7 @@ s3_in(uint16_t addr, void *priv) case 0x3d4: return svga->crtcreg; case 0x3d5: + s3_log("%04X:%08X: s3_in: crtc=%02x.\n", CS, cpu_state.pc, svga->crtcreg); switch (svga->crtcreg) { case 0x2d: return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ @@ -3515,6 +3581,11 @@ s3_in(uint16_t addr, void *priv) } return svga->crtc[svga->crtcreg]; + case 0x82ec: + return s3->port_82ec & 0xff; + case 0x82ed: + return s3->port_82ec >> 8; + default: break; } @@ -3658,9 +3729,10 @@ s3_readl(uint32_t addr, void *priv) static void s3_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *) svga->priv; - int clk_sel = (svga->miscout >> 2) & 3; + s3_t *s3 = (s3_t *) svga->priv; + int clk_sel = (svga->miscout >> 2) & 3; uint8_t mask = 0xc0; + int enhanced_8bpp_modes = 0x00; if (svga->crtc[0x33] & 0x20) { /* In this mode, the dots per clock are always 8 or 16, never 9 or 18. */ @@ -3719,6 +3791,7 @@ s3_recalctimings(svga_t *svga) if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip < S3_TRIO32)) clk_sel = svga->crtc[0x42] & 0x0f; + s3_log("MiscOut=%02x, cr42=%02x.\n", (svga->miscout >> 2) & 3, svga->crtc[0x42] & 0x0f); svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); switch (s3->ramdac_type) { @@ -3737,12 +3810,12 @@ s3_recalctimings(svga_t *svga) break; } - if (s3->chip >= S3_TRIO32) { + if ((s3->chip >= S3_TRIO32) || (s3->chip == S3_86C805I)) { switch (svga->crtc[0x67] >> 4) { case 3: case 5: case 7: - svga->clock /= 2; + svga->clock /= 2.0; break; default: @@ -3750,19 +3823,7 @@ s3_recalctimings(svga_t *svga) } } - if (s3->chip <= S3_86C805) { - s3->color_16bit = !!(svga->crtc[0x43] & 0x08); - s3_log("Color 16bit=%x, bpp=%d, 256color=%x.\n", s3->color_16bit, svga->bpp, (svga->attrregs[0x10] & 0x40)); - if ((svga->bpp == 24) || (svga->bpp == 8)) - s3->color_16bit = 0; - - if (s3->color_16bit) - s3->width = 1024; - else { - if (s3->chip <= S3_86C924) - s3->width = 1024; - } - } + enhanced_8bpp_modes = !!((svga->crtc[0x3a] & 0x10) && !svga->lowres); if (s3->chip >= S3_86C928) { if (s3->chip != S3_86C801) @@ -3771,8 +3832,6 @@ s3_recalctimings(svga_t *svga) switch (svga->crtc[0x50] & mask) { case 0x00: s3->width = (svga->crtc[0x31] & 0x02) ? 2048 : 1024; - if (s3->color_16bit) - s3->width = 1024; break; case 0x01: s3->width = 1152; @@ -3781,7 +3840,8 @@ s3_recalctimings(svga_t *svga) s3->width = 640; break; case 0x80: - s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 0x04)) ? 1600 : 800; + /*For later chips, bit 2 of port 0x4ae8 means 1600x1200x4bpp if the original width is 800 (per Vision864 manual).*/ + s3->width = ((s3->chip > S3_86C805I) && (s3->accel.advfunc_cntl & 0x04) && !enhanced_8bpp_modes) ? 1600 : 800; break; case 0x81: s3->width = 1600; @@ -3794,6 +3854,20 @@ s3_recalctimings(svga_t *svga) } } + if (s3->chip <= S3_86C805I) { + s3->color_16bit = !!(svga->crtc[0x43] & 0x08); + s3_log("Color 16bit=%x, bpp=%d, 256color=%x.\n", s3->color_16bit, svga->bpp, (svga->attrregs[0x10] & 0x40)); + if ((svga->bpp == 24) || (svga->bpp == 8)) + s3->color_16bit = 0; + + if (s3->color_16bit) + s3->width = 1024; + else { + if (s3->chip <= S3_86C924) + s3->width = 1024; + } + } + if (svga->crtc[0x33] & 0x20) { /* The S3 version of the Cirrus' special blanking mode, with identical behavior. */ svga->hblankstart = (((svga->crtc[0x5d] & 0x02) >> 1) << 8) + svga->crtc[1]/* + @@ -3822,11 +3896,11 @@ s3_recalctimings(svga_t *svga) } } - if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { + if (enhanced_8bpp_modes) { s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " - "attr=%02x, hdisp=%d, dotsperclock=%x, clksel=%x, clockmultiplier=%d, multiplexingrate=%d.\n", svga->bpp, s3->width, svga->crtc[0x50], + "attr=%02x, hdisp=%d, dotsperclock=%x, clksel=%x, clockmultiplier=%d, multiplexingrate=%d, mapenable=%x.\n", svga->bpp, s3->width, svga->crtc[0x50], svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 0x04, - svga->attrregs[0x10] & 0x40, svga->hdisp, svga->dots_per_clock, clk_sel, svga->clock_multiplier, svga->multiplexing_rate); + svga->attrregs[0x10] & 0x40, svga->hdisp, svga->dots_per_clock, clk_sel, svga->clock_multiplier, svga->multiplexing_rate, svga->mapping.enable); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; @@ -3839,15 +3913,24 @@ s3_recalctimings(svga_t *svga) if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) { if (svga->multiplexing_rate == 2) { - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; + if (svga->clock_multiplier == 1) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + svga->clock *= 2.0; + } else { + if (clk_sel > 2) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + svga->clock *= 4.0; + } + } } else { if (!svga->clock_multiplier) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; + svga->clock *= 2.0; } } - svga->clock *= 2.0; } else { if (svga->multiplexing_rate == 0) { svga->hdisp <<= 1; @@ -3875,70 +3958,65 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_86C801: + case S3_86C805: + case S3_86C805I: case S3_86C928PCI: if (!svga->chain4) svga->chain4 |= 0x08; break; case S3_VISION964: - switch (s3->card_type) { - case S3_ELSAWIN2KPROX_964: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + } + break; + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + break; + default: + break; + } + break; + case S3_VISION868: + switch (s3->ramdac_type) { + case ATT498: /*AT&T 498 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (s3->width >= 1024) + svga->clock /= 2.0; } break; - default: break; } break; case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: - if (svga->hdisp == 832) - svga->hdisp -= 32; + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + if (!s3->elsa_eeprom) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } break; - case S3_DIAMOND_STEALTH64_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - case S3_SPEA_MERCURY_P64V: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; + case TVP3026: /*TVP3026 RAMDAC and clock chip*/ + s3_log("TVP3026 968 8bpp: MiscOut=%x, clksel=%x.\n", (svga->miscout >> 2) & 3, clk_sel); + if (clk_sel == 2) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } else if ((clk_sel == 3) && (s3->width >= 1024)) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } if (svga->hdisp == 832) svga->hdisp -= 32; break; - case S3_ELSAWIN2KPROX: - s3_log("S3 width 8bpp=%d, hdisp=%d.\n", s3->width, svga->hdisp); - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; - } - break; - default: break; } @@ -3958,45 +4036,35 @@ s3_recalctimings(svga_t *svga) break; case S3_86C801: - switch (s3->card_type) { - case S3_PHOENIX_86C801: + case S3_86C805: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; break; - + case ATT49X: /*AT&T 490/1/2 RAMDAC*/ + if (svga->dots_per_clock != 16) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->clock *= 2.0; + svga->dots_per_clock >>= 2; + } + break; default: break; } break; - case S3_86C805: - switch (s3->card_type) { - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - case S3_WINNER1000_805: - case S3_PHOENIX_86C805: - case S3_86C805_ONBOARD: - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - break; - - case S3_SPEA_MIRAGE_86C805: + case S3_86C805I: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - switch (s3->width) { - case 800: - case 1024: - if (svga->hdisp == 400) { - /*SPEA specific drivers + its VBE RAM BIOS...*/ - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock /= 2.0; - } - break; - default: - break; - } break; - default: break; } @@ -4085,93 +4153,66 @@ s3_recalctimings(svga_t *svga) case S3_VISION864: svga->hdisp >>= 1; svga->dots_per_clock >>= 1; + svga->clock /= 2.0; break; case S3_VISION964: - switch (s3->card_type) { - case S3_ELSAWIN2KPROX_964: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); } break; - + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + break; default: break; } break; case S3_VISION868: - switch (s3->card_type) { - case S3_PHOENIX_VISION868: - case S3_NUMBER9_9FX_531: + switch (s3->ramdac_type) { + case ATT498: /*AT&T 498 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + svga->clock /= 2.0; + } + break; + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; svga->clock /= 2.0; break; - default: break; } break; case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: - if (svga->hdisp == 832) - svga->hdisp -= 32; + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + if (!s3->elsa_eeprom) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } break; - case S3_DIAMOND_STEALTH64_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - case S3_SPEA_MERCURY_P64V: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; - /* TODO: Is this still needed? */ + case TVP3026: /*TVP3026 RAMDAC and clock chip*/ + s3_log("TVP3026 968 15bpp: MiscOut=%x, clksel=%x.\n", (svga->miscout >> 2) & 3, clk_sel); + if (clk_sel == 2) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } else if ((clk_sel == 3) && (s3->width >= 1024)) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } if (svga->hdisp == 832) svga->hdisp -= 32; break; - - case S3_ELSAWIN2KPROX: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; - } - break; default: break; } @@ -4197,43 +4238,35 @@ s3_recalctimings(svga_t *svga) break; case S3_86C801: - switch (s3->card_type) { - case S3_PHOENIX_86C801: + case S3_86C805: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; break; - + case ATT49X: /*AT&T 490/1/2 RAMDAC*/ + if (svga->dots_per_clock != 16) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->clock *= 2.0; + svga->dots_per_clock >>= 2; + } + break; default: break; } break; - case S3_86C805: - switch (s3->card_type) { - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - case S3_WINNER1000_805: - case S3_PHOENIX_86C805: - case S3_86C805_ONBOARD: + case S3_86C805I: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; break; - - case S3_SPEA_MIRAGE_86C805: - svga->hdisp >>= 1; - switch (s3->width) { - case 800: - case 1024: - if (svga->hdisp == 400) { - /*SPEA specific drivers + its VBE RAM BIOS...*/ - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - break; - default: - break; - } - break; - default: break; } @@ -4322,92 +4355,66 @@ s3_recalctimings(svga_t *svga) case S3_VISION864: svga->hdisp >>= 1; svga->dots_per_clock >>= 1; + svga->clock /= 2.0; break; case S3_VISION868: - switch (s3->card_type) { - case S3_PHOENIX_VISION868: - case S3_NUMBER9_9FX_531: + switch (s3->ramdac_type) { + case ATT498: /*AT&T 498 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + svga->clock /= 2.0; + } + break; + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; + svga->clock /= 2.0; break; - default: break; } break; case S3_VISION964: - switch (s3->card_type) { - case S3_ELSAWIN2KPROX_964: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); } break; - + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + break; default: break; } break; case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + if (!s3->elsa_eeprom) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } + break; + case TVP3026: /*TVP3026 RAMDAC and clock chip*/ + if (clk_sel == 2) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } else if ((clk_sel == 3) && (s3->width >= 1024)) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } + s3_log("TVP3026 968 16bpp: MiscOut=%x, clksel=%x.\n", (svga->miscout >> 2) & 3, clk_sel); if (svga->hdisp == 832) svga->hdisp -= 32; break; - case S3_DIAMOND_STEALTH64_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - case S3_SPEA_MERCURY_P64V: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; - /* TODO: Is this still needed? */ - if (svga->hdisp == 832) - svga->hdisp -= 32; - break; - - case S3_ELSAWIN2KPROX: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; - } - break; default: break; } @@ -4440,26 +4447,15 @@ s3_recalctimings(svga_t *svga) } break; case S3_86C801: - switch (s3->card_type) { - case S3_PHOENIX_86C801: - case S3_SPEA_MIRAGE_86C801: - svga->hdisp = (svga->hdisp << 1) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; - break; - default: - break; - } - break; case S3_86C805: - switch (s3->card_type) { - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - case S3_WINNER1000_805: - case S3_PHOENIX_86C805: - case S3_SPEA_MIRAGE_86C805: - case S3_86C805_ONBOARD: + case S3_86C805I: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: svga->hdisp = (svga->hdisp << 1) / 3; svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + svga->clock = (svga->clock * 4.0) / 3.0; break; default: break; @@ -4470,21 +4466,24 @@ s3_recalctimings(svga_t *svga) svga->chain4 |= 0x08; break; case S3_86C928PCI: /*Technically the 928 cards don't support 24bpp.*/ - switch (s3->card_type) { - case S3_ELSAWIN1KPCI_86C928: - if (svga->dots_per_clock == 16) { - svga->dots_per_clock >>= 1; + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + svga->clock = (svga->clock * 4.0) / 3.0; + if (svga->hdisp == 640) + s3->width = 640; + } + } else if (svga->getclock == av9194_getclock) { /*AV9194 clock chip*/ svga->hdisp = (svga->hdisp << 1) / 3; svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; - svga->clock /= (2.0 / 3.0); - if (svga->hdisp == 640) - s3->width = 640; } break; - case S3_SPEA_MERCURY_LITE_PCI: - svga->hdisp = (svga->hdisp << 1) / 3; - svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; - break; default: break; } @@ -4492,14 +4491,34 @@ s3_recalctimings(svga_t *svga) case S3_VISION864: svga->hdisp = (svga->hdisp << 1) / 3; svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; - svga->clock /= (2.0 / 3.0); + svga->clock = (svga->clock * 4.0) / 3.0; break; case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: - svga->hdisp = (svga->hdisp / 3) << 2; - svga->dots_per_clock = (svga->hdisp / 3) << 2; + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp = (svga->hdisp << 2) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 2) / 3; + svga->clock = (svga->clock * 4.0) / 3.0; + svga->clock /= 2.0; + if (!s3->elsa_eeprom) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } + break; + + case TVP3026: /*TVP3026 RAMDAC and clock chip*/ + svga->hdisp = (svga->hdisp << 1) / 3; + if (clk_sel >= 2) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock = (svga->clock * 4.0) / 3.0; + } + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + + s3_log("TVP3026 968 24bpp: MiscOut=%x, clksel=%x.\n", (svga->miscout >> 2) & 3, clk_sel); + if (svga->hdisp == 832) + svga->hdisp -= 32; break; default: break; @@ -4519,6 +4538,25 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_86C805I: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + if (s3->width == 800) { + if ((svga->crtc[0x67] >> 4) == 7) { + svga->clock *= 2.0; + s3_log("800x600: MEMLatch=%08x, htotal=%x.\n", svga->memaddr_latch, svga->htotal); + } + } + break; + default: + break; + } + break; + case S3_86C928: if (!svga->chain4) svga->chain4 |= 0x08; @@ -4538,16 +4576,21 @@ s3_recalctimings(svga_t *svga) break; case SC1502X: /*SC15025 RAMDAC*/ if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + s3_log("32bpp 928 ISA VL SC1502X double=%02x, highres=%02x, dotperclock=%d, clksel=%d, pitch=%d, hdisp=%d, clock=%02x.\n", + svga->crtc[0x31] & 0x02, s3->accel.advfunc_cntl & 0x04, svga->dots_per_clock, clk_sel, s3->width, svga->hdisp, svga->crtc[0x67] >> 4); if (svga->crtc[0x31] & 0x02) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - if (svga->hdisp == 640) - s3->width = 1024; + if (svga->dots_per_clock == 16) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + if (svga->hdisp == 640) + s3->width = 1024; + } } else { svga->hdisp >>= 2; svga->dots_per_clock >>= 2; if (svga->hdisp == 800) - s3->width = 1024; + svga->clock *= 2.0; } } break; @@ -4576,103 +4619,58 @@ s3_recalctimings(svga_t *svga) case S3_VISION864: svga->hdisp >>= 2; svga->dots_per_clock >>= 2; + svga->clock /= 2.0; break; case S3_VISION868: - switch (s3->card_type) { - case S3_PHOENIX_VISION868: - case S3_NUMBER9_9FX_531: + switch (s3->ramdac_type) { + case ATT498: /*AT&T 498 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + case S3_SDAC: /*S3 SDAC/GENDAC RAMDAC with its clock chip*/ svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - svga->clock /= 2.0; break; default: break; } break; case S3_VISION964: - switch (s3->card_type) { - case S3_MIROCRYSTAL20SV_964: - switch (s3->width) { - case 800: - case 1024: - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - svga->clock /= 2.0; - break; - default: - break; - } - break; - case S3_ELSAWIN2KPROX_964: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; - } + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); break; default: break; } break; case S3_VISION968: - switch (s3->card_type) { - case S3_MIROVIDEO40SV_ERGO_968: - if (svga->hdisp == 832) - svga->hdisp -= 32; + switch (s3->ramdac_type) { + case IBM_RGB: /*IBM RGB528 RAMDAC and clock chip*/ + svga->hdisp *= (svga->clock_multiplier + 1); + svga->dots_per_clock *= (svga->clock_multiplier + 1); + if (!s3->elsa_eeprom) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } break; - case S3_DIAMOND_STEALTH64_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - case S3_SPEA_MERCURY_P64V: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; - /* TODO: Is this still needed? */ + case TVP3026: /*TVP3026 RAMDAC and clock chip*/ + s3_log("TVP3026 968 32bpp: MiscOut=%x, clksel=%x.\n", (svga->miscout >> 2) & 3, clk_sel); + if (clk_sel == 2) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } else if ((clk_sel == 3) && (s3->width >= 1024)) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } if (svga->hdisp == 832) svga->hdisp -= 32; break; - - case S3_ELSAWIN2KPROX: - switch (s3->width) { - case 1280: - case 1600: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - case 2048: - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - break; - default: - break; - } - break; default: break; } @@ -4703,10 +4701,13 @@ s3_recalctimings(svga_t *svga) svga->write_bank = 0; svga->read_bank = 0; } + /*In non-enhanced/IBM VGA modes, reset the misc index registers.*/ + s3->accel.multifunc[0xd] = 0x000; + s3->accel.multifunc[0xe] = 0x000; } } - if ((((s3->card_type == S3_ELSAWIN1K_86C928) || (s3->card_type == S3_ELSAWIN1KPCI_86C928)) && (svga->bpp == 32)) || + if ((s3->elsa_eeprom && (svga->bpp == 32)) || (s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else @@ -4938,7 +4939,7 @@ s3_updatemapping(s3_t *s3) /*Banked framebuffer*/ if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ { - s3_log("Enhanced Mode Mapping.\n"); + s3_log("Enhanced Mode Mapping, gdc6=%02x.\n", svga->gdcreg[6] & 0xc); /* Enhanced mode forces 64kb at 0xa0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; @@ -4976,7 +4977,8 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928) { s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (s3->chip <= S3_86C805) { + s3_log("Initial linear base=%08x, crtc58=%02x, crtc53=%02x.\n", s3->linear_base, svga->crtc[0x58], svga->crtc[0x53]); + if (s3->chip <= S3_86C805I) { if (s3->vlb) s3->linear_base &= 0x03ffffff; else if (!s3->pci) @@ -5016,11 +5018,13 @@ s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); + s3_log("First LinearBase update=%x, size=%x, mmio1=%02x, mmio2=%02x, mapenable=%x.\n", s3->linear_base, s3->linear_size, svga->crtc[0x53] & 0x10, s3->accel.advfunc_cntl & 0x20, svga->mapping.enable); if ((s3->linear_base == 0xa0000) || (s3->linear_size == 0x10000)) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; + s3_log("Actually enable banked mapping=%d.\n", svga->mapping.enable); } } else { if (s3->chip >= S3_TRIO64V) @@ -5028,7 +5032,7 @@ s3_updatemapping(s3_t *s3) else if ((s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) s3->linear_base &= 0xfe000000; - s3_log("LinearBase update=%x, size=%x.\n", s3->linear_base, s3->linear_size); + s3_log("Update LinearBase update=%x, size=%x.\n", s3->linear_base, s3->linear_size); if (s3->linear_base) mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); else @@ -5036,8 +5040,8 @@ s3_updatemapping(s3_t *s3) } svga->fb_only = 1; } else { - svga->fb_only = 0; mem_mapping_disable(&s3->linear_mapping); + svga->fb_only = 0; } /* Memory mapped I/O. */ @@ -5094,6 +5098,8 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; + s3_log("%04X:%08X: OUTB FIFO=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); + if (port >= 0x8000) { if (!s3->enable_8514) return; @@ -5115,18 +5121,19 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) s3->accel.subsys_cntl = (s3->accel.subsys_cntl & 0xff) | (val << 8); s3_update_irqs(s3); break; - case 0x4548: case 0x46e8: - s3->accel.setup_md = val; + s3->accel.setup_md = (s3->accel.setup_md & 0xff00) | val; + break; + case 0x46e9: + s3->accel.setup_md = (s3->accel.setup_md & 0xff) | (val << 8); break; case 0x4948: case 0x4ae8: s3->accel.advfunc_cntl = val; - if ((s3->chip > S3_86C805) && ((svga->crtc[0x50] & 0xc1) == 0x80)) { - s3->width = (val & 4) ? 1600 : 800; + if ((s3->chip > S3_86C805I) && ((svga->crtc[0x50] & 0xc1) == 0x80)) { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); - } else if (s3->chip <= S3_86C805) { + } else if (s3->chip <= S3_86C805I) { svga->fullchange = svga->monitor->mon_changeframecount; svga_recalctimings(svga); } @@ -5144,6 +5151,8 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *priv) { s3_t *s3 = (s3_t *) priv; + s3_log("%04X:%08X: OUTW FIFO=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + if (!s3->enable_8514) return; @@ -5158,6 +5167,8 @@ s3_accel_out_l(uint16_t port, uint32_t val, void *priv) { s3_t *s3 = (s3_t *) priv; + s3_log("%04X:%08X: OUTL FIFO=%04x, val=%08x.\n", CS, cpu_state.pc, port, val); + if (!s3->enable_8514) return; @@ -5175,6 +5186,8 @@ s3_accel_in(uint16_t port, void *priv) int temp; uint8_t temp2 = 0x00; + s3_log("%04X:%08X: INB=%04x.\n", CS, cpu_state.pc, port); + if (!s3->enable_8514) return 0xff; @@ -5186,6 +5199,13 @@ s3_accel_in(uint16_t port, void *priv) case 0x42e9: return s3->accel.subsys_cntl >> 8; + case 0x4948: + case 0x4ae8: + return s3->accel.advfunc_cntl; + case 0x4949: + case 0x4ae9: + return 0x00; + case 0x8148: case 0x82e8: if (s3_enable_fifo(s3)) @@ -5286,6 +5306,7 @@ s3_accel_in(uint16_t port, void *priv) case 0x9949: case 0x9ae9: temp = 0; + s3_log("FIFO=%x, cmd=%d, sy=%d.\n", s3_enable_fifo(s3), s3->accel.cmd >> 13, s3->accel.sy); if (s3_enable_fifo(s3)) { if (!s3->blitter_busy) wake_fifo_thread(s3); @@ -5312,17 +5333,26 @@ s3_accel_in(uint16_t port, void *priv) else { switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn on FIFO empty bits!*/ case 0: - if (!s3->accel.ssv_len) + if (s3->accel.cmd & 0x100) { + if (!s3->accel.ssv_len) + temp |= 0x04; + } else temp |= 0x04; break; case 1: - if (!s3->accel.sy) + if (s3->accel.cmd & 0x100) { + if (!s3->accel.sy) + temp |= 0x04; + } else temp |= 0x04; break; case 2: case 6: case 7: - if (s3->accel.sy < 0) + if (s3->accel.cmd & 0x100) { + if (s3->accel.sy < 0) + temp |= 0x04; + } else temp |= 0x04; break; @@ -5726,9 +5756,20 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.color_cmp >> 16; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.color_cmp >> 16; + else + temp2 = s3->accel.color_cmp & 0xff; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 16; + else + temp2 = s3->accel.color_cmp & 0xff; + } + } else temp2 = s3->accel.color_cmp & 0xff; return temp2; @@ -5739,13 +5780,34 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) - temp2 = s3->accel.color_cmp >> 24; - else + + if (s3->bpp == 3) { + if (s3->chip < S3_VISION964) { + if (s3->accel.multifunc[0xe] & 0x10) + temp2 = s3->accel.color_cmp >> 24; + else + temp2 = s3->accel.color_cmp >> 8; + + s3->accel.multifunc[0xe] ^= 0x10; + } else { + if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 24; + else + temp2 = s3->accel.color_cmp >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } else { temp2 = s3->accel.color_cmp >> 8; - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; + if (s3->chip < S3_VISION964) + s3->accel.multifunc[0xe] ^= 0x10; + else { + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + } + } return temp2; } break; @@ -5796,7 +5858,11 @@ s3_accel_in(uint16_t port, void *priv) if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); if (s3->chip >= S3_VISION964) { - temp = s3->accel.multifunc[0xf] & 0xf; + temp = s3->accel.read_sel_reg & 0xf; + s3_log("964 and up: ReadSelReg=%x.\n", temp); + if (s3->accel.multifunc_phase == 1) + s3->accel.multifunc_phase = 2; + switch (temp) { case 0x0: return s3->accel.multifunc[0x0] & 0xff; @@ -5825,7 +5891,7 @@ s3_accel_in(uint16_t port, void *priv) break; } } else { - temp = s3->accel.multifunc[0xf] & 7; + temp = s3->accel.read_sel_reg & 7; switch (temp) { case 0x0: return s3->accel.multifunc[0x0] & 0xff; @@ -5857,8 +5923,8 @@ s3_accel_in(uint16_t port, void *priv) if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); if (s3->chip >= S3_VISION964) { - temp = s3->accel.multifunc[0xf] & 0xf; - s3->accel.multifunc[0xf] = (s3->accel.multifunc[0xf] + 1) & 0xf; + temp = s3->accel.read_sel_reg & 0xf; + s3->accel.read_sel_reg = (s3->accel.read_sel_reg + 1) & 0xf; switch (temp) { case 0x0: return s3->accel.multifunc[0x0] >> 8; @@ -5875,11 +5941,11 @@ s3_accel_in(uint16_t port, void *priv) case 0x6: return s3->accel.multifunc[0xe] >> 8; case 0x7: - return s3->accel.cmd >> 8; + return (s3->accel.cmd >> 8) & ~0xf0; case 0x8: - return (s3->accel.subsys_cntl >> 8) & ~0xe000; + return (s3->accel.subsys_cntl >> 8) & ~0xe0; case 0x9: - return (s3->accel.setup_md >> 8) & ~0xf000; + return s3->accel.setup_md >> 8; case 0xa: return s3->accel.multifunc[0xd] >> 8; @@ -5887,8 +5953,8 @@ s3_accel_in(uint16_t port, void *priv) break; } } else { - temp = s3->accel.multifunc[0xf] & 7; - s3->accel.multifunc[0xf] = (s3->accel.multifunc[0xf] + 1) & 7; + temp = s3->accel.read_sel_reg & 7; + s3->accel.read_sel_reg = (s3->accel.read_sel_reg + 1) & 7; switch (temp) { case 0x0: return s3->accel.multifunc[0x0] >> 8; @@ -5905,7 +5971,7 @@ s3_accel_in(uint16_t port, void *priv) case 0x6: return s3->accel.multifunc[0xe] >> 8; case 0x7: - return s3->accel.cmd >> 8; + return (s3->accel.cmd >> 8) & ~0xf0; default: break; @@ -6247,6 +6313,7 @@ s3_accel_in_w(uint16_t port, void *priv) if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD + s3_log("PIXTRANS WORD READ=%04x.\n", s3->accel.cmd); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { @@ -6256,7 +6323,7 @@ s3_accel_in_w(uint16_t port, void *priv) s3->accel_start(8, 1, temp | (temp << 16), 0, s3); } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cur_x & 0x400) temp = (temp >> 8) | (temp << 8); @@ -6266,7 +6333,7 @@ s3_accel_in_w(uint16_t port, void *priv) s3->accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); } } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cur_x & 0x400) temp = (temp >> 8) | (temp << 8); @@ -6326,6 +6393,7 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) svga_t *svga = &s3->svga; uint32_t temp = 0x00000000; const uint16_t *vram_w = (uint16_t *) svga->vram; + const uint32_t *vram_l = (uint32_t *) svga->vram; if (!s3->enable_8514) return 0xffffffff; @@ -6333,6 +6401,7 @@ s3_accel_in_l(UNUSED(uint16_t port), void *priv) if (s3_cpu_dest(s3)) { READ_PIXTRANS_LONG + s3_log("PIXTRANS LONG READ=%04x.\n", s3->accel.cmd); switch (s3->accel.cmd & 0x600) { case 0x000: if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { @@ -6443,6 +6512,7 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) s3_accel_write_fifo(s3, addr, val); break; default: + s3_log("FIFOWORD Write=%04x, val=%04x.\n", addr & (addr_mask - 1), val); s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_WORD); break; } @@ -6607,6 +6677,7 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) break; default: + s3_log("FIFOLONG Write=%04x, val=%08x.\n", addr & (addr_mask - 3), val); s3_queue(s3, addr & addr_mask, val, FIFO_WRITE_DWORD); break; } @@ -6745,6 +6816,7 @@ s3_accel_read_l(uint32_t addr, void *priv) svga_t *svga = &s3->svga; uint32_t temp = 0x00000000; const uint16_t *vram_w = (uint16_t *) svga->vram; + const uint32_t *vram_l = (uint32_t *) svga->vram; if (!s3->enable_8514) return 0xffffffff; @@ -6962,7 +7034,7 @@ polygon_setup(s3_t *s3) } #define READ(addr, dat) \ - if (((s3->bpp == 0) && !s3->color_16bit) || (s3->bpp == 2)) \ + if (((s3->bpp == 0) && !s3->color_16bit)) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ else if ((s3->bpp == 1) || s3->color_16bit) \ dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ @@ -7807,12 +7879,10 @@ polygon_setup(s3_t *s3) { \ old_dest_dat = dest_dat; \ ROPMIX_READ(dest_dat, pat_dat, src_dat); \ - out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ - out &= 0xFFFFFF; \ } #define WRITE(addr, dat) \ - if (((s3->bpp == 0) && !s3->color_16bit) || (s3->bpp == 2)) { \ + if (((s3->bpp == 0) && !s3->color_16bit)) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ } else if ((s3->bpp == 1) || s3->color_16bit) { \ @@ -8041,7 +8111,7 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.busy = 1; if (host) { - if (idf == 0 && odf == 0) { + if ((idf == 0) && (odf == 0)) { if (s3->bpp == 0) count = 4; else if (s3->bpp == 1) @@ -8093,6 +8163,7 @@ s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) s3->videoengine.dx = 0.0; } + s3_log("VideoEngine count=%d.\n", count); while (count) { if (host) { /*Source data is CPU*/ src = cpu_dat; @@ -8235,6 +8306,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi int clip_r = s3->accel.multifunc[4] & 0xfff; int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; uint32_t mix_mask = 0; + uint8_t *vram_b = svga->vram; uint16_t *vram_w = (uint16_t *) svga->vram; uint32_t *vram_l = (uint32_t *) svga->vram; uint32_t compare = s3->accel.color_cmp; @@ -8268,7 +8340,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 1) || s3->color_16bit) { srcbase >>= 1; dstbase >>= 1; - } else if (s3->bpp == 3) { + } else if (s3->bpp >= 2) { srcbase >>= 2; dstbase >>= 2; } @@ -8279,21 +8351,23 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (!cpu_input) s3->accel.dat_count = 0; - if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 0x02)))) { - if ((s3->bpp == 3) && (count == 2)) { - if (s3->accel.dat_count) { - cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; - count = 4; - s3->accel.dat_count = 0; - } else { - s3->accel.dat_buf = cpu_dat & 0xffff; - s3->accel.dat_count = 1; + if (cpu_input) { + if (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 0x02))) { + if ((s3->bpp == 3) && (count == 2)) { + if (s3->accel.dat_count) { + cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; + count = 4; + s3->accel.dat_count = 0; + } else { + s3->accel.dat_buf = cpu_dat & 0xffff; + s3->accel.dat_count = 1; + } } + if ((s3->bpp == 1) || s3->color_16bit) + count >>= 1; + else if (s3->bpp >= 2) + count >>= 2; } - if ((s3->bpp == 1) || s3->color_16bit) - count >>= 1; - else if (s3->bpp == 3) - count >>= 2; } if ((s3->bpp == 0) && !s3->color_16bit) @@ -8327,7 +8401,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on the NOP command)*/ - s3_log("CMD=%d, full=%04x, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%02x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%04x, mix=%04x, count=%d, rd_mask=%04x, wrt_mask=%04x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%04x, bkgdcolor=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x.\n", cmd, s3->accel.cmd, s3->bpp, clip_r, clip_b, s3->accel.multifunc[0x0a] & 0xc4, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffff, mix_dat & 0xffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix); + s3_log("CMD=%d, full=%04x, cnt=%d, s3bpp=%x, clr=%d, clb=%d, sourcedisplay=%02x, mmio=%02x, srcbase=%08x, dstbase=%08x, cpu=%08x, mix=%08x, count=%d, rd_mask=%08x, wrt_mask=%08x, width=%d, s=%d,%d, c=%d,%d, d=%d,%d, 16bitcolor=%x, frgdcolor=%08x, bkgdcolor=%08x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, curx=%d, cury=%d, cll=%d, b2e8pix=%x, multifuncE=%03x.\n", cmd, s3->accel.cmd, count, s3->bpp, clip_r, clip_b, s3->accel.multifunc[0x0a] & 0xc4, svga->crtc[0x53] & 0x18, srcbase, dstbase, cpu_dat & 0xffffffff, mix_dat & 0xffffffff, count, rd_mask, wrt_mask, s3->width, s3->accel.sx, s3->accel.sy, s3->accel.cx, s3->accel.cy, s3->accel.destx_distp, s3->accel.desty_axstp, s3->color_16bit, frgd_color, bkgd_color, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.cur_x, s3->accel.cur_y, clip_l, s3->accel.b2e8_pix, s3->accel.multifunc[0xe]); switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ @@ -8444,6 +8518,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->bpp == 2) { + s3->accel.cx *= 3; + s3->accel.cy *= 3; + } + s3->accel.sy = s3->accel.maj_axis_pcnt; if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; @@ -8468,66 +8547,179 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } if (s3->accel.cmd & 0x08) { /*Radial*/ - if ((s3->bpp == 0) && s3->color_16bit) { - if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.minus) { - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } - rd_mask &= 0x00ff; - } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) - break; - } + if (s3->bpp == 2) { + wrt_mask = s3->accel.wrt_mask; + rd_mask = s3->accel.rd_mask; - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + if ((rd_mask == 0x0000ffff) || (rd_mask == 0x000000ff)) + rd_mask = 0xffffffff; - default: - break; - } + while (count-- && (s3->accel.sy >= 0)) { + if ((s3->accel.cx & 0xfff) >= (clip_l * 3) && (s3->accel.cx & 0xfff) <= (clip_r * 3) && (s3->accel.cy & 0xfff) >= (clip_t * 3) && (s3->accel.cy & 0xfff) <= (clip_b * 3)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; - if (s3->accel.multifunc[0xe] & 0x100) { - if (s3->accel.multifunc[0xe] & 0x80) { - if (src_dat != compare) - update = 0; - else - update = 1; - } else { - if (src_dat == compare) - update = 0; - else - update = 1; + default: + break; } - } else - update = 1; - - if (update) { - READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - - old_dest_dat = dest_dat; - MIX - WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); - } - } + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + dest_dat = (*(uint32_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask]) & 0xffffff; + + old_dest_dat = dest_dat; + MIX + + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx + 1 - (s3->accel.minus * 3)) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx + 2 - (s3->accel.minus * 3)) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[(((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } + } + + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 16; + + if (!s3->accel.sy) { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; + } + break; + } + + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx += 3; + break; + case 0x20: + s3->accel.cx += 3; + s3->accel.cy -= 3; + break; + case 0x40: + s3->accel.cy -= 3; + break; + case 0x60: + s3->accel.cx -= 3; + s3->accel.cy -= 3; + break; + case 0x80: + s3->accel.cx -= 3; + break; + case 0xa0: + s3->accel.cx -= 3; + s3->accel.cy += 3; + break; + case 0xc0: + s3->accel.cy += 3; + break; + case 0xe0: + s3->accel.cx += 3; + s3->accel.cy += 3; + break; + + default: + break; + } + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = (s3->accel.cx / 3) & 0xfff; + s3->accel.cur_y = (s3->accel.cy / 3) & 0xfff; + break; + } + + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); + } else { + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; + } + rd_mask &= 0x00ff; + } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) + break; + } + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + READ((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + + old_dest_dat = dest_dat; + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx - s3->accel.minus, dest_dat); + } + } mix_dat <<= 1; mix_dat |= 1; @@ -8589,7 +8781,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Pattern on pixtrans (911/924)*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); @@ -8605,7 +8797,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } } else { - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit || (svga->bpp == 24))) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); @@ -8625,6 +8817,132 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (!s3->accel.b2e8_pix) s3_log("CMDFULL=%04x, FRGDMIX=%x, FRGDCOLR=%04x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, CLIPT=%d, CLIPB=%d.\n", s3->accel.cmd, frgd_mix, s3->accel.frgd_color, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, clip_t, clip_b); + if (s3->bpp == 2) { + wrt_mask = s3->accel.wrt_mask; + rd_mask = s3->accel.rd_mask; + + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + if ((rd_mask == 0x0000ffff) || (rd_mask == 0x000000ff)) + rd_mask = 0xffffffff; + + while (count-- && (s3->accel.sy >= 0)) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if (s3->accel.minus) + s3_log("Total pixel cx=%d, cy=%d.\n", s3->accel.cx - s3->accel.minus, s3->accel.cy); + + if ((s3->accel.cx & 0xfff) >= (clip_l * 3) && (s3->accel.cx & 0xfff) <= (clip_r * 3) && (s3->accel.cy & 0xfff) >= (clip_t * 3) && (s3->accel.cy & 0xfff) <= (clip_b * 3)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + dest_dat = (*(uint32_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask]) & 0xffffff; + + old_dest_dat = dest_dat; + MIX + + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx + 1 - (s3->accel.minus * 3)) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[((s3->accel.cy * s3->width) + s3->accel.cx + 2 - (s3->accel.minus * 3)) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[(((s3->accel.cy * s3->width) + s3->accel.cx - (s3->accel.minus * 3)) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + + cpu_dat >>= 16; + + if (!s3->accel.sy) { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) + s3->accel.color_16bit_check = 0; + else + s3->accel.color_16bit_check = 1; + } + break; + } + + if (s3->accel.cmd & 0x40) { + if (s3->accel.cmd & 0x80) + s3->accel.cy += 3; + else + s3->accel.cy -= 3; + + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x20) + s3->accel.cx += 3; + else + s3->accel.cx -= 3; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } else { + if (s3->accel.cmd & 0x20) + s3->accel.cx += 3; + else + s3->accel.cx -= 3; + + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { + s3->accel.err_term += s3->accel.destx_distp; + if (s3->accel.cmd & 0x80) + s3->accel.cy += 3; + else + s3->accel.cy -= 3; + } else + s3->accel.err_term += s3->accel.desty_axstp; + } + + s3->accel.sy--; + s3->accel.cx &= 0xfff; + s3->accel.cy &= 0xfff; + } + s3->accel.cur_x = (s3->accel.cx / 3) & 0xfff; + s3->accel.cur_y = (s3->accel.cy / 3) & 0xfff; + break; + } while (count-- && (s3->accel.sy >= 0)) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; @@ -8754,11 +9072,21 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->bpp == 2) { + s3_log("24bpp x68 rectfill: cmd=%04x CX=%d, CY=%d.\n", s3->accel.cmd, s3->accel.cx, s3->accel.cy); + s3->accel.cx *= 3; + s3->accel.cy *= 3; + } else if ((s3->bpp == 0) && (svga->bpp == 24)) + s3_log("24bpp 80x rectfill: BKGDCOLOR=%04x, FRGDCOLOR=%04x.\n", bkgd_color, frgd_color); + s3->accel.dest = dstbase + s3->accel.cy * s3->width; if ((s3->bpp == 0) && s3->color_16bit) { + if (!rd_mask && (clip_r == 0x7ff)) + rd_mask = 0xff; + s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; - s3_log("CMD2: RDMASK16CHECK=%d, rdmask=%04x.\n", s3->accel.rd_mask_16bit_check, rd_mask); + s3_log("CMD2: %04X: RDMASK16CHECK=%d, rdmask=%04x, clip_r=%04x.\n", s3->accel.cmd, s3->accel.rd_mask_16bit_check, rd_mask, clip_r); if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cmd == 0x41b3) { if (frgd_mix == 0) { @@ -8822,19 +9150,21 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Pattern on pixtrans (911/924)*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; - if (s3->accel.rd_mask_16bit_check) { - if (s3->accel.minus) { - wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); - frgd_color = (s3->accel.frgd_color_actual[1] << 8); - bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); - } else { - wrt_mask = s3->accel.wrt_mask_actual[0]; - frgd_color = s3->accel.frgd_color_actual[0]; - bkgd_color = s3->accel.bkgd_color_actual[0]; - } - rd_mask &= 0x00ff; - } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) - break; + if ((s3->bpp == 0) && s3->color_16bit) { + if (s3->accel.rd_mask_16bit_check) { + if (s3->accel.minus) { + wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); + frgd_color = (s3->accel.frgd_color_actual[1] << 8); + bkgd_color = (s3->accel.bkgd_color_actual[1] << 8); + } else { + wrt_mask = s3->accel.wrt_mask_actual[0]; + frgd_color = s3->accel.frgd_color_actual[0]; + bkgd_color = s3->accel.bkgd_color_actual[0]; + } + rd_mask &= 0x00ff; + } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.cur_x & 0x400)) + break; + } } else { if ((s3->bpp == 0) && s3->color_16bit) { if (s3->accel.cmd == 0x41b3) { @@ -8884,7 +9214,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3_log("FIXME: S3 911/924 15/16bpp documentation needed.\n"); } else { if (!cpu_input && (s3->accel.cur_x & 0x400)) { - s3_log("No Input.\n"); + s3_log("No Input on %04x.\n", s3->accel.cmd); break; } else if (cpu_input && (s3->accel.cmd == 0x53b3) && (s3->accel.cur_x & 0x400)) break; @@ -8896,6 +9226,118 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + if ((s3->bpp == 2) || (svga->bpp == 24)) { + int multiplier = 1; + if (s3->bpp == 2) { + multiplier = 3; + wrt_mask = s3->accel.wrt_mask; + rd_mask = s3->accel.rd_mask; + + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + if ((rd_mask == 0x00ffffff) || (rd_mask == 0x0000ffff) || (rd_mask == 0x000000ff)) + rd_mask = 0xffffffff; + } + + while (count-- && (s3->accel.sy >= 0)) { + if ((((s3->accel.cx >= (clip_l * multiplier)) && (s3->accel.cx <= (clip_r * multiplier)) && (s3->accel.cy >= (clip_t * multiplier)) && (s3->accel.cy <= (clip_b * multiplier))) && !(s3->accel.multifunc[0xe] & 0x20)) || + (((s3->accel.cx < (clip_l * multiplier)) && (s3->accel.cx > (clip_r * multiplier)) && (s3->accel.cy < (clip_t * multiplier)) && (s3->accel.cy > (clip_b * multiplier))) && (s3->accel.multifunc[0xe] & 0x20)) ) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + + default: + break; + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + if (s3->bpp == 2) + dest_dat = (*(uint32_t *) &vram_b[(s3->accel.dest + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + else { + READ(s3->accel.dest + s3->accel.cx, dest_dat); + } + + old_dest_dat = dest_dat; + MIX + + if (s3->accel.cmd & 0x10) { + if (s3->bpp == 2) { + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.cx) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.cx + 1) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.cx + 2) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[((s3->accel.dest + s3->accel.cx) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } else { + WRITE(s3->accel.dest + s3->accel.cx, dest_dat); + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) + s3->accel.cx += multiplier; + else + s3->accel.cx -= multiplier; + + s3->accel.cx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cx *= multiplier; + + if (s3->accel.cmd & 0x80) + s3->accel.cy += multiplier; + else + s3->accel.cy -= multiplier; + + s3->accel.cy &= 0xfff; + s3->accel.dest = dstbase + s3->accel.cy * s3->width; + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx / multiplier; + s3->accel.cur_y = s3->accel.cy / multiplier; + return; + } + } + } + return; + } + while (count-- && (s3->accel.sy >= 0)) { if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; @@ -9151,7 +9593,6 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 6: /*BitBlt*/ if (!cpu_input) { /*!cpu_input is trigger to start operation*/ s3->accel.minus = 0; - s3->accel.minus_src_24bpp = 0; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; @@ -9161,6 +9602,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->bpp == 2) { + s3->accel.dx *= 3; + s3->accel.dy *= 3; + s3->accel.cx *= 3; + s3->accel.cy *= 3; + s3->accel.blit_24bpp = 0; + } else if ((s3->bpp == 0) && (svga->bpp == 24)) { + s3_log("BitBLT bpp%d: 24bpp params=%04x, dwidth=%d, dheight=%d, swidth=%d, sheight=%d, lwidth=%d, lheight=%d, srcbase=%08x, dstbase=%08x, blit24 times=%d, moddx=%d, modcx=%d.\n", s3->bpp, s3->accel.cmd, s3->accel.dx / 3, s3->accel.dy, s3->accel.cx / 3, s3->accel.cy, s3->accel.sx / 3, s3->accel.sy, srcbase, dstbase, s3->accel.blit_24bpp, s3->accel.dx % 3, s3->accel.cx % 3); + s3->accel.blit_24bpp = (s3->accel.blit_24bpp + 1) & 3; + } else + s3->accel.blit_24bpp = 0; + if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; s3_log("CMD6: RDMASK16CHECK=%d.\n", s3->accel.rd_mask_16bit_check); @@ -9193,7 +9646,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - if ((s3->bpp == 0) && s3->color_16bit) { + if ((s3->bpp == 0) && (s3->color_16bit)) { if (s3->accel.rd_mask_16bit_check) { if (s3->accel.minus) { wrt_mask = (s3->accel.wrt_mask_actual[1] << 8); @@ -9204,13 +9657,210 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi frgd_color = s3->accel.frgd_color_actual[0]; bkgd_color = s3->accel.bkgd_color_actual[0]; } - rd_mask &= 0x00ff; - } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.destx_distp & 0x400)) - break; + rd_mask &= 0x00ff; + } else if (!s3->accel.rd_mask_16bit_check && (s3->accel.destx_distp & 0x400)) + break; + } + + s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); + + if ((s3->bpp == 2) || (svga->bpp == 24)) { + int multiplier = 1; + if (s3->bpp == 2) { + multiplier = 3; + wrt_mask = s3->accel.wrt_mask; + rd_mask = s3->accel.rd_mask; + + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + if (rd_mask == 0x0000ffff) + rd_mask = 0xffffffff; + } + + if (!cpu_input && (frgd_mix == 3) && !vram_mask && !(s3->accel.multifunc[0xe] & 0x100) && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { + s3_log("Special BitBLT24, wrtmask=%04x.\n", wrt_mask); + while (1) { + if ((s3->accel.dx >= (clip_l * multiplier)) && (s3->accel.dx <= (clip_r * multiplier)) && (s3->accel.dy >= (clip_t * multiplier)) && (s3->accel.dy <= (clip_b * multiplier))) { + if (s3->bpp == 2) { + src_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + dest_dat = (*(uint32_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask]) & 0xffffff; + } else { + READ(s3->accel.src + s3->accel.cx, src_dat); + READ(s3->accel.dest + s3->accel.dx, dest_dat); + } + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + + if (s3->accel.cmd & 0x10) { + s3_log("CMD6 special bitblt24 bpp%d: dest=%02x, src=%06x, dx=%d, dy=%d, cx=%d, cy=%d, sx=%d, sy=%d.\n", s3->bpp, dest_dat, src_dat, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, s3->accel.sx, s3->accel.sy); + if (s3->bpp == 2) { + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 1) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 2) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[((s3->accel.dest + s3->accel.dx) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } else { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } + } + } + + s3->accel.cx += multiplier; + s3->accel.dx += multiplier; + s3->accel.sx--; + + s3->accel.dx &= 0xfff; + + if (s3->accel.sx < 0) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cx *= multiplier; + s3->accel.dx *= multiplier; + + s3->accel.cy += multiplier; + s3->accel.dy += multiplier; + + s3->accel.src = srcbase + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); + + s3->accel.sy--; + + if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx / multiplier; + s3->accel.desty_axstp = s3->accel.dy / multiplier; + return; + } + } + } + } else { + s3_log("Normal24 blit, srcbase=%08x, dstbase=%08x, full=%04x, wrt_mask=%08x, extmultifunc0e=%03x, frgdmixval=%02x.\n", srcbase, dstbase, s3->accel.cmd, wrt_mask, s3->accel.multifunc[0x0e] & 0x180, s3->accel.frgd_mix); + while (count-- && (s3->accel.sy >= 0)) { + if ((s3->accel.dx >= (clip_l * multiplier)) && (s3->accel.dx <= (clip_r * multiplier)) && ((s3->accel.dy >= clip_t * multiplier)) && (s3->accel.dy <= (clip_b * multiplier))) { + if (vram_mask && (s3->accel.cmd & 0x10)) { + if (s3->bpp == 2) + mix_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + else { + READ(s3->accel.src + s3->accel.cx, mix_dat); + } + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (s3->bpp == 2) + src_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + else { + READ(s3->accel.src + s3->accel.cx, src_dat); + } + if (vram_mask && (s3->accel.cmd & 0x10)) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + + default: + break; + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + if (s3->bpp == 2) + dest_dat = (*(uint32_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask]) & 0xffffff; + else { + READ(s3->accel.dest + s3->accel.dx, dest_dat); + } + + old_dest_dat = dest_dat; + MIX + + if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { + s3_log("CMD6 %04x: normal bitblt24 bpp%d: dest=%02x, src=%02x, old=%02x, dx=%d, dy=%d, cx=%d, cy=%d, sx=%d, sy=%d, moddx=%d, modcx=%d, frgdmix=%02x, bkgdmix=%02x.\n", s3->accel.cmd, s3->bpp, dest_dat, src_dat, old_dest_dat, s3->accel.dx / 3, s3->accel.dy, s3->accel.cx / 3, s3->accel.cy, s3->accel.sx / 3, s3->accel.sy, s3->accel.dx % 3, s3->accel.cx % 3, s3->accel.frgd_mix, s3->accel.bkgd_mix); + if (s3->bpp == 2) { + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 1) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 2) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[((s3->accel.dest + s3->accel.dx) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } else { + if (s3->accel.blit_24bpp == 5) { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx += multiplier; + s3->accel.dx += multiplier; + } else { + s3->accel.cx -= multiplier; + s3->accel.dx -= multiplier; + } + + s3->accel.dx &= 0xfff; + + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cx *= multiplier; + s3->accel.dx *= multiplier; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy += multiplier; + s3->accel.dy += multiplier; + } else { + s3->accel.cy -= multiplier; + s3->accel.dy -= multiplier; + } + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx / multiplier; + s3->accel.desty_axstp = s3->accel.dy / multiplier; + return; + } + } + } + } + break; } - s3_log("CMDFULL=%04x, FRGDSEL=%x, BKGDSEL=%x, FRGDMIX=%02x, BKGDMIX=%02x, MASKCHECK=%x, RDMASK=%04x, MINUS=%d, WRTMASK=%04X, MIX=%04x, CX=%d, CY=%d, DX=%d, DY=%d, SX=%d, SY=%d, PIXCNTL=%02x, 16BITCOLOR=%x, RDCHECK=%x, CLIPL=%d, CLIPR=%d, OVERFLOW=%d, pitch=%d.\n", s3->accel.cmd, frgd_mix, bkgd_mix, s3->accel.frgd_mix & 0x0f, s3->accel.bkgd_mix & 0x0f, s3->accel.rd_mask_16bit_check, rd_mask, s3->accel.minus, wrt_mask, mix_dat & 0xffff, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy, s3->accel.sx, s3->accel.sy, s3->accel.multifunc[0x0a] & 0xc4, s3->accel.color_16bit_check, s3->accel.rd_mask_16bit_check, clip_l, clip_r, (s3->accel.destx_overflow & 0xc00) == 0xc00, s3->width); - if (!cpu_input && (frgd_mix == 3) && !vram_mask && !(s3->accel.multifunc[0xe] & 0x100) && ((s3->accel.cmd & 0xa0) == 0xa0) && ((s3->accel.frgd_mix & 0xf) == 7) && ((s3->accel.bkgd_mix & 0xf) == 7)) { s3_log("Special BitBLT.\n"); while (1) { @@ -9398,6 +10048,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->bpp == 2) { + s3->accel.dx *= 3; + s3->accel.dy *= 3; + s3->accel.cx *= 3; + s3->accel.cy *= 3; + } + /*Align source with destination*/ s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -9411,6 +10068,119 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->bpp == 2) { + wrt_mask = s3->accel.wrt_mask; + rd_mask = s3->accel.rd_mask; + + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + if (rd_mask == 0x0000ffff) + rd_mask = 0xffffffff; + + while (count-- && (s3->accel.sy >= 0)) { + if ((s3->accel.dx >= (clip_l * 3)) && (s3->accel.dx <= (clip_r * 3)) && (s3->accel.dy >= (clip_t * 3)) && (s3->accel.dy <= (clip_b * 3))) { + if (vram_mask) { + mix_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + + default: + break; + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + dest_dat = (*(uint32_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask]) & 0xffffff; + + old_dest_dat = dest_dat; + MIX + + if (s3->accel.cmd & 0x10) { + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask] = dest_dat & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 1) & s3->vram_mask] = (dest_dat >> 8) & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 2) & s3->vram_mask] = (dest_dat >> 16) & 0xff; + svga->changedvram[((s3->accel.dest + s3->accel.dx) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx = ((s3->accel.cx + 3) & 7) | (s3->accel.cx & ~7); + s3->accel.dx += 3; + } else { + s3->accel.cx = ((s3->accel.cx - 3) & 7) | (s3->accel.cx & ~7); + s3->accel.dx -= 3; + } + s3->accel.dx &= 0xfff; + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cx *= 3; + s3->accel.dx *= 3; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy = ((s3->accel.cy + 3) & 7) | (s3->accel.cy & ~7); + s3->accel.dy += 3; + } else { + s3->accel.cy = ((s3->accel.cy - 3) & 7) | (s3->accel.cy & ~7); + s3->accel.dy -= 3; + } + + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx / 3; + s3->accel.desty_axstp = s3->accel.dy / 3; + return; + } + } + } + break; + } + while (count-- && (s3->accel.sy >= 0)) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { if (vram_mask) { @@ -9756,8 +10526,11 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi case 14: /*ROPBlt (Vision868/968 only)*/ ; - uint32_t mono_pattern[64] = { 0 }; - if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) + uint32_t mono_pattern[8][8] = { 0 }; + int use_rop_mix = 0; + uint32_t vram_dat = 0; + + if ((s3->chip != S3_VISION968) && (s3->chip != S3_VISION868)) break; if (!cpu_input) /*!cpu_input is trigger to start operation*/ @@ -9774,18 +10547,26 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.px = s3->accel.pat_x & 0xfff; s3->accel.py = s3->accel.pat_y & 0xfff; + if (s3->bpp == 2) { + s3->accel.dx *= 3; + s3->accel.dy *= 3; + s3->accel.cx *= 3; + s3->accel.cy *= 3; + s3->accel.px *= 3; + s3->accel.py *= 3; + } + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); - s3_log("ROPBLT=%04x, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%x, BKGDSEL=%x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.px, s3->accel.py, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, frgd_mix, bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); + + s3_log("ROPBLT=%04x, BPP=%d, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, SX=%d, SY=%d, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%02x, BKGDSEL=%02x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->bpp, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.sx, s3->accel.sy, s3->accel.pat_x, s3->accel.pat_y, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, s3->accel.frgd_mix, s3->accel.bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ if (s3->accel.ropmix & 0x100) { - int x; - int y; switch (s3->accel.cmd & 0x600) { case 0x000: case 0x600: @@ -9798,13 +10579,246 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - mono_pattern[y * 8 + (7 - x)] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + if (cpu_input) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 0x02)) { + if ((frgd_mix < 2) || (bkgd_mix < 2)) + use_rop_mix = 3; + } else { + if ((frgd_mix == 2) || (bkgd_mix == 2)) + use_rop_mix = 2; + } + } else { + if ((s3->accel.multifunc[0xa] & 0xc0) != 0x80) { + if ((frgd_mix == 3) || (bkgd_mix == 3)) + use_rop_mix = 1; + } + } + + if (use_rop_mix == 3) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + mono_pattern[y][7 - x] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } else if (use_rop_mix == 2) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + mono_pattern[y][7 - x] = (cpu_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } else if (use_rop_mix <= 1) { + if (use_rop_mix == 0) + frgd_mix = 3; + + if (s3->bpp == 2) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + vram_dat = (*(uint32_t *) &vram_b[(((s3->accel.py + (y * 3)) * s3->width) + s3->accel.px + (x * 3)) & s3->vram_mask]) & 0xffffff; + if ((s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x800000; + else if (!(s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x800000); + else if ((s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x800000); + else if (!(s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x800000; + + if (s3->accel.pat_bg_color != s3->accel.pat_fg_color) + s3_log("MonoPattern Screen=%08x, y=%d, x=%d, sel=%08x, vram=%08x.\n", mono_pattern[y][7 - x], y, 7 - x, vram_dat & 0x800000, vram_dat); + } + } + } else if (s3->bpp == 1) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + vram_dat = vram_w[(((s3->accel.py + y) * s3->width) + s3->accel.px + x) & (s3->vram_mask >> 1)]; + if ((s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x8000; + else if (!(s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x8000); + else if ((s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x8000); + else if (!(s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x80000; + } + } + } else if (s3->bpp == 3) { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + vram_dat = vram_l[(((s3->accel.py + y) * s3->width) + s3->accel.px + x) & (s3->vram_mask >> 2)]; + if ((s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x80000000; + else if (!(s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x80000000); + else if ((s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x80000000); + else if (!(s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x80000000; + } + } + } else { + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + vram_dat = svga->vram[(((s3->accel.py + y) * s3->width) + s3->accel.px + x) & s3->vram_mask]; + if ((s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x800; + else if (!(s3->accel.dx & 1) && (s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x80); + else if ((s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = !(vram_dat & 0x80); + else if (!(s3->accel.dx & 1) && !(s3->accel.dy & 1)) + mono_pattern[y][7 - x] = vram_dat & 0x80; + } + } + } + } + } + + if (s3->bpp == 2) { + wrt_mask = s3->accel.wrt_mask; + if (wrt_mask == 0x0000ffff) + wrt_mask = 0xffffffff; + + while (count-- && (s3->accel.sy >= 0)) { + if ((s3->accel.dx >= (clip_l * 3)) && (s3->accel.dx <= (clip_r * 3)) && (s3->accel.dy >= (clip_t * 3)) && (s3->accel.dy <= (clip_b * 3))) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = (*(uint32_t *) &vram_b[(s3->accel.src + s3->accel.cx) & s3->vram_mask]) & 0xffffff; + break; + + default: + break; + } + + if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ + if (use_rop_mix <= 1) { + pat_dat = mono_pattern[(s3->accel.py / 3) & 7][(s3->accel.px / 3) & 7] ? s3->accel.pat_fg_color : s3->accel.pat_bg_color; + if (s3->accel.pat_bg_color != s3->accel.pat_fg_color) + s3_log("PatternData=%06x, PX=%d, PY=%d, MonoSel=%06x.\n", pat_dat, (s3->accel.px / 3) & 7, (s3->accel.py / 3) & 7, vram_dat); + } else { + switch (mono_pattern[(s3->accel.py / 3) & 7][(s3->accel.px / 3) & 7] ? (frgd_mix & 1) : (bkgd_mix & 1)) { + case 0: + pat_dat = s3->accel.pat_bg_color; + break; + case 1: + pat_dat = s3->accel.pat_fg_color; + break; + default: + break; + } + } + } else { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + pat_dat = s3->accel.bkgd_color; + break; + case 1: + pat_dat = s3->accel.frgd_color; + break; + case 2: + pat_dat = cpu_dat; + break; + case 3: + pat_dat = (*(uint32_t *) &vram_b[(s3->accel.pattern + s3->accel.px) & s3->vram_mask]) & 0xffffff; + break; + + default: + break; + } + } + + if (s3->accel.multifunc[0xe] & 0x100) { + if (s3->accel.multifunc[0xe] & 0x80) { + if (src_dat != compare) + update = 0; + else + update = 1; + } else { + if (src_dat == compare) + update = 0; + else + update = 1; + } + } else + update = 1; + + if (update) { + dest_dat = (*(uint32_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask]) & 0xffffff; + + ROPMIX + out = (out & wrt_mask) | (old_dest_dat & ~wrt_mask); + + if (s3->accel.cmd & 0x10) { + s3_log("ROPBLT24 ROPSET=%03x, DX=%d, DY=%d, OUT=%02x, SRCC=%08x, DSTC=%08x.\n", s3->accel.ropmix, s3->accel.dx, s3->accel.dy, out, (s3->accel.src + s3->accel.cx) & (s3->vram_mask >> 2), (s3->accel.dest + s3->accel.dx) & (s3->vram_mask >> 2)); + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx) & s3->vram_mask] = out & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 1) & s3->vram_mask] = (out >> 8) & 0xff; + *(uint8_t *) &vram_b[(s3->accel.dest + s3->accel.dx + 2) & s3->vram_mask] = (out >> 16) & 0xff; + svga->changedvram[((s3->accel.dest + s3->accel.dx) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx += 3; + s3->accel.dx += 3; + s3->accel.px += 3; + } else { + s3->accel.cx -= 3; + s3->accel.dx -= 3; + s3->accel.px -= 3; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.dx = s3->accel.destx_distp & 0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.px = s3->accel.pat_x & 0xfff; + + s3->accel.dx *= 3; + s3->accel.cx *= 3; + s3->accel.px *= 3; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy += 3; + s3->accel.dy += 3; + s3->accel.py += 3; + } else { + s3->accel.cy -= 3; + s3->accel.dy -= 3; + s3->accel.py -= 3; + } + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); + s3->accel.src = srcbase + (s3->accel.cy * s3->width); + s3->accel.pattern = (s3->accel.py * s3->width); + + s3->accel.sy--; + + if (cpu_input) + return; + + if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx / 3; + s3->accel.desty_axstp = s3->accel.dy / 3; + return; + } } } + break; } - while (count-- && s3->accel.sy >= 0) { + while (count-- && (s3->accel.sy >= 0)) { if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9825,17 +10839,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ - switch (mono_pattern[(s3->accel.py & 7) * 8 + (s3->accel.px & 7)] ? (frgd_mix & 1) : (bkgd_mix & 1)) { - case 0: - pat_dat = s3->accel.pat_bg_color; - break; - case 1: - pat_dat = s3->accel.pat_fg_color; - break; - default: - break; + if (use_rop_mix <= 1) + pat_dat = mono_pattern[s3->accel.py & 7][s3->accel.px & 7] ? s3->accel.pat_fg_color : s3->accel.pat_bg_color; + else { + switch (mono_pattern[s3->accel.py & 7][s3->accel.px & 7] ? (frgd_mix & 1) : (bkgd_mix & 1)) { + case 0: + pat_dat = s3->accel.pat_bg_color; + break; + case 1: + pat_dat = s3->accel.pat_fg_color; + break; + default: + break; + } } - s3_log("MonoMIX=%08x, PX=%d, PY=%d.\n", mix_dat, s3->accel.px & 7, s3->accel.py & 7); } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9875,8 +10892,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX + out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); - s3_log("Destination=%08x, Source=%08x, Pattern=%08x, OUT=%08x, mix=%08x, count=%d.\n", dest_dat, src_dat, pat_dat, out, mix_dat, count); if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } @@ -9928,8 +10945,9 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy--; - if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) + if (cpu_input) return; + if (s3->accel.sy < 0) { s3->accel.destx_distp = s3->accel.dx; s3->accel.desty_axstp = s3->accel.dy; @@ -10293,7 +11311,7 @@ s3_init(const device_t *info) break; case S3_WINNER1000_805: bios_fn = ROM_WINNER1000_805; - chip = S3_86C801; + chip = S3_86C805I; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; case S3_86C805_ONBOARD: @@ -10636,8 +11654,8 @@ s3_init(const device_t *info) case S3_VISION968: switch (info->local) { - case S3_ELSAWIN2KPROX: case S3_DIAMOND_STEALTH64_968: + case S3_ELSAWIN2KPROX: case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; @@ -10731,7 +11749,6 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; - s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; @@ -10754,7 +11771,6 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; - s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; @@ -10776,11 +11792,12 @@ s3_init(const device_t *info) s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; + sdac_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); break; case S3_SPEA_MIRAGE_86C801: case S3_SPEA_MIRAGE_86C805: - case S3_WINNER1000_805: svga->decode_mask = (2 << 20) - 1; stepping = 0xa2; /*86C801/86C805*/ s3->id = stepping; @@ -10793,8 +11810,24 @@ s3_init(const device_t *info) s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; - if (info->local == S3_WINNER1000_805) - s3->elsa_eeprom = 1; + break; + + case S3_WINNER1000_805: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa8; /*86C801I/86C805I*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + + svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + s3->elsa_eeprom = 1; + sdac_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); break; case S3_86C805_ONBOARD: @@ -10924,6 +11957,8 @@ s3_init(const device_t *info) s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; + sdac_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); break; case S3_DIAMOND_STEALTH64_964: @@ -10991,10 +12026,10 @@ s3_init(const device_t *info) if (info->local == S3_ELSAWIN2KPROX) { s3->elsa_eeprom = 1; ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 28322000.0f); - } else if (info->local != S3_DIAMOND_STEALTH64_968) - ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 16000000.0f); - else + } else if (info->local == S3_DIAMOND_STEALTH64_968) ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 14318184.0f); + else + ibm_rgb528_ramdac_set_ref_clock(svga->ramdac, svga, 16000000.0f); break; default: svga->ramdac = device_add(&tvp3026_ramdac_device); @@ -11031,13 +12066,14 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; icd2061_set_ref_clock(svga->ramdac, 14318184.0f); - svga_recalctimings(svga); } else { svga->ramdac = device_add(&sdac_ramdac_device); s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; + sdac_set_ref_clock(svga->ramdac, 14318184.0f); } + svga_recalctimings(svga); break; case S3_PHOENIX_TRIO32: diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index daf59aea69d..e9da4b412f8 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -1063,32 +1063,49 @@ s3_virge_updatemapping(virge_t *virge) return; } - switch (svga->gdcreg[6] & 0xc) { /*Banked framebuffer*/ - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - if (xga_active && (svga->xga != NULL)) { - xga->on = 0; - mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); - } - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ + { + /* Enhanced mode forces 64kb at 0xa0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } + } else + switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + if (xga_active && (svga->xga != NULL)) { + xga->on = 0; + mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel); + } + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + + default: + break; + } virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/ + /*Linear framebuffer*/ + mem_mapping_disable(&svga->mapping); + switch (svga->crtc[0x58] & 7) { case 0: /*64k*/ virge->linear_size = 0x10000; @@ -1110,11 +1127,19 @@ s3_virge_updatemapping(virge_t *virge) break; } virge->linear_base &= ~(virge->linear_size - 1); - if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + //pclog("CR58 & 7=%x, base=%08x.\n", svga->crtc[0x58] & 7, virge->linear_base); + if ((virge->linear_base == 0xa0000) || (virge->linear_size == 0x10000)) { mem_mapping_disable(&virge->linear_mapping); - } else - mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); + if (!(svga->crtc[0x53] & 0x10)) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + } else { + if (virge->linear_base) + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); + else + mem_mapping_disable(&virge->linear_mapping); + } svga->fb_only = 1; } else { mem_mapping_disable(&virge->linear_mapping); @@ -1122,6 +1147,7 @@ s3_virge_updatemapping(virge_t *virge) } if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { /*Old MMIO*/ + mem_mapping_disable(&svga->mapping); if (svga->crtc[0x53] & 0x20) mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); else @@ -1129,9 +1155,12 @@ s3_virge_updatemapping(virge_t *virge) } else mem_mapping_disable(&virge->mmio_mapping); - if (svga->crtc[0x53] & 0x08) /*New MMIO*/ - mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); - else + if (svga->crtc[0x53] & 0x08) { /*New MMIO*/ + if (virge->linear_base) + mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); + else + mem_mapping_disable(&virge->new_mmio_mapping); + } else mem_mapping_disable(&virge->new_mmio_mapping); } @@ -3124,7 +3153,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) case 0: case CMD_SET_MS: READ(src_addr, source); - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + if ((virge->s3d.cmd_set & CMD_SET_TP) && (source == src_fg_clr)) update = 0; break; case CMD_SET_IDS: @@ -3150,7 +3179,7 @@ s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) count = 0; } } - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + if ((virge->s3d.cmd_set & CMD_SET_TP) && (source == src_fg_clr)) update = 0; break; case CMD_SET_IDS | CMD_SET_MS: @@ -4829,7 +4858,7 @@ s3_virge_colorkey(virge_t* virge, uint32_t x, uint32_t y) return true; else if (!(virge->streams.chroma_ctrl & (1 << 28))) return true; - + comp_r = (virge->streams.chroma_ctrl >> 16) & 0xFF; comp_g = (virge->streams.chroma_ctrl >> 8) & 0xFF; comp_b = (virge->streams.chroma_ctrl) & 0xFF; @@ -4853,7 +4882,7 @@ s3_virge_colorkey(virge_t* virge, uint32_t x, uint32_t y) */ uint8_t index = virge->streams.chroma_ctrl & 0xFF; alpha_key = (virge->chip < S3_VIRGEGX2) ? (virge->streams.chroma_ctrl & (1 << 29)) : ((virge->streams.chroma_ctrl >> 29) & 3) == 1; - + if (alpha_key) { comp_r = comp_g = comp_b = index; comp_r_h = comp_g_h = comp_b_h = index; @@ -5188,6 +5217,7 @@ s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) svga->crtc[0x59] = (svga->crtc[0x59] & 0x01) | (val & 0xfe); else svga->crtc[0x59] = (svga->crtc[0x59] & 0x03) | (val & 0xfc); + s3_virge_updatemapping(virge); return; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 03f829e742a..43158adbb86 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1421,6 +1421,41 @@ svga_poll(void *priv) } else { timer_advance_u64(&svga->timer, svga->dispontime); + if (svga->adv_flags & FLAG_PANNING_ATI) { + if (svga->panning_blank) { + svga->scrollcache = 0; + svga->half_pixel = 0; + + svga->x_add = svga->left_overscan; + } else { + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) + svga->scrollcache &= 0x07; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + svga->half_pixel = 0; + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; + svga->scrollcache &= 0x07; + } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; + svga->half_pixel = svga->scrollcache & 0x01; + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } + + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; + + svga->x_add = svga->left_overscan - svga->scrollcache; + } + } + if (svga->dispon) svga->cgastat &= ~1; svga->hdisp_on = 0; @@ -1477,9 +1512,13 @@ svga_poll(void *priv) svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { - svga->scrollcache = 0; - svga->half_pixel = 0; - svga->x_add = svga->left_overscan; + if (svga->adv_flags & FLAG_PANNING_ATI) + svga->panning_blank = 1; + else { + svga->scrollcache = 0; + svga->half_pixel = 0; + svga->x_add = svga->left_overscan; + } } } } @@ -1570,31 +1609,38 @@ svga_poll(void *priv) svga->dispon = 1; svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - svga->scrollcache = (svga->attrregs[0x13] & 0x0f); - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 1) - svga->scrollcache &= 0x07; - else { - svga->scrollcache++; - if (svga->scrollcache > 8) - svga->scrollcache = 0; - } + if ((svga->adv_flags & FLAG_PANNING_ATI) && svga->panning_blank) { + svga->scrollcache = 0; svga->half_pixel = 0; - } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { - svga->half_pixel = 0; - svga->scrollcache &= 0x07; + + svga->x_add = svga->left_overscan; } else { - if (svga->scrollcache > 7) - svga->scrollcache = 7; - svga->half_pixel = svga->scrollcache & 0x01; - svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - } + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) + svga->scrollcache &= 0x07; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + svga->half_pixel = 0; + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; + svga->scrollcache &= 0x07; + } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; + svga->half_pixel = svga->scrollcache & 0x01; + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } - if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) - svga->scrollcache <<= 1; + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; - svga->x_add = svga->left_overscan - svga->scrollcache; + svga->x_add = svga->left_overscan - svga->scrollcache; + } svga->linecountff = 0; @@ -1626,19 +1672,10 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*hwcursor_draw)(struct svga_t *svga, int displine), void (*overlay_draw)(struct svga_t *svga, int displine)) { - int e; - svga->priv = priv; svga->monitor_index = monitor_index_global; svga->monitor = &monitors[svga->monitor_index]; - for (int c = 0; c < 256; c++) { - e = c; - for (int d = 0; d < 8; d++) { - svga_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } svga->readmode = 0; svga->attrregs[0x11] = 0; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 35f42c2ee79..cb7e794e879 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -134,8 +134,8 @@ video_cards[] = { { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_winner1000_805_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32i_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32_machspeed_vga_gui_2400s_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32i_axis_microdevice_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, /* MCA */ { .device = &mach32_mca_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &gd5426_mca_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -145,12 +145,13 @@ video_cards[] = { /* VLB */ { .device = &mach32_vlb_device, .flags = VIDEO_FLAG_TYPE_8514 }, { .device = &mach64gx_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32i_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32_machspeed_vga_gui_2400s_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32i_hercules_dynamite_pro_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_videomagic_revb_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_cardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_noncardex_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_revc_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_generic_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_diamond_revd_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5424_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5426_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5428_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -196,11 +197,10 @@ video_cards[] = { { .device = &gd5446_pci_device, .flags = VIDEO_FLAG_TYPE_SECONDARY }, { .device = &gd5446_stb_pci_device, .flags = VIDEO_FLAG_TYPE_SECONDARY }, { .device = &gd5480_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_videomagic_revb_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_revc_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_revc_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_generic_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_cardex_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &et4000w32p_diamond_revd_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -327,8 +327,10 @@ video_prepare(void) for (int i = 0; i < MONITORS_NUM; i++) { /* Reset the CGA palette. */ +#if 0 if (monitors[i].mon_cga_palette) *monitors[i].mon_cga_palette = 0; +#endif cgapal_rebuild_monitor(i); /* Do an inform on the default values, so that that there's some sane values initialized diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c index bca6d6efa24..0130fb7be5d 100644 --- a/src/video/vid_tandy.c +++ b/src/video/vid_tandy.c @@ -16,6 +16,7 @@ * Copyright 2016-2019 Miran Grca. * Copyright 2025 starfrost */ +#include #include #include #include @@ -162,6 +163,48 @@ vid_update_latch(t1kvid_t *vid) vid->crtc[0x11] = lp_latch & 0xff; } +static void +baseline_calib_start(t1kvid_t *vid) +{ + vid->baseline_ready = false; + vid->hsync_offset = 0; + vid->vsync_offset = 0; + timer_on_auto(&vid->calib_timer, 100000.0); +} + +static void +baseline_calib_finish(void *priv) +{ + tandy_t *dev = (tandy_t *) priv; + t1kvid_t *vid = dev->vid; + + vid->baseline_hsyncpos = vid->crtc[2]; + vid->baseline_vsyncpos = vid->crtc[7]; + vid->baseline_ready = true; +} + +static void +vid_update_display_offset(t1kvid_t *vid, uint8_t reg) +{ + int hsync_scale = (vid->mode & 1) ? 8 : 16; + int vsync_scale = vid->crtc[9] + 1; + + if (!vid->baseline_ready) { + vid->hsync_offset = 0; + vid->vsync_offset = 0; + return; + } else { + switch (reg) { + case 2: + vid->hsync_offset = ((int)vid->baseline_hsyncpos - (int)vid->crtc[2]) * hsync_scale; + break; + case 7: + vid->vsync_offset_pending = ((int)vid->baseline_vsyncpos - (int)vid->crtc[7]) * vsync_scale; + break; + } + } +} + void tandy_vid_out(uint16_t addr, uint8_t val, void *priv) { @@ -188,12 +231,16 @@ tandy_vid_out(uint16_t addr, uint8_t val, void *priv) vid->fullchange = changeframecount; recalc_timings(dev); } + if (vid->crtcreg == 0x02 || vid->crtcreg == 0x07) + vid_update_display_offset(vid, vid->crtcreg); } break; case 0x03d8: old = vid->mode; vid->mode = val; + if (old != val) + baseline_calib_start(vid); if ((old ^ val) & 0x01) recalc_timings(dev); if (!dev->is_sl2) @@ -337,7 +384,7 @@ vid_read(uint32_t addr, void *priv) } static void -vid_render(tandy_t *dev, int line) +vid_render(tandy_t *dev, int line, int hos_offs) { t1kvid_t *vid = dev->vid; uint16_t cursoraddr = (vid->crtc[15] | (vid->crtc[14] << 8)) & 0x3fff; @@ -349,53 +396,91 @@ vid_render(tandy_t *dev, int line) uint16_t dat; int col; int cols[4]; + uint32_t border_val; + int out_x; + int c_start; cols[0] = (vid->array[2] & 0xf) + 16; - for (c = 0; c < 8; c++) { - if (vid->array[3] & 4) { - buffer32->line[line][c] = cols[0]; - if (vid->mode & 1) - buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = cols[0]; - else - buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = cols[0]; - } else if ((vid->mode & 0x12) == 0x12) { - buffer32->line[line][c] = 0; - if (vid->mode & 1) - buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = 0; - else - buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = 0; + if (line < 0) { + if (dev->is_sl2 && (vid->array[5] & 1)) { + vid->memaddr += vid->crtc[1] * 2; } else { - buffer32->line[line][c] = buffer32->line[(line) + 1][c] = (vid->col & 15) + 16; - if (vid->mode & 1) - buffer32->line[line][c + (vid->crtc[1] << 3) + 8] = (vid->col & 15) + 16; - else - buffer32->line[line][c + (vid->crtc[1] << 4) + 8] = (vid->col & 15) + 16; + vid->memaddr += vid->crtc[1]; + } + return; + } + + if (vid->array[3] & 4) { + border_val = cols[0]; + } else if ((vid->mode & 0x12) == 0x12) { + border_val = 0; + } else { + border_val = (vid->col & 15) + 16; + } + + if (vid->array[3] & 4) { + for (c = 0; c < hos_offs; c++) { + buffer32->line[line][c] = border_val; + } + } else if ((vid->mode & 0x12) == 0x12) { + for (c = 0; c < hos_offs; c++) { + buffer32->line[line][c] = border_val; } + } else { + for (c = 0; c < hos_offs; c++) { + buffer32->line[line][c] = buffer32->line[(line) + 1][c] = border_val; + } + } + + if (vid->mode & 1) { + out_x = (vid->crtc[1] << 3) + hos_offs; + } else { + out_x = (vid->crtc[1] << 4) + hos_offs; + } + c_start = out_x < 0 ? -out_x : 0; + for (c = c_start; c < 8 - vid->hsync_offset; c++) { + buffer32->line[line][out_x + c] = border_val; } if (dev->is_sl2 && (vid->array[5] & 1)) { /*640x200x16*/ for (x = 0; x < vid->crtc[1] * 2; x++) { dat = (vid->vram[(vid->memaddr << 1) & 0xffff] << 8) | vid->vram[((vid->memaddr << 1) + 1) & 0xffff]; vid->memaddr++; - buffer32->line[line][(x << 2) + 8] = vid->array[((dat >> 12) & 0xf) + 16] + 16; - buffer32->line[line][(x << 2) + 9] = vid->array[((dat >> 8) & 0xf) + 16] + 16; - buffer32->line[line][(x << 2) + 10] = vid->array[((dat >> 4) & 0xf) + 16] + 16; - buffer32->line[line][(x << 2) + 11] = vid->array[(dat & 0xf) + 16] + 16; + out_x = (x << 2) + hos_offs; + if (out_x >= 0) { + buffer32->line[line][out_x] = vid->array[((dat >> 12) & 0xf) + 16] + 16; + buffer32->line[line][out_x + 1] = vid->array[((dat >> 8) & 0xf) + 16] + 16; + buffer32->line[line][out_x + 2] = vid->array[((dat >> 4) & 0xf) + 16] + 16; + buffer32->line[line][out_x + 3] = vid->array[(dat & 0xf) + 16] + 16; + } else if (out_x > -4) { + for (c = -out_x; c < 4; c++) { + buffer32->line[line][out_x + c] = + vid->array[((dat >> (12 - c * 4)) & 0xf) + 16] + 16; + } + } } } else if ((vid->array[3] & 0x10) && (vid->mode & 1)) { /*320x200x16*/ for (x = 0; x < vid->crtc[1]; x++) { dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; vid->memaddr++; - buffer32->line[line][(x << 3) + 8] = buffer32->line[line][(x << 3) + 9] = - vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 3) + 10] = buffer32->line[line][(x << 3) + 11] = - vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 3) + 12] = buffer32->line[line][(x << 3) + 13] = - vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 3) + 14] = buffer32->line[line][(x << 3) + 15] = - vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + out_x = (x << 3) + hos_offs; + if (out_x >= 0) { + buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] = + vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] = + vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] = + vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] = + vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + } else if (out_x > -8) { + for (c = -out_x; c < 8; c++) { + buffer32->line[line][out_x + c] = + vid->array[((dat >> (12 - (c >> 1) * 4)) & vid->array[1] & 0x0f) + 16] + 16; + } + } } } else if (vid->array[3] & 0x10) { /*160x200x16*/ for (x = 0; x < vid->crtc[1]; x++) { @@ -406,30 +491,43 @@ vid_render(tandy_t *dev, int line) dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; vid->memaddr++; - buffer32->line[line][(x << 4) + 8] = buffer32->line[line][(x << 4) + 9] = - buffer32->line[line][(x << 4) + 10] = buffer32->line[line][(x << 4) + 11] = - vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 4) + 12] = buffer32->line[line][(x << 4) + 13] = - buffer32->line[line][(x << 4) + 14] = buffer32->line[line][(x << 4) + 15] = - vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 4) + 16] = buffer32->line[line][(x << 4) + 17] = - buffer32->line[line][(x << 4) + 18] = buffer32->line[line][(x << 4) + 19] = - vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; - buffer32->line[line][(x << 4) + 20] = buffer32->line[line][(x << 4) + 21] = - buffer32->line[line][(x << 4) + 22] = buffer32->line[line][(x << 4) + 23] = - vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + out_x = (x << 4) + hos_offs; + if (out_x >= 0) { + buffer32->line[line][out_x] = buffer32->line[line][out_x + 1] = + buffer32->line[line][out_x + 2] = buffer32->line[line][out_x + 3] = + vid->array[((dat >> 12) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 4] = buffer32->line[line][out_x + 5] = + buffer32->line[line][out_x + 6] = buffer32->line[line][out_x + 7] = + vid->array[((dat >> 8) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 8] = buffer32->line[line][out_x + 9] = + buffer32->line[line][out_x + 10] = buffer32->line[line][out_x + 11] = + vid->array[((dat >> 4) & vid->array[1] & 0x0f) + 16] + 16; + buffer32->line[line][out_x + 12] = buffer32->line[line][out_x + 13] = + buffer32->line[line][out_x + 14] = buffer32->line[line][out_x + 15] = + vid->array[(dat & vid->array[1] & 0x0f) + 16] + 16; + } else if (out_x > -16) { + for (c = -out_x; c < 16; c++) { + buffer32->line[line][out_x + c] = + vid->array[((dat >> (12 - (c >> 2) * 4)) & vid->array[1] & 0x0f) + 16] + 16; + } + } } } else if (vid->array[3] & 0x08) { /*640x200x4 - this implementation is a complete guess!*/ for (x = 0; x < vid->crtc[1]; x++) { dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 3) * 0x2000) + 1]; vid->memaddr++; - for (c = 0; c < 8; c++) { - chr = (dat >> 6) & 2; - chr |= ((dat >> 15) & 1); - buffer32->line[line][(x << 3) + 8 + c] = - vid->array[(chr & vid->array[1]) + 16] + 16; - dat <<= 1; + out_x = (x << 3) + hos_offs; + if (out_x > -8) { + c_start = out_x < 0 ? -out_x : 0; + dat <<= c_start; + for (c = c_start; c < 8; c++) { + chr = (dat >> 6) & 2; + chr |= ((dat >> 15) & 1); + buffer32->line[line][out_x + c] = + vid->array[(chr & vid->array[1]) + 16] + 16; + dat <<= 1; + } } } } else if (vid->mode & 1) { @@ -446,17 +544,22 @@ vid_render(tandy_t *dev, int line) cols[1] = vid->array[((attr & 15) & vid->array[1]) + 16] + 16; cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; } - if (vid->scanline & 8) for (c = 0; c < 8; c++) - buffer32->line[line][(x << 3) + c + 8] = - ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; - else for (c = 0; c < 8; c++) { - if (vid->scanline == 8) - buffer32->line[line][(x << 3) + c + 8] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; - else - buffer32->line[line][(x << 3) + c + 8] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + out_x = (x << 3) + hos_offs; + if (out_x > -8) { + c_start = out_x < 0 ? -out_x : 0; + if (vid->scanline & 8) for (c = c_start; c < 8; c++) { + buffer32->line[line][out_x + c] = + ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; + } else for (c = c_start; c < 8; c++) { + if (vid->scanline == 8) + buffer32->line[line][out_x + c] = cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; + else + buffer32->line[line][out_x + c] = cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + if (drawcursor) for (c = c_start; c < 8; c++) { + buffer32->line[line][out_x + c] ^= 15; + } } - if (drawcursor) for (c = 0; c < 8; c++) - buffer32->line[line][(x << 3) + c + 8] ^= 15; vid->memaddr++; } } else if (!(vid->mode & 2)) { @@ -474,22 +577,31 @@ vid_render(tandy_t *dev, int line) cols[0] = vid->array[((attr >> 4) & vid->array[1]) + 16] + 16; } vid->memaddr++; - if (vid->scanline & 8) for (c = 0; c < 8; c++) - buffer32->line[line][(x << 4) + (c << 1) + 8] = - buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] = - ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; - else for (c = 0; c < 8; c++) { - if (vid->scanline == 8) - buffer32->line[line][(x << 4) + (c << 1) + 8] = - buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; - else - buffer32->line[line][(x << 4) + (c << 1) + 8] = - buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + out_x = (x << 4) + hos_offs; + if (out_x > -16) { + c_start = out_x < 0 ? -out_x >> 1 : 0; + if (vid->scanline & 8) for (c = c_start; c < 8; c++) { + buffer32->line[line][out_x + (c << 1)] = + buffer32->line[line][out_x + 1 + (c << 1)] = + ((chr >= 0xb3) && (chr <= 0xdf)) ? cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0] : cols[0]; + } else for (c = c_start; c < 8; c++) { + if (vid->scanline == 8) { + buffer32->line[line][out_x + (c << 1)] = + buffer32->line[line][out_x + 1 + (c << 1)] = + cols[(fontdat[chr][7] & (1 << (c ^ 7))) ? 1 : 0]; + } else { + buffer32->line[line][out_x + (c << 1)] = + buffer32->line[line][out_x + 1 + (c << 1)] = + cols[(fontdat[chr][vid->scanline & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + if (drawcursor) { + c_start = out_x < 0 ? -out_x : 0; + for (c = c_start; c < 16; c++) { + buffer32->line[line][out_x + c] ^= 15; + } + } } - if (drawcursor) for (c = 0; c < 16; c++) - buffer32->line[line][(x << 4) + c + 8] ^= 15; } } else if (!(vid->mode & 16)) { cols[0] = (vid->col & 15); @@ -515,10 +627,15 @@ vid_render(tandy_t *dev, int line) dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; vid->memaddr++; - for (c = 0; c < 8; c++) { - buffer32->line[line][(x << 4) + (c << 1) + 8] = - buffer32->line[line][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; + out_x = (x << 4) + hos_offs; + if (out_x > -16) { + c_start = out_x < 0 ? -out_x >> 1 : 0; + dat <<= (c_start > 0 ? c_start << 1 : 0); + for (c = c_start; c < 8; c++) { + buffer32->line[line][out_x + (c << 1)] = + buffer32->line[line][out_x + 1 + (c << 1)] = cols[dat >> 14]; + dat <<= 2; + } } } } else { @@ -528,9 +645,14 @@ vid_render(tandy_t *dev, int line) dat = (vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000)] << 8) | vid->vram[((vid->memaddr << 1) & 0x1fff) + ((vid->scanline & 1) * 0x2000) + 1]; vid->memaddr++; - for (c = 0; c < 16; c++) { - buffer32->line[line][(x << 4) + c + 8] = buffer32->line[(line) + 1][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; + out_x = (x << 4) + hos_offs; + if (out_x > -16) { + c_start = out_x < 0 ? -out_x : 0; + dat <<= (c_start > 0 ? c_start : 0); + for (c = c_start; c < 16; c++) { + buffer32->line[line][out_x + c] = buffer32->line[(line) + 1][out_x + c] = cols[dat >> 15]; + dat <<= 1; + } } } } @@ -541,6 +663,9 @@ vid_render_blank(tandy_t *dev, int line) { t1kvid_t *vid = dev->vid; + if (line < 0) + return; + if (vid->array[3] & 4) { if (vid->mode & 1) hline(buffer32, 0, line, (vid->crtc[1] << 3) + 16, (vid->array[2] & 0xf) + 16); @@ -562,6 +687,9 @@ vid_render_process(tandy_t *dev, int line) t1kvid_t *vid = dev->vid; int x; + if (line < 0) + return; + if (vid->mode & 1) x = (vid->crtc[1] << 3) + 16; else @@ -584,6 +712,9 @@ vid_poll(void *priv) int oldvc; int scanline_old; int old_ma; + int hos_offs = 8 + vid->hsync_offset; + int displine_offs = vid->displine + vid->vsync_offset; + int displine_offs_double = (vid->displine << 1) + (vid->vsync_offset << 1); if (!vid->linepos) { timer_advance_u64(&vid->timer, vid->dispofftime); @@ -600,39 +731,39 @@ vid_poll(void *priv) vid->lastline = vid->displine; switch (vid->double_type) { default: - vid_render(dev, vid->displine << 1); - vid_render_blank(dev, (vid->displine << 1) + 1); + vid_render(dev, displine_offs_double, hos_offs); + vid_render_blank(dev, displine_offs_double + 1); break; case DOUBLE_NONE: - vid_render(dev, vid->displine); + vid_render(dev, displine_offs, hos_offs); break; case DOUBLE_SIMPLE: old_ma = vid->memaddr; - vid_render(dev, vid->displine << 1); + vid_render(dev, displine_offs_double, hos_offs); vid->memaddr = old_ma; - vid_render(dev, (vid->displine << 1) + 1); + vid_render(dev, displine_offs_double + 1, hos_offs); break; } } else switch (vid->double_type) { default: - vid_render_blank(dev, vid->displine << 1); + vid_render_blank(dev, displine_offs_double); break; case DOUBLE_NONE: - vid_render_blank(dev, vid->displine); + vid_render_blank(dev, displine_offs); break; case DOUBLE_SIMPLE: - vid_render_blank(dev, vid->displine << 1); - vid_render_blank(dev, (vid->displine << 1) + 1); + vid_render_blank(dev, displine_offs_double); + vid_render_blank(dev, displine_offs_double + 1); break; } switch (vid->double_type) { default: - vid_render_process(dev, vid->displine << 1); - vid_render_process(dev, (vid->displine << 1) + 1); + vid_render_process(dev, displine_offs_double); + vid_render_process(dev, displine_offs_double + 1); break; case DOUBLE_NONE: - vid_render_process(dev, vid->displine); + vid_render_process(dev, displine_offs); break; } @@ -696,6 +827,7 @@ vid_poll(void *priv) vid->cursoron = vid->blink & 16; } if (vid->vc == vid->crtc[7]) { + vid->vsync_offset = vid->vsync_offset_pending; vid->dispon = 0; vid->displine = 0; vid->vsynctime = 16; @@ -784,6 +916,8 @@ tandy_vid_close(void *priv) { tandy_t *dev = (tandy_t *) priv; + timer_on_auto(&dev->vid->calib_timer, 0.0); + free(dev->vid); dev->vid = NULL; } @@ -795,6 +929,12 @@ tandy_vid_init(tandy_t *dev) t1kvid_t *vid; vid = calloc(1, sizeof(t1kvid_t)); + vid->baseline_hsyncpos = 0; + vid->baseline_vsyncpos = 0; + vid->baseline_ready = false; + vid->hsync_offset = 0; + vid->vsync_offset = 0; + vid->vsync_offset_pending = 0; vid->memctrl = -1; video_inform(VIDEO_FLAG_TYPE_CGA, &timing_dram); @@ -814,6 +954,7 @@ tandy_vid_init(tandy_t *dev) vid->b8000_mask = 0x3fff; timer_add(&vid->timer, vid_poll, dev, 1); + timer_add(&vid->calib_timer, baseline_calib_finish, dev, 0); mem_mapping_add(&vid->mapping, 0xb8000, 0x08000, vid_read, NULL, NULL, vid_write, NULL, NULL, NULL, 0, dev); io_sethandler(0x03d0, 16, diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 2fd4ba482cb..30f76abfa77 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -692,6 +692,7 @@ tgui_recalctimings(svga_t *svga) const tgui_t *tgui = (tgui_t *) svga->priv; uint8_t ger22lower = (tgui->accel.ger22 & 0xff); uint8_t ger22upper = (tgui->accel.ger22 >> 8); + int std_vga_clock = 1; if (tgui->type >= TGUI_9440) { if ((svga->crtc[0x38] & 0x19) == 0x09) @@ -767,10 +768,11 @@ tgui_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); if (svga->gdcreg[0xf] & 0x08) - svga->clock *= 2; + svga->clock *= 2.0; else if (svga->gdcreg[0xf] & 0x40) - svga->clock *= 3; + svga->clock *= 3.0; } else { + //pclog("TGUI9400CXi: Clock double=%d.\n", (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8))); switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { case 0x02: svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; @@ -816,6 +818,7 @@ tgui_recalctimings(svga_t *svga) break; default: + std_vga_clock = 0; break; } @@ -823,6 +826,9 @@ tgui_recalctimings(svga_t *svga) svga->htotal <<= 1; svga->hdisp <<= 1; svga->hdisp_time <<= 1; + svga->dots_per_clock <<= 1; + if (std_vga_clock) + svga->clock /= 2.0; } } @@ -843,6 +849,7 @@ tgui_recalctimings(svga_t *svga) svga->htotal <<= 1; svga->hdisp <<= 1; svga->hdisp_time <<= 1; + svga->dots_per_clock <<= 1; break; default: break; @@ -866,6 +873,7 @@ tgui_recalctimings(svga_t *svga) svga->htotal <<= 1; svga->hdisp <<= 1; svga->hdisp_time <<= 1; + svga->dots_per_clock <<= 1; } switch (svga->hdisp) { case 640: @@ -880,18 +888,24 @@ tgui_recalctimings(svga_t *svga) break; case 15: svga->render = svga_render_15bpp_highres; - if (tgui->type < TGUI_9440) + if (tgui->type < TGUI_9440) { svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } break; case 16: svga->render = svga_render_16bpp_highres; - if (tgui->type < TGUI_9440) + if (tgui->type < TGUI_9440) { svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } break; case 24: svga->render = svga_render_24bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp = (svga->hdisp << 1) / 3; + if (tgui->type < TGUI_9440) { + svga->hdisp /= 3; + svga->dots_per_clock /= 3; + } break; case 32: if (svga->rowoffset == 0x100) diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index fe02b7811a3..b070e7aba63 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -168,10 +168,8 @@ voodoo_readw(uint32_t addr, void *priv) } voodoo->flush = 1; - while (!FIFO_EMPTY) { + while (!FIFO_EMPTY) voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } voodoo_wait_for_render_thread_idle(voodoo); voodoo->flush = 0; @@ -427,18 +425,27 @@ voodoo_writel(uint32_t addr, uint32_t val, void *priv) voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { #if 0 - voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); + voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask, val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); #endif *(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; - if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) - voodoo_wake_fifo_thread(voodoo); + + /* Voodoo1: use higher CMDFIFO threshold to reduce wake frequency */ + if (voodoo->type == VOODOO_1) { + if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) > 300) + voodoo_wake_fifo_thread(voodoo); + } + /* Other cards (Voodoo2, Banshee, Voodoo3, ...) keep the original behavior */ + else { + if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) + voodoo_wake_fifo_thread(voodoo); + } } else switch (addr & 0x3fc) { case SST_intrCtrl: fatal("intrCtrl write %08x\n", val); break; - + case SST_userIntrCMD: fatal("userIntrCMD write %08x\n", val); break; diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 612ca4c18b9..4530e6b01e6 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -60,7 +60,10 @@ voodoo_fifo_log(const char *fmt, ...) # define voodoo_fifo_log(fmt, ...) #endif -#define WAKE_DELAY (TIMER_USEC * 100) +#define WAKE_DELAY_DEFAULT (TIMER_USEC * 100) + +/* Per-card wake delay: Voodoo1 uses a larger delay to reduce FIFO wake frequency */ +#define WAKE_DELAY_OF(v) ((v)->type == VOODOO_1 ? (TIMER_USEC * 2000) : WAKE_DELAY_DEFAULT) void voodoo_wake_fifo_thread(voodoo_t *voodoo) { @@ -69,7 +72,7 @@ voodoo_wake_fifo_thread(voodoo_t *voodoo) process one word and go back to sleep, requiring it to be woken on almost every write. Instead, wait a short while so that the CPU emulation writes more data so we have more batched-up work.*/ - timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); + timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY_OF(voodoo)); } } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 0a982200659..bec538c6274 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2716,15 +2716,15 @@ xga_hwcursor_draw(svga_t *svga, int displine) if (x >= idx) { switch (comb) { case 0x00: - /* Cursor Color 1 */ + /* Cursor Color 1 */ p[x_pos] = xga->hwc_color0; break; case 0x01: - /* Cursor Color 2 */ + /* Cursor Color 2 */ p[x_pos] = xga->hwc_color1; break; case 0x03: - /* Complement */ + /* Complement */ p[x_pos] ^= 0xffffff; break; @@ -2793,24 +2793,24 @@ xga_render_4bpp(svga_t *svga) for (int x = 0; x <= xga->h_disp; x += 16) { dat = *(uint32_t *) (&xga->vram[xga->memaddr & xga->vram_mask]); - p[1] = xga->pallook[dat & 0x0f]; - p[0] = xga->pallook[(dat >> 4) & 0x0f]; - p[3] = xga->pallook[(dat >> 8) & 0x0f]; - p[2] = xga->pallook[(dat >> 12) & 0x0f]; - p[5] = xga->pallook[(dat >> 16) & 0x0f]; - p[4] = xga->pallook[(dat >> 20) & 0x0f]; - p[7] = xga->pallook[(dat >> 24) & 0x0f]; - p[6] = xga->pallook[(dat >> 28) & 0x0f]; + p[0] = xga->pallook[dat & 0x0f]; + p[1] = xga->pallook[(dat >> 4) & 0x0f]; + p[2] = xga->pallook[(dat >> 8) & 0x0f]; + p[3] = xga->pallook[(dat >> 12) & 0x0f]; + p[4] = xga->pallook[(dat >> 16) & 0x0f]; + p[5] = xga->pallook[(dat >> 20) & 0x0f]; + p[6] = xga->pallook[(dat >> 24) & 0x0f]; + p[7] = xga->pallook[(dat >> 28) & 0x0f]; dat = *(uint32_t *) (&xga->vram[(xga->memaddr + 4) & xga->vram_mask]); - p[9] = xga->pallook[dat & 0x0f]; - p[8] = xga->pallook[(dat >> 4) & 0x0f]; - p[11] = xga->pallook[(dat >> 8) & 0x0f]; - p[10] = xga->pallook[(dat >> 12) & 0x0f]; - p[13] = xga->pallook[(dat >> 16) & 0x0f]; - p[12] = xga->pallook[(dat >> 20) & 0x0f]; - p[15] = xga->pallook[(dat >> 24) & 0x0f]; - p[14] = xga->pallook[(dat >> 28) & 0x0f]; + p[8] = xga->pallook[dat & 0x0f]; + p[9] = xga->pallook[(dat >> 4) & 0x0f]; + p[10] = xga->pallook[(dat >> 8) & 0x0f]; + p[11] = xga->pallook[(dat >> 12) & 0x0f]; + p[12] = xga->pallook[(dat >> 16) & 0x0f]; + p[13] = xga->pallook[(dat >> 20) & 0x0f]; + p[14] = xga->pallook[(dat >> 24) & 0x0f]; + p[15] = xga->pallook[(dat >> 28) & 0x0f]; xga->memaddr += 8; p += 16; diff --git a/src/video/video.c b/src/video/video.c index a999748b702..81fe3a26b92 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -612,7 +612,7 @@ cgapal_rebuild_monitor(int monitor_index) palette_lookup[0x15] = 0xffc400c4; palette_lookup[0x16] = 0xffc47e00; palette_lookup[0x17] = 0xffc4c4c4; - palette_lookup[0x18] = 0x0ffe4e4e; + palette_lookup[0x18] = 0xff4e4e4e; palette_lookup[0x19] = 0xff4e4edc; palette_lookup[0x1a] = 0xff4edc4e; palette_lookup[0x1b] = 0xff4ef3f3; diff --git a/vcpkg.json b/vcpkg.json index 73f6d08f824..6a4f6376cb8 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "5.2", + "version-string": "6.0", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later",