Compare commits

...

77 Commits

Author SHA1 Message Date
Rafael Kitover 6139428207
translations: remove dup Chinese translations
Remove zh.po, which is not on Transifex anymore and zh-Hans.po, which I
have removed from Transifex just now, leaving zh-CN.po, as suggested by
@wuweiran.

Fix #1435.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-04-02 13:45:14 +00:00
Rafael Kitover 5a5579d27f
build: minor followup on SFML 3.x API change
Followup on 29e85e5d (build: update Link SFML usage to SFML 3.x APIs,
2025-04-01) to alias an optional.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-04-02 09:07:54 +00:00
Rafael Kitover 29e85e5d87 build: update Link SFML usage to SFML 3.x APIs
Make some changes for the SFML Network library for the 3.x APIs.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-04-01 23:34:58 +00:00
Fabrice de Gans e228394656 [Input] Process key down event for some controls
In #1424, the app event handler was disabling all key down events,
preventing controls that depend on them to properly handle these. This
was done to work around an issue on macOS where unhandled keyboard
events would fire an audio alert.
Since this breaks text controls, these changes check for the currently
focused window and let the event propagate for text controls.

Fixes #1434
2025-04-01 18:57:26 +02:00
Rafael Kitover d5ac2a853b
Revert "Update Link SFML usage to SFML 3.x APIs"
This reverts commit e82ae7bb13.

Sorry, somehow I pushed to the wrong branch.
2025-03-29 19:40:59 +00:00
Rafael Kitover e82ae7bb13
Update Link SFML usage to SFML 3.x APIs
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-29 18:54:53 +00:00
Rafael Kitover 20b82d8ab7
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-29 04:00:24 +00:00
Rafael Kitover 8d26b4f49f
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-25 23:00:22 +00:00
Fabrice de Gans 3fdc30f7d7
Mark `wxEVT_KEY_DOWN` as processed in `wxvbamApp` (#1424)
This prevents wxWidgets from triggering the alert sound on macOS.
There should be no side effect from this.

Fixes #1384
2025-03-22 16:24:14 -07:00
Rafael Kitover 57211ddc77
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-20 19:00:21 +00:00
Squall Leonhart 2de7efd9eb
Reallocate GBA ROM to the the new size(#1422)
The GBA ROM was erroneously reallocated to the constant `ROM_SIZE`.

Closes #1421
2025-03-15 13:39:57 -07:00
Rafael Kitover 5b4559f4ee
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-07 13:00:21 +00:00
Rafael Kitover 6178526cd9
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-03-06 09:00:20 +00:00
Rafael Kitover c8a1d8eb2e
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-28 23:00:26 +00:00
Rafael Kitover 6e3883937b
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-28 22:00:21 +00:00
Rafael Kitover 8dd647914a
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-20 17:00:21 +00:00
Rafael Kitover 0dae126a29
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-20 16:00:22 +00:00
Rafael Kitover 5038cd7ba5
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-16 23:00:22 +00:00
Rafael Kitover ddd8fca044
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-11 19:00:21 +00:00
Rafael Kitover 25c85a83d9
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-11 18:00:21 +00:00
Fabrice de Gans 32dd410954
[build] Disable link (#1411)
SFML 2 no longer compiles with a modern compiler and we are blocked on
SFML 3 being available in vcpkg to fix it. There is no easy way to
backport fixes to SFML 2 so disable link for the time being.
2025-02-08 15:13:10 -08:00
Fabrice de Gans e4f17d33ce
[Sound] Set volume on game startup (#1410)
On startup, the internal emulator sound volume is set to 100%. The user
value in the wx frontend is not used until the emulator volume slider is
modified, resulting in games starting with volume at 100% on startup.

This fixes #1407 by always setting the internal emulator sound volume on
game startup.
2025-02-08 12:57:12 -08:00
Rafael Kitover 2ab707c0ca
build: update default.nix
Update default.nix to remove gcc from the macOS package set and add
clang/llvm/libcxx to the Linux package set.

Change 'epoxy' in the Linux package set to the new package name
'libepoxy'.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-02-02 09:42:05 +00:00
Rafael Kitover 4dba928765
build: update installdeps for OpenSUSE
Update `installdeps` for current OpenSUSE wxWidgets and FFmpeg packages.

Disable 32 bit cross builds in OpenSUSE because those packages are no
longer available.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-29 20:21:32 +00:00
Rafael Kitover 3d6550d161
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-25 18:00:22 +00:00
Rafael Kitover 3cf12f2594
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-15 15:00:25 +00:00
Rafael Kitover de1ec01c78
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-13 18:00:26 +00:00
Rafael Kitover 295abb9cd0
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-13 15:00:26 +00:00
Rafael Kitover 8260b62482
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-13 13:00:22 +00:00
Rafael Kitover d18c6f115f
Use faster sqrt() for xBRZ for XP builds
Use the `sqrt()` introduced in 615e5863 (Add fast-inverse SSE1 sqrt()
from Quake 3 Arena, 2025-01-12) or the xBRZ filters for Windows XP 32
bit builds.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-12 15:50:29 +00:00
Squall Leonhart d36f80b5e6
Add fast-inverse SSE1 sqrt() from Quake 3 Arena
Add the Quake 3 Arena fast-inverse `sqrt()` using SSE1 intrinsics to
third_party.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-12 15:50:02 +00:00
Rafael Kitover 44aa859e6d
build: add cmake var and cpp macro for XP builds
Add the WINXP CMake variable and WINXP CPP macro for MinGW 32 bit
Windows XP builds.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-12 15:04:14 +00:00
Rafael Kitover 5a2d3a6f95
build: set arch to pentium3 not -mmx for XP builds
Set the gcc architecture to pentium3 not pentium-mmx for Windows XP 32
bit builds.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-12 10:04:07 +00:00
PunkPangolin d6b939c428
Set developer id/component type in metainfo.xml
Add developer block to `metainfo.xml` with id 'visualboyadvance-m.org'.

Also set component type to 'desktop-application'.

This file is used to describe the application on Linux.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-09 20:07:45 +00:00
Rafael Kitover 8b8be7d4a8
Revert "Change domain to temporary"
This reverts commit 72364fd1a4.
2025-01-08 13:12:40 +00:00
Rafael Kitover 72364fd1a4
Change domain to temporary
Domain has expired, change links to temporary domain.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2025-01-08 13:09:49 +00:00
Rafael Kitover c6da07feb3
build: link avrt for OpenAL on WIN32
For static builds for Windows, link `avrt`, a system library that is now
required by OpenAL.

Also remove our version of `FindOpenAL.cmake` in favor of the
system-provided version.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-12-16 13:47:48 +00:00
Rafael Kitover 94979eff97
build: initialize GTest submodule in CMake
Try to initialize the GTest Git submodule from the CMake code if it has
not been.

If that fails, turn off `BUILD_TESTING`.

We do not want to require recursive clones or initializing submodules
for users by default.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-12-16 13:09:02 +00:00
Rafael Kitover e8494b56d1
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-12-13 05:08:59 +00:00
Fabrice de Gans c85397518b
[win32-deps] Update win32-deps (#1375) 2024-11-24 22:03:05 -08:00
Fabrice de Gans cf2339822d
[win32-deps] Use specific commit in submodule (#1374)
This will help make older builds reproducible.
2024-11-24 21:37:11 -08:00
Fabrice de Gans dcb9ccca90
[gtest] Use googletest as a submodule (#1373)
Some Linux distributions use a hermetic build environment to build. This
resulted in issues with `FetchContent` attempting to download googletest
at configure time.
This fixes the issue by integrating googletest as a git submodule
instead of downloading it at configure time.
2024-11-24 12:39:10 -08:00
Fabrice de Gans a8ec85d536
[GB] Add support for per-game overrides (#1370)
* [GB] Add support for per-game overrides

Alleyway is a buggy game that does not work properly when a Game Boy
Printer is connected. In order to work around this issue, this adds
upport for built-in per-software Game Boy overrides. In addition, this
renames various variables to make their meaning clearer.

* This only supports built-in overrides. External INI files are not
  supported.
* Only the Game Boy Printer option is supported, this only takes effect
  on game startup and the general configuration option is restored when
  the game is unloaded.
* As a result, it is possible to override the per-game override by
  manually setting the option while the game is running, this is working
  as intended.
* Future refactors of the option handling will manage overrides better.
* Switch `gbPrinterEnabled` default to off.

Fixes #1368
2024-11-24 12:15:26 -08:00
Rafael Kitover 611f3a3409
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-11-04 02:00:27 +00:00
Rafael Kitover b6da6c490c
translations: transifex pull
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-11-04 01:00:23 +00:00
Fabrice de Gans 9d20ce9b59
[Input] Reset keyboard tracking on focus loss (#1357)
When pressing Alt+Tab, the "Alt" and "Tab" keys were considered in the
"pressed" state until the user pressed them again because the window is
no longer receiving keyboard events. This resulted in some shortcuts no
longer working, since "Alt" was always in the pressed state. This
changes the keyboard tracking to be reset when the application loses
focus, fixing the issue.

This change also adds tests for the keyboard tracking.
2024-10-08 18:22:17 -07:00
Squall Leonhart 709a322337
cherry pick d5d01a8b68 2024-10-07 00:26:31 +11:00
Rafael Kitover cdfd37fc4e
build: rename dependencies submodule -> win32-deps
Rename the Git submodule `dependencies` used for some dependent files
for Win32 builds to `win32-deps` and make the necessary adjustments to
the CMake code.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-10-04 20:05:52 +00:00
Rafael Kitover 4f8d0a8867
build: update harfbuzz for macOS builder
Update harfbuzz in the macOS builder from the ancient version to the
current release and switch it to using Meson.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-10-03 13:50:16 +00:00
Fabrice de Gans b22e9fb709
Ignore illegal opcodes used by Wii U VC (#1351)
The Wii U VC emulator incorrectly allows for armv6 thumb instructions
(like LSRS). These cause an undefined instruction error on real hardware
but the Wii U VC emulator just ignores them. This change mimicks the Wii
U VC emulator behavior.
2024-09-29 23:13:11 -07:00
Rafael Kitover 4e2799b582
build: don't hardcode Windows certificate password
Use a file for the Windows code-signing certificate instead of
hardcoding it into the CMake code.

Update the developer manual with instructions on where to put the
Windows code-signing certificate and the file containing the password
for it.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-29 20:59:40 +00:00
Fabrice de Gans 7fa90531e6
Disable open menu tracking outside of Windows (#1350)
Tracking whether or not the menus are opened is necessary on Windows since menus stop
the main loop. This is not necessary on other platforms. In particular, on Mac, we do
not get a `wxEVT_MENU_CLOSE` event when opening a dialog from a shortcut, resulting in
the menu status tracking being incorrect.

Fixes #1348
2024-09-29 13:59:19 -07:00
Fabrice de Gans e1c2ecc584
[dialogs] Display all controls in AccelConfig on Mac (#1349)
Calling `ExpandAll()` on the `wxTreeCtrl` would cause it to display outside of its
intended view, hiding other controls. Instead, this sets a minimum size for the tree
control, so the default window size is reasonable.

Fixes #1348
2024-09-28 10:38:28 -07:00
Rafael Kitover 4c450ab360
build: fix linking FAudio statically on MINGW
Link `FAudio.a` explicitly on MINGW toolchains, for some reason linking
`FAudio` with static preference no longer works.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-19 09:22:38 +00:00
Fabrice de Gans d5e1a1f36b [GB] Properly set OPRI on startup
Previously, the OPRI register was always set to be in CGB mode when not
using the CGB BIOS, resulting in graphics corruption when running DMG
software in CGB mode without using the CGB BIOS. This fixes the issue by
properly setting bit 1 of the OPRI register as expected.

This was broken in #1119.
2024-09-17 18:52:35 -07:00
Rafael Kitover 821b9176bd
build: do not use debug libs for RelWithDebInfo
Stop trying to use debug libs for `CMAKE_BUILD_TYPE=RelWithDebInfo`,
this also fixes the current link error with SFML.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-17 18:35:39 +00:00
Rafael Kitover 9031103c9a
build: fix linking non-debug pcre for debug wx
Remove the cmake code that adds the pcre library because the wxWidgets
cmake code correctly includes it now, on both vcpkg and MSYS2.

Also fix up `wxWidgets_ROOT_DIR` and `wxWidgets_LIB_DIR` for debug
builds.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-15 19:53:27 +00:00
Rafael Kitover 557f897ead
build: fix using host pkgconf for ARM64 cross bld
Set `VCPKG_HOST_TRIPLET` and `VCPKG_USE_HOST_TOOLS` when using an X64
host for an ARM64 cross build in order to use the host `pkgconf` and
possibly other tools.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-15 15:47:28 +00:00
Rafael Kitover c8a4f66cf8
build: fix UpdateAppcast.cmake
Hardcode `git` instead of using `${GIT_EXECUTABLE}` which we are not
using anymore.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-15 12:50:00 +00:00
Zach Bacon ddc93ec6e1
release v2.1.11
Signed-off-by: Zach Bacon <zachbacon@vba-m.com>
2024-09-15 01:48:38 -04:00
Rafael Kitover ab38ae8f24
doc: add keychain/notarization for Mac in dev man
Add information on unlocking the keychain for codesigning and setting up
credentials for notarization to the macOS binary section in the release
process section of the developer manual.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-14 08:38:02 +00:00
Rafael Kitover d337688fa7
build: use ccache correctly in the macOS builder
Make compiler symlinks in the macOS builder instead of prepending
`ccache` to the compiler in the CC/CXX environment variables.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-14 07:53:34 +00:00
Rafael Kitover 3eea90afb6
build: set BUILD_TESTING=OFF when not git checkout
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-13 16:29:25 +00:00
Rafael Kitover b3952d74a8
build: fix ENABLE_LIRC=ON
Fix the `ENABLE_LIRC` cmake option, pass an interface specifier to
`target_compile_definitions()`.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-13 15:29:16 +00:00
Fabrice de Gans be09125d52 Use relative paths for installation
The CMake documentation [1] advises against using `CMAKE_INSTALL_FULL_*`
in `install()` commands.

[1] https://cmake.org/cmake/help/v3.30/module/GNUInstallDirs.html#result-variables
2024-09-13 01:05:38 +00:00
Rafael Kitover f264e7f807
Fix Help -> Translations URL
Fix the URL a browser is launched with when the `Help -> Translations`
menu item is selected to point to the project page on Transifex.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-12 17:35:40 +00:00
Rafael Kitover fe0791762a
build: update Windows dependencies submodule
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-12 14:17:16 +00:00
Fabrice de Gans 61f427dec1
Write shortcuts in the proper section (#1335)
Shortcuts were mistakenly written in `Keyboard/Keyboard` rather than in
the `Keyboard` section.
In addition, this properly fixes toggling checkable menu item options
via a shortcut.

Fixes #1334
2024-09-11 22:48:06 -07:00
Rafael Kitover d619ee2bb1
build: fix installing GoogleTest
Add the `EXCLUDE_FROM_ALL` keyword to the `FetchContent_Declare` call
for GoogleTest, so that gtest/gmock are not installed with the project.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 14:43:34 +00:00
Rafael Kitover 7128e6dd08
build: update wxWidgets for macOS builder to 3.2.6
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 12:40:27 +00:00
Rafael Kitover 0decffea8d
build: update macOS builder dists
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 11:42:26 +00:00
Rafael Kitover 9b60e17746
build: default to ENABLE_FFMPEG=OFF for MinGW32
Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 11:20:02 +00:00
Rafael Kitover 26207038c9
Update WinSparkle to 0.8.1 and add ARM64
Update the included WinSparkle dll to 0.8.1 and add support for using
the ARM64 WinSparkle dll as well.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 11:07:19 +00:00
Rafael Kitover 90867bc802
doc: update developer manual release steps
Update the release steps in the developer manual to mention the
requirement for a GnuPG key, emphasize the editing the changelog step
and add instructions for putting `signtool.exe` in the `PATH` for the 32
bit Windows binary.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 10:10:13 +00:00
Rafael Kitover 7f49cd33ad
build: rm FAudio from installdeps MINGW32 target
Do not try to install FAudio for the MINGW32 32 bit Windows MSYS2 target
in `installdeps`. We do not use it for the 32 bit build and there is no
package for it for MINGW32.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 09:23:27 +00:00
Rafael Kitover d8342d3d67
doc: add ENABLE_FAUDIO to CMake opts in README.md
Describe `ENABLE_FAUDIO` in the table of CMake options in `README.md`.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 08:59:26 +00:00
Rafael Kitover 12e840a8fa
Remove non-user-facing changes from CHANGELOG.md
Remove non-user-facing changes from `CHANGELOG.md` for 2.1.10.

Signed-off-by: Rafael Kitover <rkitover@gmail.com>
2024-09-09 08:52:12 +00:00
67 changed files with 1334 additions and 8639 deletions

10
.gitmodules vendored
View File

@ -1,4 +1,6 @@
[submodule "dependencies"]
path = dependencies
url = https://github.com/visualboyadvance-m/dependencies.git
branch = master
[submodule "win32-deps"]
path = win32-deps
url = https://github.com/visualboyadvance-m/win32-deps.git
[submodule "third_party/googletest"]
path = third_party/googletest
url = https://github.com/google/googletest.git

View File

@ -4,97 +4,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [2.1.11] - 2024-09-15
==========================
* 3eea90af - build: set BUILD_TESTING=OFF when not git checkout [rkitover]
* b3952d74 - build: fix ENABLE_LIRC=ON [rkitover]
* f264e7f8 - Fix Help -> Translations URL [rkitover]
* 61f427de - Write shortcuts in the proper section (#1335) [Steelskin]
* d619ee2b - build: fix installing GoogleTest [rkitover]
* 26207038 - Update WinSparkle to 0.8.1 and add ARM64 [rkitover]
## [2.1.10] - 2024-09-08
==========================
* 2b8f9f71 - Copy string options rather than referencing them [steelskin]
* e76cef79 - Remove cast for UTF-16 -> UTF-8 conversion [steelskin]
* 7f06428d - Disable dialog position save/restore on wxGTK (#1331) [Steelskin]
* e4a93404 - Update README.md and Developer Manual [rkitover]
* 5d7023a5 - translations: transifex pull [rkitover]
* 3bd7c918 - build: fix cmake -DTAG_RELEASE functionality [rkitover]
* 67e4944c - translations: transifex pull [rkitover]
* df4ff16e - translations: transifex pull [rkitover]
* d4805065 - translations: transifex pull [rkitover]
* e39b1f2c - translations: transifex pull [rkitover]
* 73b65a65 - translations: transifex pull [rkitover]
* 9e556e6a - translations: transifex pull [rkitover]
* 11e73f2c - translations: transifex pull [rkitover]
* e97b0448 - translations: transifex pull [rkitover]
* aa6ed14b - [FAudio] Always convert UTF-16 names (#1328) [Steelskin]
* 2ce20c4f - translations: transifex pull [rkitover]
* e4ef4aa6 - Propagate key events (#1323) [Steelskin]
* cf5cb40c - translations: transifex pull [rkitover]
* c450d143 - translations: transifex pull [rkitover]
* 41572be3 - translations: transifex pull [rkitover]
* 4f8da1c5 - translations: transifex pull [rkitover]
* 32091669 - translations: transifex pull [rkitover]
* abd72a5b - translations: transifex pull [rkitover]
* 7e6349b1 - translations: transifex pull [rkitover]
* 0782be74 - translations: transifex pull [rkitover]
* a7b545ab - translations: transifex pull [rkitover]
* 1a564f90 - translations: transifex pull [rkitover]
* 3d4e03f8 - translations: transifex pull [rkitover]
* fc17209a - translations: transifex pull [rkitover]
* 38877ef2 - translations: transifex pull [rkitover]
* 8691a15b - translations: transifex pull [rkitover]
* 961fd030 - translations: rebuild source .pot [rkitover]
* e2cf6ecb - Add option to mute sound during speedup [rkitover]
* 7a0826a6 - Migrate vba-m.com links in .github folder [aavindraa]
* d516683a - build: fix for wx using GTK2 [rkitover]
* 834c7de8 - build: update macOS builder dists [rkitover]
* 4f1a5dd7 - [Test] Add tests for widgets code [steelskin]
* 5766b9b9 - translations: transifex pull [rkitover]
* 5d8426d3 - translations: transifex pull [rkitover]
* 63ec3528 - translations: transifex pull [rkitover]
* f646c384 - [Test] Change assert to custom CHECK macros [steelskin]
* 09433875 - [CI] Remove workaround for MSVC CI [steelskin]
* 05c09ff5 - [Build] Add devkitpro-based libretro targets to CI [steelskin]
* 7f78fbb3 - translations: transifex pull [rkitover]
* 261e26f4 - translations: transifex pull [rkitover]
* ed820708 - translations: transifex pull [rkitover]
* 5b8b6a0b - [Test] Add tests for the EmulatedGamepad class [steelskin]
* 8809ce26 - [Test] Add tests for the Bindings class [steelskin]
* a4862585 - [Build] Share wx-related targets configuration [steelskin]
* 55c1477d - build: disable FAudio for 32 bit Windows builds [rkitover]
* 2d7a1ea2 - build: fix faudio linkage regression on MSVC+vcpkg [rkitover]
* 244149c0 - build: fix faudio static linkage [rkitover]
* c0bcf3bf - [Test] Add tests for many config classes [steelskin]
* 13756bcb - [Test] Replace doctest with googletest [steelskin]
* fc82e062 - build: do not build SDL bin on Windows or macOS [rkitover]
* df89beb2 - build: disable gpg signatures by default [rkitover]
* 82eda48e - translations: transifex pull [rkitover]
* b47787b3 - translations: rebuild source .pot [rkitover]
* c9668d9a - [config] Create the vbam-wx-config target [steelskin]
* 90a56c69 - [config] Move strutils to src/config/ [steelskin]
* d377f7ab - [CI] Install only one MSVC toolchain [steelskin]
* 1fac1297 - translations: transifex pull [rkitover]
* af7d5f7b - translations: transifex pull [rkitover]
* 28f7c201 - translations: transifex pull [rkitover]
* 486330f2 - Activate GitHub Sponsors [rkitover]
* 1ae78a04 - translations: transifex pull [rkitover]
* c776da71 - translations: rebuild source .pot [rkitover]
* d543784a - [UserInput] Filter key events globally [steelskin]
* 902c6c8e - [UserInput] Only process shortcut commands once [steelskin]
* d32be9dd - Move cmdtab and command enable flags to config/ [steelskin]
* b7765092 - [bindings] Set default shortcut for recent file 3 [steelskin]
* 56eb97c8 - translations: transifex pull [rkitover]
* 9f46c575 - translations: transifex pull [rkitover]
* e0402a9b - translations: transifex pull [rkitover]
* 3e30f54d - translations: fix strings starting with lowercase [rkitover]
* d73085a8 - translations: transifex pull [rkitover]
* 8eb6a690 - translations: transifex pull [rkitover]
* 3615137c - translations: transifex pull [rkitover]
* bbd5b76f - translations: transifex pull [rkitover]
* bb3604f3 - translations: rebuild source .pot [rkitover]
* 18a0067c - [Input] Unify command handling [steelskin]
* cfdbdc4e - [Input] Move input configuration objects to app [steelskin]
* 32ca2ae4 - translations: transifex pull [rkitover]
* bad96cf9 - translations: rebuild source .pot [rkitover]
* 62294702 - [Input] Remove transitional key, mod, joy triplet [steelskin]
* 72c4f33d - translations: transifex pull [rkitover]
* 3fe57f54 - translations: rebuild source .pot [rkitover]
* 1e1a369c - [Input] Unify UserInput event handling [steelskin]
* cc65ef28 - doc: add system requirements to README.md [danialhorton]
* 32627f6b - [Dialogs] Save and restore dialog positions [steelskin]
* 41952d06 - build: update macOS linker tool to 1.5 [rkitover]
@ -102,91 +33,34 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
* 1b77d659 - build: update macOS build to ffmpeg 7.0 [rkitover]
* 8d08223d - build: fix compatibility with older ffmpeg [rkitover]
* af6028a9 - build: fix build for nix on macOS [rkitover]
* ff3b5ee0 - build: update mac link tool to 1.4 [rkitover]
* b52edf52 - build: fix building on macOS with Homebrew [rkitover]
* 6766b9ca - build: fix ffmpeg 7.x compat [rkitover]
* 8eae2e5b - build: add FAudio to nix deps [rkitover]
* 50d17363 - build: fail finding FAudio silently [rkitover]
* 795f25bb - build: fix nix deps for OpenGL [rkitover]
* 647be137 - gba: set cpsr=spsr when switching to FIQ mode [40356555+Aikku93]
* 8abe3e79 - build: remove -lgcc from static link flags [rkitover]
* 710ffeb1 - build: update mac build [rkitover]
* a855ff54 - translations: transifex pull [rkitover]
* dbb5e534 - translations: transifex pull [rkitover]
* 75395696 - translations: transifex pull [rkitover]
* b00e23f5 - build: enable FAudio on non-Windows [rkitover]
* 8ef9a66b - [FAudio] Switch to portable `condition_variable` [steelskin]
* 0e503a52 - translations: transifex pull [rkitover]
* b4b02040 - translations: rebuild source .pot [rkitover]
* f4835674 - [Audio] Rework audio devices enumeration [steelskin]
* 4104a3d1 - build: fix codesigning Windows bins with signtool [rkitover]
* 1e1ec2e3 - translations: transifex pull [rkitover]
* ff21f8da - build: enable FAudio sound driver on Windows [rkitover]
* 775a571f - build: fix detecting Visual Studio default vcpkg [rkitover]
* 64abd3e8 - [Audio] Remove manual memory allocations [steelskin]
* 56320ec6 - translations: transifex pull [rkitover]
* 311b232e - FAudio: Implement and have functional FAudio output [zachbacon]
* 0e13cc93 - translations: transifex pull [rkitover]
* b455de01 - translations: transifex pull [rkitover]
* c3053d38 - translations: rebuild source .pot [rkitover]
* c8106573 - [Dialogs] Move SoundConfig dialog to its own class [steelskin]
* 047ad277 - [Dialogs] Prevent viewers from causing a crash [steelskin]
* ecd16a21 - translations: transifex pull [rkitover]
* 1594fda1 - translations: transifex pull [rkitover]
* de9b3a21 - translations: transifex pull [rkitover]
* 045c98d8 - build: only use -Werror=lto-type-mismatch on gcc [rkitover]
* 4ace296b - [Build] Improve the TRANSLATIONS_ONLY build speed [steelskin]
* 011adce2 - translations: transifex pull [rkitover]
* cc99ec0c - translations: transifex pull [rkitover]
* 1d652edf - translations: rebuild source .pot [rkitover]
* db08ca93 - [Build] Improve CI build coverage [steelskin]
* 3518dc6a - build: fix LTO on Linux [rkitover]
* cc9a03ce - Add toggle: SDL GameController mode for joysticks [rkitover]
* 8576733c - [Build] Remove lingering references to OpenAl [steelskin]
* c6da7e38 - build: add faudio to list of optional vcpkg deps [rkitover]
* 98abb8c2 - translations: transifex pull [rkitover]
* 05561922 - build: fix MSYS2 check [rkitover]
* d9432ebb - build: fix build on MINGW{64,32}/UCRT64 on MSYS2 [rkitover]
* f57cad67 - build: fix static linking on MSYS2 CLANG64 [rkitover]
* ce7cc4e2 - build: add FAudio to MSYS2 deps [rkitover]
* 8183a005 - translations: transifex pull [rkitover]
* 75a34cd0 - translations: transifex pull [rkitover]
* 23e15734 - build: set wxWidgets_DIR with vcpkg [rkitover]
* 98b51910 - [Build] Remove ENABLE_NLS, fix TRANSLATIONS_ONLY [steelskin]
* c3f0aa2e - translations: transifex pull [rkitover]
* ea596e4c - translations: rebuild source .pot [rkitover]
* 68adb14b - [Build] Use Toolchain-gcc-clang for non-MSVC [steelskin]
* a565cea8 - [Build] Remove the OpenGL check [steelskin]
* 6ac95d37 - [Build] Rework wx/CMakeLists.txt [steelskin]
* d4430ca4 - [Build] Move SDL build configuration to `sdl/` [steelskin]
* 000c7f85 - [Build] Move non-core common code to `components/` [steelskin]
* 047bd935 - [Build] Move the core emulator to src/core/ [steelskin]
* 33cb9a66 - [Build] Move System.h and most of Util.h to core/ [steelskin]
* f8374b52 - [Build] Move more of src/common to src/core/base [steelskin]
* 2f10e71f - [Build] Cleanup files in src/common [steelskin]
* 8f92d999 - [Build] Move file-related utilities to core/base [steelskin]
* ce12db1e - [Build] Move fex/ to src/core/fex/ [steelskin]
* d8a1886c - [Build] Use new way of setting /Z flag with MSVC [steelskin]
* 1d051d0e - [Build] Make powershell optional on non-Windows (#1248) [Steelskin]
* f96e42fe - build: cmake refactor and improvements [Steelskin]
* aa59d944 - [Build] Add toolchain-specific files (#1244) [Steelskin]
* 07e49025 - Fix most remaining release warnings (#1243) [Steelskin]
* 18b97b43 - Fix various build warnings (#1242) [Steelskin]
* b45a4066 - ci: add clang+bintools for macOS, disable LTO [rkitover]
* 1fff5cb1 - Move build options to their own file [steelskin]
* 13a16eb7 - Fix various warnings in filters and headers (#1241) [Steelskin]
* 69769c1b - [CI] Use proper POWERSHELL variable casing [steelskin]
* e998a401 - [CI] Properly inclue SDL2 directories for vbamcore (#1240) [Steelskin]
* f17a9855 - [CI] Look for pwsh in addition to powerhsell (#1239) [Steelskin]
* 85b7cf7a - translations: transifex pull [rkitover]
* f46da1c5 - build: remove our version of FindSDL2.cmake [rkitover]
* 404e9a1a - build: add clang to ./installdeps for MSYS2 [rkitover]
* 3ec8960f - translations: transifex pull [rkitover]
* 613bd403 - Make menu more reasonably organized (#1230) [wwrustc]
* ecb69a24 - build: add pthreads w/vcpkg, link FAudio target [rkitover]
* 215e3c5a - build: use find_program() to find powershell [rkitover]
* e5aa685f - build: don't use wx utils as UNIX cmds on Windows [rkitover]
* 53e1f44a - translations: transifex pull [rkitover]
* 9e4c8e17 - build: fix gentoo dependency namespaces [68k]
* 5f853b99 - Update metainfo.xml to new standards [jhonny.oliveira]
* e7d135db - Update links to new domain visualboyadvance-m.org [rkitover]

View File

@ -52,7 +52,7 @@ if(GIT_FOUND AND WIN32)
# Win32 deps submodule
set(SUBMODULE_MANUAL_UPDATE FALSE)
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" AND NOT EXISTS "${CMAKE_SOURCE_DIR}/dependencies/mingw-xaudio/include")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git" AND NOT EXISTS "${CMAKE_SOURCE_DIR}/win32-deps/mingw-xaudio/include")
set(SUBMODULE_MANUAL_UPDATE TRUE)
execute_process(
COMMAND "${GIT_EXECUTABLE}" submodule update --init --remote --recursive
@ -61,7 +61,7 @@ if(GIT_FOUND AND WIN32)
)
endif()
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/dependencies/mingw-xaudio/include")
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/win32-deps/mingw-xaudio/include")
if(NOT (SUBMODULE_MANUAL_UPDATE AND SUBMODULE_UPDATE_STATUS EQUAL 0))
message(FATAL_ERROR "Please pull in git submodules, e.g.\nrun: git submodule update --init --remote --recursive")
endif()
@ -83,16 +83,29 @@ include(Options)
include(Toolchain)
include(Dependencies)
# Disable tests when not in a git checkout.
if(NOT EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(BUILD_TESTING OFF)
endif()
# Configure gtest
if(BUILD_TESTING)
FetchContent_Declare(googletest
URL https://github.com/google/googletest/archive/2d16ed055d09c3689d44b272adc097393de948a0.zip
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
set(INSTALL_GTEST OFF CACHE BOOL "" FORCE)
include(GoogleTest)
if(NOT EXISTS third_party/googletest/CMakeLists.txt)
execute_process(
COMMAND git submodule update --init --recursive -- third_party/googletest
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
if(EXISTS third_party/googletest/CMakeLists.txt)
add_subdirectory(./third_party/googletest)
include(GoogleTest)
else()
set(BUILD_TESTING OFF)
endif()
endif()
if(NOT CMAKE_PREFIX_PATH AND (NOT ("$ENV{CMAKE_PREFIX_PATH}" STREQUAL "")))
@ -105,11 +118,6 @@ elseif(NOT CMAKE_BUILD_TYPE MATCHES "^(Release|Debug|RelWithDebInfo|MinSizeRel)$
message(FATAL_ERROR "Invalid CMAKE_BUILD_TYPE: '${CMAKE_BUILD_TYPE}', must be one of: 'Release', 'Debug', 'RelWithDebInfo' or 'MinSizeRel'")
endif()
# Link debug libs for RelWithDebInfo
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO "Debug")
endif()
set(MSYS OFF)
if(NOT "$ENV{MSYSTEM_PREFIX}" STREQUAL "")
set(MSYS ON)
@ -190,5 +198,5 @@ set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_PACKAGE_VERSION_MAJOR "2")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set(CPACK_PACKAGE_VERSION_PATCH "0-Git-${COMMITHASH}")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/dependencies")
list(APPEND CPACK_SOURCE_IGNORE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/win32-deps")
include(CPack)

View File

@ -199,11 +199,23 @@ Pass `-DCMAKE_BUILD_TYPE=Debug` to cmake.
### Release Process
#### GnuPG Key
You will need to create a GnuPG key for signing your commits and release tags,
and upload it to a keyserver.
Make sure to install GnuPG on all environments where you will be making commits
and tags.
#### Certificates
Make sure you have set up a Windows code signing certificate with the right
password and a Mac 'Developer ID Application' certificate.
Put the Windows certificate into `~/.codesign/windows_comodo.pkcs12` as a PKCS12
file that is password protected, and put the password for it into
`~/.codesign/windows_comodo.pkcs12.password`.
#### Release Commit and Tag
Once you are sure you're ready to release, and you are in a git clone on master
@ -216,6 +228,9 @@ cmake .. -DTAG_RELEASE=TRUE
```
, follow the instructions to edit the `CHANGELOG.md` and then push the release:
To reiterate, **make sure you edit the `CHANGELOG.md`** to remove any
non-user-facing changes before you make the release commit.
```bash
git push
git push --tags
@ -257,6 +272,10 @@ The 32-bit build is a legacy build for Windows XP compatibility. You will need
the MinGW toolchain to build it. The easiest method is to use the MINGW32 MSYS2
environment.
Make sure the Visual Studio `signtool.exe` is in your path, you can start MSYS2
with an inherited `PATH` from a Visual Studio enabled environment or add it to
your shell configuration.
First install dependencies with:
```bash
@ -311,10 +330,29 @@ certificate of the type 'Developer ID Application' stored in your login
keychain.
If you are not using a GUI session, you will need to use a method to unlock your
login keychain before building. Adding the certificate and key to the System
keychain is also a method that some people use.
login keychain before building so that your codesigning certificate can be used.
Adding the certificate and key to the System keychain is also a method that some
people use.
Then run:
To unlock your keychain on login, you can add something like this to your
`~/.zshrc`:
```bash
security unlock-keychain -p "$(cat ~/.login-keychain-password)" login.keychain
```
, with your login password in that file.
For notarization to work, you will need to create an app-specific password on
https://appleid.apple.com , get your Team ID from your Apple Developer account,
and store them with this command:
```bash
xcrun notarytool store-credentials AC_PASSWORD \
--apple-id you@domain.com \
--team-id <DeveloperTeamID> \
--password <secret_app_specific_2FA_password>
```
. Once all of this is set up, run:
```bash
tools/osx/builder

View File

@ -218,6 +218,7 @@ cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_LINK=NO -G Ninja
| `ENABLE_LTO` | Compile with Link Time Optimization (gcc and clang only) | ON for release build |
| `ENABLE_GBA_LOGGING` | Enable extended GBA logging | ON |
| `ENABLE_XAUDIO2` | Enable xaudio2 sound output for wxWidgets (Windows only) | ON |
| `ENABLE_FAUDIO` | Enable faudio sound output for wxWidgets, | ON, not 32 bit Win |
| `ENABLE_ASAN` | Enable libasan sanitizers (by default address, only in debug mode) | OFF |
| `UPSTREAM_RELEASE` | Do some release tasks, like codesigning, making zip and gpg sigs. | OFF |
| `BUILD_TESTING` | Build the tests and enable ctest support. | ON |

View File

@ -56,9 +56,11 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "[xX]86|i[3-9]86|[aA][mM][dD]64")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "[aA][aA][rR][cC][hH]|[aA][rR][mM]")
if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 4) # 32 bit
set(ARM32 ON)
set(ARCH_NAME arm32)
set(WINARCH arm)
elseif(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
set(ARM64 ON)
set(ARCH_NAME arm64)
set(WINARCH arm64)
endif()

View File

@ -23,7 +23,7 @@ if(CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg")
if(VCPKG_TARGET_TRIPLET MATCHES -static)
set(arch_suffix -static)
endif()
if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(path_prefix debug)
endif()
set(installed_prefix ${_VCPKG_INSTALLED_DIR}/${WINARCH}-windows${arch_suffix}/${path_prefix})

View File

@ -1,110 +0,0 @@
#.rst:
# FindOpenAL
# ----------
#
#
#
# Locate OpenAL This module defines OPENAL_LIBRARY OPENAL_FOUND, if
# false, do not try to link to OpenAL OPENAL_INCLUDE_DIR, where to find
# the headers
#
# $OPENALDIR is an environment variable that would correspond to the
# ./configure --prefix=$OPENALDIR used in building OpenAL.
#
# Created by Eric Wing. This was influenced by the FindSDL.cmake
# module.
#=============================================================================
# Copyright 2005-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
# This makes the presumption that you are include al.h like
# #include "al.h"
# and not
# #include <AL/al.h>
# The reason for this is that the latter is not entirely portable.
# Windows/Creative Labs does not by default put their headers in AL/ and
# OS X uses the convention <OpenAL/al.h>.
#
# For Windows, Creative Labs seems to have added a registry key for their
# OpenAL 1.1 installer. I have added that key to the list of search paths,
# however, the key looks like it could be a little fragile depending on
# if they decide to change the 1.00.0000 number for bug fix releases.
# Also, they seem to have laid down groundwork for multiple library platforms
# which puts the library in an extra subdirectory. Currently there is only
# Win32 and I have hardcoded that here. This may need to be adjusted as
# platforms are introduced.
# The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
# I do not know if the Nvidia OpenAL SDK has a registry key.
#
# For OS X, remember that OpenAL was added by Apple in 10.4 (Tiger).
# To support the framework, I originally wrote special framework detection
# code in this module which I have now removed with CMake's introduction
# of native support for frameworks.
# In addition, OpenAL is open source, and it is possible to compile on Panther.
# Furthermore, due to bugs in the initial OpenAL release, and the
# transition to OpenAL 1.1, it is common to need to override the built-in
# framework.
# Per my request, CMake should search for frameworks first in
# the following order:
# ~/Library/Frameworks/OpenAL.framework/Headers
# /Library/Frameworks/OpenAL.framework/Headers
# /System/Library/Frameworks/OpenAL.framework/Headers
#
# On OS X, this will prefer the Framework version (if found) over others.
# People will have to manually change the cache values of
# OPENAL_LIBRARY to override this selection or set the CMake environment
# CMAKE_INCLUDE_PATH to modify the search paths.
find_path(OPENAL_INCLUDE_DIR al.h
HINTS
ENV OPENALDIR
PATH_SUFFIXES AL OpenAL
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
/opt
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_OpenAL_ARCH_DIR libs/Win64)
else()
set(_OpenAL_ARCH_DIR libs/Win32)
endif()
find_library(OPENAL_LIBRARY
NAMES OpenAL al openal OpenAL32
HINTS
ENV OPENALDIR
PATH_SUFFIXES lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
PATHS
~/Library/Frameworks
/Library/Frameworks
/sw
/opt/local
/opt/csw
/opt
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
)
unset(_OpenAL_ARCH_DIR)
# handle the QUIETLY and REQUIRED arguments and set OPENAL_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)

View File

@ -71,14 +71,7 @@ find_package(PkgConfig)
if(TRANSLATIONS_ONLY)
set(ENABLE_LINK_DEFAULT OFF)
else()
find_package(SFML 2.4 COMPONENTS network system)
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
if(SFML_STATIC_LIBRARIES AND SFML_NETWORK_LIBRARY_STATIC_DEBUG AND SFML_SYSTEM_LIBRARY_STATIC_DEBUG)
set(SFML_LIBRARIES ${SFML_NETWORK_LIBRARY_STATIC_DEBUG} ${SFML_SYSTEM_LIBRARY_STATIC_DEBUG})
elseif(SFML_NETWORK_LIBRARY_DYNAMIC_DEBUG AND SFML_SYSTEM_LIBRARY_DYNAMIC_DEBUG)
set(SFML_LIBRARIES ${SFML_NETWORK_LIBRARY_DYNAMIC_DEBUG} ${SFML_SYSTEM_LIBRARY_DYNAMIC_DEBUG})
endif()
endif()
find_package(SFML 3.0 COMPONENTS network system)
set(ENABLE_LINK_DEFAULT OFF)
if(SFML_FOUND)
set(ENABLE_LINK_DEFAULT ON)
@ -91,7 +84,7 @@ set(FFMPEG_DEFAULT OFF)
set(FFMPEG_COMPONENTS AVCODEC AVFORMAT SWSCALE AVUTIL SWRESAMPLE)
set(FFMPEG_COMPONENT_VERSIONS AVCODEC>=58.18.100 AVFORMAT>=58.12.100 SWSCALE>=5.1.100 AVUTIL>=56.14.100 SWRESAMPLE>=3.1.100)
if(NOT TRANSLATIONS_ONLY AND NOT DEFINED ENABLE_FFMPEG OR ENABLE_FFMPEG)
if(NOT TRANSLATIONS_ONLY AND (NOT DEFINED ENABLE_FFMPEG OR ENABLE_FFMPEG) AND (NOT (X86 AND MINGW)))
set(FFMPEG_DEFAULT ON)
find_package(FFmpeg COMPONENTS ${FFMPEG_COMPONENTS})

View File

@ -10,19 +10,28 @@ if(NOT DEFINED VCPKG_TARGET_TRIPLET)
# Check if we are in an MSVC environment.
find_program(cl_exe_path NAME cl.exe HINTS ENV PATH)
if($ENV{CXX} MATCHES "cl.exe$" OR cl_exe_path)
if(ENV{CXX} MATCHES "cl.exe$" OR cl_exe_path)
# Infer the architecture from the LIB folders.
foreach(LIB $ENV{LIB})
if(${LIB} MATCHES "x64$")
foreach(lib $ENV{LIB})
if(lib MATCHES "x64$")
set(VBAM_VCPKG_PLATFORM "x64-windows-static")
break()
endif()
if(${LIB} MATCHES "x86$")
if(lib MATCHES "x86$")
set(VBAM_VCPKG_PLATFORM "x86-windows-static")
break()
endif()
if(${LIB} MATCHES "ARM64$")
if(lib MATCHES "ARM64$")
set(VBAM_VCPKG_PLATFORM "arm64-windows-static")
foreach(path $ENV{PATH})
if(path MATCHES "[Hh]ost[Xx]64")
set(VCPKG_HOST_TRIPLET "x64-windows-static" CACHE STRING "Vcpkg host triplet" FORCE)
set(VCPKG_USE_HOST_TOOLS ON CACHE BOOL "Use vcpkg host tools" FORCE)
break()
endif()
endforeach()
break()
endif()
endforeach()
@ -567,14 +576,4 @@ endfunction()
vcpkg_set_toolchain()
# Make vcpkg use debug libs for RelWithDebInfo
set(orig_build_type ${CMAKE_BUILD_TYPE})
if(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
set(CMAKE_BUILD_TYPE Debug)
endif()
include(${VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)
set(CMAKE_BUILD_TYPE ${orig_build_type})
unset(orig_build_type)

View File

@ -7,8 +7,10 @@ if(UPSTREAM_RELEASE)
# Require and optimize for Core2 level support, tune for generic.
add_compile_options(-march=core2 -mtune=generic)
elseif(X86_32)
# Optimize for pentium-mmx and tune for generic for older builds.
add_compile_options(-march=pentium-mmx -mtune=generic)
# Optimize for pentiumi3 and tune for generic for Windows XP builds.
set(WINXP TRUE)
add_compile_options(-march=pentium3 -mtune=generic)
add_compile_definitions(-DWINXP)
endif()
endif()
@ -46,7 +48,7 @@ if(NOT ENABLE_ASM) # inline asm is not allowed with -fPIC
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(-ggdb3 -Og -fno-omit-frame-pointer -Wall -Wextra)
add_compile_options(-ggdb3 -fno-omit-frame-pointer -Wall -Wextra)
else()
add_compile_options(-Ofast -fomit-frame-pointer)
endif()

View File

@ -3,8 +3,8 @@ if (NOT MINGW)
endif()
# this has to run after the toolchain is initialized.
include_directories("${CMAKE_SOURCE_DIR}/dependencies/mingw-include")
include_directories("${CMAKE_SOURCE_DIR}/dependencies/mingw-xaudio/include")
include_directories("${CMAKE_SOURCE_DIR}/win32-deps/mingw-include")
include_directories("${CMAKE_SOURCE_DIR}/win32-deps/mingw-xaudio/include")
# Add Winsock as the last library linked because of broken link precedence.
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lws2_32")

View File

@ -10,7 +10,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
endif()
endif()
include_directories("${CMAKE_SOURCE_DIR}/dependencies/msvc")
include_directories("${CMAKE_SOURCE_DIR}/win32-deps/msvc")
add_compile_definitions(
_FORCENAMELESSUNION

View File

@ -16,7 +16,7 @@ Ignore the following cmake error.
# Get last tag.
execute_process(
COMMAND ${GIT_EXECUTABLE} tag --sort=-v:refname
COMMAND git tag --sort=-v:refname
OUTPUT_VARIABLE git_tags
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
@ -43,7 +43,7 @@ Ignore the following cmake error.
# Clone repo.
execute_process(
COMMAND ${GIT_EXECUTABLE} clone git@github.com:visualboyadvance-m/visualboyadvance-m.github.io web-data
COMMAND git clone git@github.com:visualboyadvance-m/visualboyadvance-m.github.io web-data
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
@ -103,21 +103,21 @@ Ignore the following cmake error.
)
execute_process(
COMMAND ${GIT_EXECUTABLE} add appcast.xml
COMMAND git add appcast.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/web-data
)
# Commit the change.
execute_process(
COMMAND ${GIT_EXECUTABLE} commit -m "release ${new_tag}" --signoff -S
COMMAND git commit -m "release ${new_tag}" --signoff -S
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/web-data
)
# Make release tag.
execute_process(
COMMAND ${GIT_EXECUTABLE} tag -s -m${new_tag} ${new_tag}
COMMAND git tag -s -m${new_tag} ${new_tag}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/web-data
)

View File

@ -2,7 +2,7 @@ with import <nixpkgs> {};
stdenv.mkDerivation {
name = "visualboyadvance-m";
buildInputs = if stdenv.isDarwin then
[ ninja cmake gcc nasm faudio gettext libintl pkg-config zip sfml zlib openal ffmpeg wxGTK32 SDL2 pcre pcre2 darwin.apple_sdk.frameworks.System darwin.apple_sdk.frameworks.IOKit darwin.apple_sdk.frameworks.Carbon darwin.apple_sdk.frameworks.Cocoa darwin.apple_sdk.frameworks.QuartzCore darwin.apple_sdk.frameworks.AudioToolbox darwin.apple_sdk.frameworks.OpenGL darwin.apple_sdk.frameworks.OpenAL llvmPackages_latest.clang llvmPackages_latest.bintools ]
[ ninja cmake nasm faudio gettext libintl pkg-config zip zlib openal ffmpeg wxGTK32 SDL2 pcre pcre2 darwin.apple_sdk.frameworks.System darwin.apple_sdk.frameworks.IOKit darwin.apple_sdk.frameworks.Carbon darwin.apple_sdk.frameworks.Cocoa darwin.apple_sdk.frameworks.QuartzCore darwin.apple_sdk.frameworks.AudioToolbox darwin.apple_sdk.frameworks.OpenGL darwin.apple_sdk.frameworks.OpenAL llvmPackages_latest.clang llvmPackages_latest.bintools ]
else
[ ninja cmake gcc nasm faudio gettext libintl pkg-config zip sfml zlib openal ffmpeg wxGTK32 libGL libGLU glfw SDL2 gtk3-x11 pcre pcre2 util-linuxMinimal libselinux libsepol libthai libdatrie xorg.libXdmcp xorg.libXtst libxkbcommon epoxy dbus at-spi2-core ];
[ ninja cmake gcc clang llvm llvmPackages.libcxx nasm faudio gettext libintl pkg-config zip zlib openal ffmpeg wxGTK32 libGL libGLU glfw SDL2 gtk3-x11 pcre pcre2 util-linuxMinimal libselinux libsepol libthai libdatrie xorg.libXdmcp xorg.libXtst libxkbcommon libepoxy dbus at-spi2-core ];
}

@ -1 +0,0 @@
Subproject commit e8ce758a98161d47559aa294d3298425ec75e28e

View File

@ -799,12 +799,10 @@ suse_installdeps() {
tools="make cmake ccache nasm gettext-tools pkg-config ccache zip sfml2-devel ninja"
libs="gcc gcc-c++ libSDL2-devel wxWidgets-3_0-devel openal-soft-devel" # ffmpeg-devel
# ffmpeg requires packman repos
libs="gcc gcc-c++ libSDL2-devel wxGTK3-3_2-devel openal-soft-devel ffmpeg-7-libavcodec-devel ffmpeg-7-libavdevice-devel ffmpeg-7-libavfilter-devel ffmpeg-7-libavformat-devel ffmpeg-7-libavutil-devel ffmpeg-7-libpostproc-devel ffmpeg-7-libswresample-devel ffmpeg-7-libswscale-devel"
if [ "$target" = m32 ]; then
libs=$(echo "$libs" | sed -E 's/([^ ]) ([^ ])/\1-32bit \2/g; s/$/-32bit/;')
error '32 bit cross builds are no longer supported on OpenSUSE'
fi
check sudo zypper in -y $tools $libs
@ -1118,9 +1116,12 @@ windows_installdeps() {
*i686*)
pkgs="$pkgs nasm"
;;
*)
pkgs="$pkgs FAudio"
;;
esac
pkgs="$pkgs SDL2 sfml FAudio wxWidgets3.2 zlib binutils cmake crt-git headers-git make pkgconf tools-git windows-default-manifest libmangle-git ninja gdb ccache openal"
pkgs="$pkgs SDL2 sfml wxWidgets3.2 zlib binutils cmake crt-git headers-git make pkgconf tools-git windows-default-manifest libmangle-git ninja gdb ccache openal"
case "$target" in
*x86_64)

View File

@ -3,6 +3,7 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Orfeas Artinopoulos, 2025
# Stathis Galazios <infin1ty@hol.gr>, 2016-2017
msgid ""
msgstr ""
@ -10,7 +11,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: Stathis Galazios <infin1ty@hol.gr>, 2016-2017\n"
"Last-Translator: Orfeas Artinopoulos, 2025\n"
"Language-Team: Greek (http://app.transifex.com/bgk/vba-m/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -20,7 +21,7 @@ msgstr ""
#: audio/internal/openal.cpp:188
msgid "OpenAL: Failed to open audio device"
msgstr ""
msgstr "OpenAL: Αποτυχία ανοίγματος της συσκευής ήχου"
#: audio/internal/openal.cpp:386 audio/internal/faudio.cpp:492
#: audio/internal/xaudio2.cpp:577
@ -33,7 +34,7 @@ msgid ""
"(*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game"
" Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Αρχεία Game Boy Advance (*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game Boy Files (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:144
msgid "Open ROM file"
@ -43,7 +44,7 @@ msgstr "Άνοιγμα αρχείου ROM"
msgid ""
"Game Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Αρχεία Game Boy (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:171
msgid "Open GB ROM file"
@ -53,7 +54,7 @@ msgstr "Άνοιγμα αρχείου GB ROM"
msgid ""
"Game Boy Color Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Αρχεία Game Boy Color (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:198
msgid "Open GBC ROM file"
@ -65,7 +66,7 @@ msgstr "Επιλογή αρχείου Dot Code"
#: cmdevents.cpp:365 cmdevents.cpp:387
msgid "E-Reader Dot Code (*.bin;*.raw)|*.bin;*.raw"
msgstr ""
msgstr "Κώδικας κουκίδας E-Reader (*.bin;*.raw)|*.bin;*.raw"
#: cmdevents.cpp:406 cmdevents.cpp:601
msgid "Select battery file"
@ -79,7 +80,7 @@ msgstr "Αρχείο μπαταρίας (*.sav)|*.sav|Αποθήκευση Flash
msgid ""
"Importing a battery file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "Η εισαγωγή ενός αρχείου μπαταρίας θα διαγράψει το ήδη αποθηκευμένο παιχνίδι (μόνιμα μετά την επόμενη εγγραφή). Θέλετε να προχωρήσετε;"
#: cmdevents.cpp:416 cmdevents.cpp:444 cmdevents.cpp:564
msgid "Confirm import"
@ -101,17 +102,17 @@ msgstr "Επιλογή αρχείου κωδικών"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.spc;*.xpc)|*.spc;*.xpc"
msgstr ""
msgstr "Αρχείο κωδικών Game Shark (*.spc;*.xpc)|*.spc;*.xpc"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.gcf)|*.gcf"
msgstr ""
msgstr "Αρχείο κωδικών Game Shark (*.gcf)|*.gcf"
#: cmdevents.cpp:443
msgid ""
"Importing a code file will replace any loaded cheats. Do you want to "
"continue?"
msgstr ""
msgstr "Η εισαγωγή αρχείου κωδικών θα αντικαταστήσει τυχόν φορτωμένους κωδικούς. Θέλετε να συνεχίσετε;"
#: cmdevents.cpp:460
#, c-format
@ -141,17 +142,17 @@ msgstr "Επιλογή αρχείου στιγμιότυπου"
msgid ""
"Game Shark & PAC Snapshots (*.sps;*.xps)|*.sps;*.xps|Game Shark SP Snapshots"
" (*.gsv)|*.gsv"
msgstr ""
msgstr "Στιγμιότυπα Game Shark & PAC (*.sps;*.xps)|*.sps;*.xps|Στιγμιότυπα Game Shark SP (*.gsv)|*.gsv"
#: cmdevents.cpp:554
msgid "Game Boy Snapshot (*.gbs)|*.gbs"
msgstr ""
msgstr "Στιγμιότυπο Game Boy (*.gbs)|*.gbs"
#: cmdevents.cpp:563
msgid ""
"Importing a snapshot file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "Η εισαγωγή ενός στιγμιοτύπου θα διαγράψει τυχόν αποθηκευμένα παιχνίδια (μόνιμα μετά την επόμενη εγγραφή). Θέλετε να προχωρήσετε;"
#: cmdevents.cpp:588
#, c-format
@ -179,11 +180,11 @@ msgstr "Δεν είναι δυνατή η εξαγωγή αρχείων αποθ
#: cmdevents.cpp:630
msgid "Game Shark Snapshot (*.sps)|*.sps"
msgstr ""
msgstr "Στιγμιότυπο Game Shark (*.sps)|*.sps"
#: cmdevents.cpp:644
msgid "Exported from Visual Boy Advance-M"
msgstr ""
msgstr "Εξαγωγή από το Visual Boy Advance-M"
#: cmdevents.cpp:656
#, c-format
@ -224,16 +225,16 @@ msgstr "Επιλογή αρχείου κατάστασης"
#: cmdevents.cpp:1263 cmdevents.cpp:1356
msgid "Visual Boy Advance saved game files|*.sgm"
msgstr ""
msgstr "Αποθηκευμένα αρχεία παιχνιδιού Visual Boy Advance|*.sgm"
#: cmdevents.cpp:1386 cmdevents.cpp:1396 cmdevents.cpp:1407
#, c-format
msgid "Current state slot #%d"
msgstr ""
msgstr "Τρέχουσα θέση στιγμιοτύπου #%d"
#: cmdevents.cpp:1470
msgid "Cannot use Colorizer Hack when Game Boy BIOS File is enabled."
msgstr ""
msgstr "Δεν μπορεί να χρησιμοποιηθεί το Colorizer Hack όσο είναι ενεργοποιημένο το αρχείο BIOS του Game Boy "
#: cmdevents.cpp:1681
msgid "Sound enabled"
@ -274,22 +275,22 @@ msgid ""
"YOUR CONFIGURATION WILL BE DELETED!\n"
"\n"
"Are you sure?"
msgstr ""
msgstr "ΟΙ ΡΥΘΜΙΣΕΙΣ ΣΑΣ ΘΑ ΔΙΑΓΡΑΦΟΥΝ!"
#: cmdevents.cpp:2201
msgid "FACTORY RESET"
msgstr ""
msgstr "ΕΡΓΟΣΤΑΣΙΑΚΕΣ ΡΥΘΜΙΣΕΙΣ"
#: cmdevents.cpp:2236
msgid "Nintendo Game Boy / Color / Advance emulator."
msgstr ""
msgstr "Εξομοιωτής Nintendo Game Boy / Color / Advance."
#: cmdevents.cpp:2237
msgid ""
"Copyright (C) 1999-2003 Forgotten\n"
"Copyright (C) 2004-2006 VBA development team\n"
"Copyright (C) 2007-2020 VBA-M development team"
msgstr ""
msgstr "Πνευματική Ιδιοκτησία (C) 1999-2003 Ξεχασμένη Πνευματική Ιδιοκτησία (C) 2004-2006 VBA Ομάδα ανάπτυξης VBA Πνευματική Ιδιοκτησία (C) 2007-2020 Ομάδα ανάπτυξης VBA-M"
#: cmdevents.cpp:2239
msgid ""

View File

@ -5,6 +5,7 @@
# Translators:
# Alain Richell Rodriguez Blazquez, 2021
# Álvaro Pérez Urbano <alvaro_beta@hotmail.com>, 2021
# angel quispe, 2025
# Damián Cabello Jiménez <jdamiancabello@gmail.com>, 2018
# Dani Quiroz, 2022
# Dani Quiroz, 2022
@ -15,6 +16,7 @@
# javidg96, 2015
# jorge perez <theghostxxaz@gmail.com>, 2021
# Jose Castillo <josecastillo.prz85@gmail.com>, 2021
# José Montoro, 2024
# Manu 3L <comokaka777@gmail.com>, 2021
# Marco123V <MarcoVillalejos@hotmail.com>, 2015
# Marco Yurazeck <luthias@gmail.com>, 2020
@ -29,7 +31,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: Dani Quiroz, 2022\n"
"Last-Translator: angel quispe, 2025\n"
"Language-Team: Spanish (http://app.transifex.com/bgk/vba-m/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -39,7 +41,7 @@ msgstr ""
#: audio/internal/openal.cpp:188
msgid "OpenAL: Failed to open audio device"
msgstr ""
msgstr "OpenAL: Fallo al abrir el dispositivo de audio"
#: audio/internal/openal.cpp:386 audio/internal/faudio.cpp:492
#: audio/internal/xaudio2.cpp:577
@ -52,7 +54,7 @@ msgid ""
"(*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game"
" Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Archivos de Game boy Advance (*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game Boy Files (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:144
msgid "Open ROM file"
@ -62,7 +64,7 @@ msgstr "Abrir archivo ROM"
msgid ""
"Game Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Archivos de Game Boy (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:171
msgid "Open GB ROM file"
@ -98,7 +100,7 @@ msgstr "Archivo de batería (*.sav) | *.sav | Guardado Flash (*.dat) | *.dat"
msgid ""
"Importing a battery file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "Importar un archivo de guardado borrará cualquier partida guardada (permanente después del siguiente guardado). ¿Quieres continuar?"
#: cmdevents.cpp:416 cmdevents.cpp:444 cmdevents.cpp:564
msgid "Confirm import"
@ -130,7 +132,7 @@ msgstr ""
msgid ""
"Importing a code file will replace any loaded cheats. Do you want to "
"continue?"
msgstr ""
msgstr "Importar un archivo de códigos reemplazará cualquier cheat cargado. ¿Quieres continuar?"
#: cmdevents.cpp:460
#, c-format
@ -170,7 +172,7 @@ msgstr ""
msgid ""
"Importing a snapshot file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "Importar una snapshot borrará cualquier partida guardada (permanente una vez se sobrescriba) ¿Quieres continuar?"
#: cmdevents.cpp:588
#, c-format
@ -202,7 +204,7 @@ msgstr ""
#: cmdevents.cpp:644
msgid "Exported from Visual Boy Advance-M"
msgstr ""
msgstr "Exportado desde Visual Boy Advance-M"
#: cmdevents.cpp:656
#, c-format
@ -293,15 +295,15 @@ msgid ""
"YOUR CONFIGURATION WILL BE DELETED!\n"
"\n"
"Are you sure?"
msgstr ""
msgstr "¡SE BORRARÁ TU CONFIGURACIÓN!\n\n¿Estás seguro?"
#: cmdevents.cpp:2201
msgid "FACTORY RESET"
msgstr ""
msgstr "RESETEO DE FÁBRICA"
#: cmdevents.cpp:2236
msgid "Nintendo Game Boy / Color / Advance emulator."
msgstr ""
msgstr "Emulador de Nintendo Game Boy / Color / Advance"
#: cmdevents.cpp:2237
msgid ""
@ -324,11 +326,11 @@ msgid ""
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses ."
msgstr ""
msgstr "Este programa es un software gratis: puedes redistribuirlo / o modificarlo bajo los terminos de la Licencia Pública General GNU.\npublicada por\nla Free Software Foundation, ya sea la versión 2 de la Licencia, o\n(a su elección) cualquier versión posterior.\n\nEste programa se distribuye con la esperanza de que sea útil,\npero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de\nCOMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Ver el\nLicencia pública general GNU para obtener más detalles.\n\nDebería haber recibido una copia de la Licencia Pública General GNU\njunto con este programa. Si no, consulte http://www.gnu.org/licenses."
#: cmdevents.cpp:2424
msgid "Cannot use Game Boy BIOS when Colorizer Hack is enabled."
msgstr ""
msgstr "No puedes usar la BIOS de la Game Boy cuando el Hack Colorizer está habilitado."
#: cmdevents.cpp:2490
msgid "LAN link is already active. Disable link mode to disconnect."
@ -344,7 +346,7 @@ msgstr "Menú de comandos"
#: dialogs/accel-config.cpp:245
msgid "This will clear all user-defined accelerators. Are you sure?"
msgstr ""
msgstr "Esto borrará todos los aceleradores definidos por el usuario. ¿Estás seguro?"
#: dialogs/accel-config.cpp:245 dialogs/accel-config.cpp:292
msgid "Confirm"
@ -401,7 +403,7 @@ msgstr "Desconocido"
#: dialogs/game-maker.cpp:235
msgid "Invalid"
msgstr ""
msgstr "No válido "
#: dialogs/gb-rom-info.cpp:22
msgid "No mapper"

View File

@ -3,15 +3,18 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Andrés Oña, 2025
# chxndler perez cueva <chxndlerpc@gmail.com>, 2018
# Dani Quiroz, 2022
# David Martínez <david8dgm@gmail.com>, 2020
# Dex Galaxy, 2022
# Dilan Meza, 2025
# Enzo Cortés, 2023
# FERNANDO AYALA PEREZ, 2021
# Kevin Bustinza <ufreshx@gmail.com>, 2021
# MELERIX, 2023
# Sebastián Castro Saldarriaga, 2023
# Timoteo Traiber Minnaard, 2024
# Yeferson Galviz, 2023
# yocsan Cañderón <yecoyocsan@gmail.com>, 2021
msgid ""
@ -20,7 +23,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: Yeferson Galviz, 2023\n"
"Last-Translator: Dilan Meza, 2025\n"
"Language-Team: Spanish (Latin America) (http://app.transifex.com/bgk/vba-m/language/es_419/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -30,12 +33,12 @@ msgstr ""
#: audio/internal/openal.cpp:188
msgid "OpenAL: Failed to open audio device"
msgstr ""
msgstr "OpenAL: No se pudo abrir el dispositivo de audio"
#: audio/internal/openal.cpp:386 audio/internal/faudio.cpp:492
#: audio/internal/xaudio2.cpp:577
msgid "Default device"
msgstr "Default device"
msgstr "Dispositivo predeterminado"
#: cmdevents.cpp:133
msgid ""
@ -47,7 +50,7 @@ msgstr "Archivos Game Boy Advance (*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar
#: cmdevents.cpp:144
msgid "Open ROM file"
msgstr "Open ROM file"
msgstr "Abrir archivo ROM"
#: cmdevents.cpp:165
msgid ""
@ -75,7 +78,7 @@ msgstr "Seleccionar archivo de código de punto"
#: cmdevents.cpp:365 cmdevents.cpp:387
msgid "E-Reader Dot Code (*.bin;*.raw)|*.bin;*.raw"
msgstr ""
msgstr "Código de puntos del lector electrónico (*.bin;*.raw)|*.bin;*.raw"
#: cmdevents.cpp:406 cmdevents.cpp:601
msgid "Select battery file"
@ -344,7 +347,7 @@ msgstr "Confirm"
#: dialogs/accel-config.cpp:290
#, c-format
msgid "This will unassign \"%s\" from \"%s\". Are you sure?"
msgstr ""
msgstr "Esto desasignará \"1%s\" de \"1%s\". ¿Estás seguro?"
#: dialogs/directories-config.cpp:49
msgid "Browse"
@ -352,7 +355,7 @@ msgstr "Browse"
#: dialogs/display-config.cpp:52
msgid "Invalid value for Default magnification."
msgstr ""
msgstr "Valor no válido para ampliación predeterminada."
#: dialogs/display-config.cpp:331 xrc/DisplayConfig.xrc:86
#: xrc/DisplayConfig.xrc:136 xrc/DisplayConfig.xrc:222
@ -374,7 +377,7 @@ msgstr "Plugin"
#: dialogs/display-config.cpp:407
#, c-format
msgid "Using pixel filter: %s"
msgstr ""
msgstr "Usando filtro de píxeles: 1%s"
#: dialogs/display-config.cpp:414
#, c-format
@ -392,35 +395,35 @@ msgstr "Unknown"
#: dialogs/game-maker.cpp:235
msgid "Invalid"
msgstr ""
msgstr "Inválido"
#: dialogs/gb-rom-info.cpp:22
msgid "No mapper"
msgstr ""
msgstr "Sin mapeador"
#: dialogs/gb-rom-info.cpp:43
msgid "Pocket Camera"
msgstr ""
msgstr "Cámara de bolsillo"
#: dialogs/gb-rom-info.cpp:68
msgid " + RAM"
msgstr ""
msgstr "+ RAM"
#: dialogs/gb-rom-info.cpp:69
msgid " + RTC"
msgstr ""
msgstr "+RTC"
#: dialogs/gb-rom-info.cpp:70
msgid " + Battery"
msgstr ""
msgstr "+ Batería"
#: dialogs/gb-rom-info.cpp:71
msgid " + Rumble"
msgstr ""
msgstr "+ Rumble"
#: dialogs/gb-rom-info.cpp:72
msgid " + Motion Sensor"
msgstr ""
msgstr "+ Sensor de Movimiento"
#: dialogs/gb-rom-info.cpp:74
#, c-format
@ -486,7 +489,7 @@ msgstr ""
#: dialogs/gb-rom-info.cpp:159
#, c-format
msgid "%02X (Unknown)"
msgstr ""
msgstr "%02X (Desconocido)"
#: dialogs/gb-rom-info.cpp:131
#, c-format
@ -516,7 +519,7 @@ msgstr ""
#: dialogs/gb-rom-info.cpp:155
#, c-format
msgid "%02X (Japan)"
msgstr ""
msgstr "%02X (Japón)"
#: dialogs/gb-rom-info.cpp:157
#, c-format
@ -568,7 +571,7 @@ msgstr "Aceptar"
#: gfxviewers.cpp:1202
msgid "Select output file and type"
msgstr "Select output file and type"
msgstr "Seleccionar archivo de salida y tipo"
#: gfxviewers.cpp:1203
msgid ""
@ -582,15 +585,15 @@ msgstr "Start!"
#: guiinit.cpp:110
msgid "Connect"
msgstr "Connect"
msgstr "Conectar"
#: guiinit.cpp:127
msgid "You must enter a valid host name"
msgstr "You must enter a valid host name"
msgstr "Debe introducir un nombre de host válido"
#: guiinit.cpp:128
msgid "Host name invalid"
msgstr "Host name invalid"
msgstr "Nombre de host inválido"
#: guiinit.cpp:146
msgid "Waiting for clients..."
@ -670,15 +673,15 @@ msgstr "32-bit "
#: guiinit.cpp:1057
msgid "Signed decimal"
msgstr ""
msgstr "decimal con signo"
#: guiinit.cpp:1061
msgid "Unsigned decimal"
msgstr ""
msgstr "decimal sin signo"
#: guiinit.cpp:1065
msgid "Unsigned hexadecimal"
msgstr ""
msgstr "hexadecimal sin signo"
#: guiinit.cpp:1637
msgid "Main icon not found"
@ -881,11 +884,11 @@ msgstr "Sin VSYNC disponible en esta plataforma"
#: panel.cpp:2444
msgid "Memory allocation error"
msgstr ""
msgstr "error en la asignación de memoria"
#: panel.cpp:2447
msgid "Error initializing codec"
msgstr ""
msgstr "error al inicializar codec"
#: panel.cpp:2450
msgid "Error writing to output file"
@ -1008,7 +1011,7 @@ msgstr "Select memory dump file"
#: viewsupt.cpp:789
msgid "Red:"
msgstr ""
msgstr "Rojo:"
#: viewsupt.cpp:798
msgid "Green:"
@ -3460,7 +3463,7 @@ msgstr "&R"
#: xrc/MainMenu.xrc:494 xrc/MainMenu.xrc:517
msgid "Configure..."
msgstr ""
msgstr "Configurar..."
#: xrc/MainMenu.xrc:498
msgid "&Real-time clock"
@ -3480,15 +3483,15 @@ msgstr "&LCD Filter"
#: xrc/MainMenu.xrc:521
msgid "&Game Boy color option"
msgstr ""
msgstr "Opción de color Game Boy"
#: xrc/MainMenu.xrc:529
msgid "&Game Boy Colorizer Hack (requires restart)"
msgstr ""
msgstr "Hack de color Game Boy (requiere reinicio)"
#: xrc/MainMenu.xrc:533
msgid "&Game Boy printer"
msgstr ""
msgstr "Impresora Game Boy"
#: xrc/MainMenu.xrc:537
msgid "&Gather a full page before printing"
@ -3500,43 +3503,43 @@ msgstr "&Save printouts as screen captures"
#: xrc/MainMenu.xrc:546
msgid "&Use Game Boy BIOS file (requires restart)"
msgstr ""
msgstr "Usar archivo BIOS de Game Boy (requiere reinicio)"
#: xrc/MainMenu.xrc:550
msgid "&Use Game Boy Color BIOS file"
msgstr ""
msgstr "Usar archivo BIOS de Game Boy Color"
#: xrc/MainMenu.xrc:555
msgid "&General..."
msgstr ""
msgstr "General"
#: xrc/MainMenu.xrc:558
msgid "&Speedup / Turbo..."
msgstr ""
msgstr "Aceleración / Turbo"
#: xrc/MainMenu.xrc:561
msgid "D&irectories..."
msgstr ""
msgstr "Directorios"
#: xrc/MainMenu.xrc:564
msgid "&Key Shortcuts..."
msgstr ""
msgstr "Atajos de teclas"
#: xrc/MainMenu.xrc:567
msgid "UI Settings"
msgstr ""
msgstr "Configuración de UI"
#: xrc/MainMenu.xrc:569
msgid "Enable &Status bar"
msgstr ""
msgstr "Habilitar barra de estado"
#: xrc/MainMenu.xrc:573
msgid "Hide &Menu Bar"
msgstr ""
msgstr "Ocultar barra de menú"
#: xrc/MainMenu.xrc:577
msgid "Suspend &Screen Saver"
msgstr ""
msgstr "Suspender y proteger pantalla"
#: xrc/MainMenu.xrc:583
msgid "&Tools"
@ -3548,15 +3551,15 @@ msgstr "&Cheats"
#: xrc/MainMenu.xrc:587
msgid "List &cheats..."
msgstr ""
msgstr "Lista y trucos"
#: xrc/MainMenu.xrc:590
msgid "Find c&heat..."
msgstr ""
msgstr "Encontrar truco"
#: xrc/MainMenu.xrc:594
msgid "A&utomatically save / load cheats"
msgstr ""
msgstr "Guardar / cargar trucos automáticamente"
#: xrc/MainMenu.xrc:598
msgid "&Enable cheats"
@ -3656,7 +3659,7 @@ msgstr "Report &Bugs"
#: xrc/MainMenu.xrc:733
msgid "Visual Boy Advance-M Support &Forum"
msgstr ""
msgstr "Soporte y foro de Visual Boy Advance-M"
#: xrc/MainMenu.xrc:736
msgid "Translations"
@ -3744,7 +3747,7 @@ msgstr "Start Network Link"
#: xrc/NetLink.xrc:13
msgid "WARNING: Link will likely not work over the internet or LAN."
msgstr ""
msgstr "ADVERTENCIA: Es probable que el enlace no funcione a través de Internet o LAN."
#: xrc/NetLink.xrc:38
msgid "Server"
@ -3760,7 +3763,7 @@ msgstr "Players:"
#: xrc/NetLink.xrc:83
msgid "2"
msgstr ""
msgstr "2"
#: xrc/NetLink.xrc:107
msgid "Server:"
@ -3792,7 +3795,7 @@ msgstr "Sound Settings"
#: xrc/SoundConfig.xrc:18
msgid "Volume:"
msgstr ""
msgstr "Volumen:"
#: xrc/SoundConfig.xrc:36
msgid "Mute"
@ -3804,7 +3807,7 @@ msgstr "Maximum"
#: xrc/SoundConfig.xrc:73
msgid "Sample rate:"
msgstr ""
msgstr "Frecuencia de muestreo:"
#: xrc/SoundConfig.xrc:79
msgid "48 KHz"
@ -3824,7 +3827,7 @@ msgstr "11 KHz"
#: xrc/SoundConfig.xrc:112
msgid "Direct Sound"
msgstr ""
msgstr "Sonido directo"
#: xrc/SoundConfig.xrc:140
msgid "Device"
@ -3864,7 +3867,7 @@ msgstr "Center"
#: xrc/SoundConfig.xrc:263
msgid "Left / Right"
msgstr ""
msgstr "Izquierda / Derecha"
#: xrc/SoundConfig.xrc:292
msgid "Sound filtering"
@ -3892,4 +3895,4 @@ msgstr "Frame skip"
#: xrc/SpeedupConfig.xrc:61
msgid "Mute Sound"
msgstr ""
msgstr "Silenciar sonido"

View File

@ -7,7 +7,7 @@
# Chizuru <saiber.one1@gmail.com>, 2015
# Dimas Radityo, 2022
# Jeremy Belpois <jeremy.belpois.einstein@gmail.com>, 2019
# heydootdoot last, 2024
# heydootdoot last, 2024-2025
# Jeremy Belpois <jeremy.belpois.einstein@gmail.com>, 2019-2020
msgid ""
msgstr ""
@ -15,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: heydootdoot last, 2024\n"
"Last-Translator: heydootdoot last, 2024-2025\n"
"Language-Team: Indonesian (http://app.transifex.com/bgk/vba-m/language/id/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -146,11 +146,11 @@ msgstr "Pilih snapshot"
msgid ""
"Game Shark & PAC Snapshots (*.sps;*.xps)|*.sps;*.xps|Game Shark SP Snapshots"
" (*.gsv)|*.gsv"
msgstr ""
msgstr "Snapshot Game Shark & PAC (*.sps;*.xps)|*.sps;*.xps|Snapshot Game Shark SP (*.gsv)|*.gsv"
#: cmdevents.cpp:554
msgid "Game Boy Snapshot (*.gbs)|*.gbs"
msgstr ""
msgstr "Snapshot Game Boy (*.gbs)|*.gbs"
#: cmdevents.cpp:563
msgid ""
@ -171,7 +171,7 @@ msgstr "Galat memuat snapshot %s"
#: cmdevents.cpp:613
#, c-format
msgid "Wrote battery %s"
msgstr "Menyimpan baterai %s"
msgstr "Simpan baterai %s"
#: cmdevents.cpp:615 panel.cpp:803
#, c-format
@ -184,11 +184,11 @@ msgstr "Simpanan EEPROM tak dapat diekspor"
#: cmdevents.cpp:630
msgid "Game Shark Snapshot (*.sps)|*.sps"
msgstr ""
msgstr "Snapshot Game Shark (*.sps)|*.sps"
#: cmdevents.cpp:644
msgid "Exported from Visual Boy Advance-M"
msgstr ""
msgstr "Diekspor dari Visual Boy Advance-M"
#: cmdevents.cpp:656
#, c-format
@ -213,7 +213,7 @@ msgstr "Gambar PNG|*.png|Gambar BMP|*.bmp"
#: cmdevents.cpp:699 sys.cpp:579
#, c-format
msgid "Wrote snapshot %s"
msgstr "Menyimpan snapshot %s"
msgstr "Simpan snapshot %s"
#: cmdevents.cpp:720 cmdevents.cpp:790 cmdevents.cpp:859 cmdevents.cpp:925
msgid " files ("
@ -225,7 +225,7 @@ msgstr "Pilih berkas"
#: cmdevents.cpp:1262 cmdevents.cpp:1355
msgid "Select state file"
msgstr "Pilih berkas state"
msgstr "Pilih berkas savestate"
#: cmdevents.cpp:1263 cmdevents.cpp:1356
msgid "Visual Boy Advance saved game files|*.sgm"
@ -234,7 +234,7 @@ msgstr "Simpanan permainan Visual Boy Advance|*.sgm"
#: cmdevents.cpp:1386 cmdevents.cpp:1396 cmdevents.cpp:1407
#, c-format
msgid "Current state slot #%d"
msgstr "Slot keadaan saat ini #%d"
msgstr "Slot savestate saat ini #%d"
#: cmdevents.cpp:1470
msgid "Cannot use Colorizer Hack when Game Boy BIOS File is enabled."
@ -776,22 +776,22 @@ msgstr "pemain"
#: panel.cpp:751
#, c-format
msgid "Loaded state %s"
msgstr "State yang dimuat %s"
msgstr "Savestate yang dimuat %s"
#: panel.cpp:751
#, c-format
msgid "Error loading state %s"
msgstr "Terjadi kesalahan dalam memuat state %s"
msgstr "Galat memuat savestate %s"
#: panel.cpp:775
#, c-format
msgid "Saved state %s"
msgstr "State yang disimpan %s"
msgstr "Savestate yang disimpan %s"
#: panel.cpp:775
#, c-format
msgid "Error saving state %s"
msgstr "Terjadi kesalahan dalam menyimpan state %s"
msgstr "Galat menyimpan savestate %s"
#: panel.cpp:979
#, c-format
@ -828,7 +828,7 @@ msgstr "Tidak ada memori untuk memuat state mundur"
#: panel.cpp:1300
msgid "Error writing rewind state"
msgstr "Terjadi kesalahan dalam menyimpan state mundur"
msgstr "Galat menulis savestate mundur"
#: panel.cpp:2277
msgid "Enabling EGL VSync."
@ -1049,7 +1049,7 @@ msgstr "Atur berkas konfigurasi"
#: wxvbam.cpp:638
msgid "Delete shared link state first, if it exists"
msgstr "Hapus state hubungan yang dibagikan terlebih dahulu, jika ada"
msgstr "Hapus dulu tautan savestate, jika adaa"
#: wxvbam.cpp:645
msgid "List all settable options and exit"
@ -1072,7 +1072,7 @@ msgstr "Galat bina / konfigurasi: Tak dapat cari xrc tertanam"
msgid ""
"Wrote built-in configuration to %s.\n"
"To override, remove all but changed root node(s). First found root node of correct name in any .xrc or .xrs files in following search path overrides built-in:"
msgstr ""
msgstr "Menyimpan konfig tertanam ke %s.\nUntuk timpa berkas, hapus semua node root kecuali yang terubah. Cari dulu node root yang benar pada berkas .xrc / .xrs di pencarian berkas timpaan tertanam berikut:"
#: wxvbam.cpp:703
msgid "Configuration is read from, in order:"
@ -1083,7 +1083,7 @@ msgstr "Konfigurasi dibaca dari, secara berurutan:"
msgid ""
"Wrote built-in override file to %s\n"
"To override, delete all but changed section. First found section is used from search path:"
msgstr ""
msgstr "Menyimpan berkas timpaan ke %s\nUntuk timpa berkas, hapus semua bagian kecuali yang terubah. Cari dulu bagian yang digunakan dari pencarian:"
#: wxvbam.cpp:723
msgid ""
@ -1342,7 +1342,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:445
msgid "Automatically load last saved state"
msgstr ""
msgstr "Otomatis memuat terakhir savestate"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:447
msgid ""
@ -1507,11 +1507,11 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:522
msgid "Do not overwrite cheat list when loading state"
msgstr ""
msgstr "Jangan timpa daftar cheat saat memuat savestate"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:524
msgid "Do not overwrite native (battery) save when loading state"
msgstr ""
msgstr "Jangan timpa simpanan lokal (baterai) saat memuat savestate"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:526
msgid "Throttle game speed, even when accelerated (0-450 %, 0 = no throttle)"
@ -3078,7 +3078,7 @@ msgstr "Ter&baru"
#: xrc/MainMenu.xrc:50
msgid "Load current state slot"
msgstr "Muat slot keadaan saat ini"
msgstr "Muat savestate saat ini"
#: xrc/MainMenu.xrc:53
msgid "&Auto load most recent"
@ -3098,7 +3098,7 @@ msgstr "Jangan ubah daftar &cheat"
#: xrc/MainMenu.xrc:100
msgid "&Load state"
msgstr "&Muat state"
msgstr "&Muat savestate"
#: xrc/MainMenu.xrc:104
msgid "&Oldest slot"
@ -3106,11 +3106,11 @@ msgstr "&Slot terlama"
#: xrc/MainMenu.xrc:107
msgid "Save current state slot"
msgstr "Simpan slot keadaan saat ini"
msgstr "Simpan savestate saat ini"
#: xrc/MainMenu.xrc:110
msgid "Increase state slot number and save"
msgstr "Tambah jumlah slot keadaan lalu simpan"
msgstr "Tambah jumlah savestate lalu simpan"
#: xrc/MainMenu.xrc:117
msgid "&2"
@ -3154,15 +3154,15 @@ msgstr ""
#: xrc/MainMenu.xrc:147
msgid "&Save state"
msgstr "&Simpan state"
msgstr "&Simpan savestate"
#: xrc/MainMenu.xrc:150
msgid "Increase state slot number"
msgstr "Tambah jumlah slot keadaan"
msgstr "Tambah jumlah savestate"
#: xrc/MainMenu.xrc:153
msgid "Decrease state slot number"
msgstr "Kurangi jumlah slot keadaan"
msgstr "Kurangi jumlah ssavestate"
#: xrc/MainMenu.xrc:158 xrc/MainMenu.xrc:170
msgid "&Battery file..."

View File

@ -13,6 +13,7 @@
# Giulio Serroni, 2022
# JustAnOrange, 2023
# Luca Bonello <fenopiu@gmail.com>, 2016
# ludo thorn, 2025
# Michele Rebughini <michelerebughini@gmail.com>, 2020
# OTTO X <blg.dpnx@gmail.com>, 2015
# Picat <pichu474android@gmail.com>, 2016
@ -26,7 +27,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: JustAnOrange, 2023\n"
"Last-Translator: ludo thorn, 2025\n"
"Language-Team: Italian (Italy) (http://app.transifex.com/bgk/vba-m/language/it_IT/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -2715,7 +2716,7 @@ msgstr "Impostazioni Game Boy Advance"
#: xrc/GameBoyAdvanceConfig.xrc:21
msgid "Save type:"
msgstr ""
msgstr "Tipo di salvataggio"
#: xrc/GameBoyAdvanceConfig.xrc:27 xrc/GameBoyAdvanceConfig.xrc:199
#: xrc/GameBoyConfig.xrc:29 xrc/GameBoyConfig.xrc:59
@ -2764,7 +2765,7 @@ msgstr ""
#: xrc/GameBoyAdvanceConfig.xrc:115
msgid "Current BIOS file:"
msgstr ""
msgstr "File BIOS attuale:"
#: xrc/GameBoyAdvanceConfig.xrc:136 xrc/GameBoyConfig.xrc:168
msgid "Boot ROM"
@ -2818,7 +2819,7 @@ msgstr "Impostazioni speciali per questo gioco"
#: xrc/GameBoyConfig.xrc:4
msgid "Game Boy settings"
msgstr ""
msgstr "Impostazioni Game Boy"
#: xrc/GameBoyConfig.xrc:20
msgid "Emulated &system:"
@ -3330,7 +3331,7 @@ msgstr "&Speed hack"
#: xrc/MainMenu.xrc:310 xrc/MainMenu.xrc:316 xrc/MainMenu.xrc:383
#: xrc/MainMenu.xrc:417
msgid "&Configure..."
msgstr ""
msgstr "&Configura..."
#: xrc/MainMenu.xrc:314
msgid "&Video"
@ -3414,7 +3415,7 @@ msgstr "&Attiva suono"
#: xrc/MainMenu.xrc:397
msgid "&Game Boy Advance sound interpolation"
msgstr ""
msgstr "&Game Boy Advance interpolazione suono"
#: xrc/MainMenu.xrc:402
msgid "&Game Boy sound enhancement"

View File

@ -7,6 +7,7 @@
# Giovanni Schiano-Moriello, 2022
# Hinaloe <hina@hinaloe.net>, 2017
# Kuso Bully <aaadsaaads@yahoo.co.jp>, 2018
# Lanta Liz, 2025
# Mach555 <aimmasayukitone@yahoo.co.jp>, 2015
# Mutuda Katuo <afetser@gmail.com>, 2017
# Okubo Shohei <stream.larn3@gmail.com>, 2021
@ -18,7 +19,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: 田中康陽, 2022\n"
"Last-Translator: Lanta Liz, 2025\n"
"Language-Team: Japanese (http://app.transifex.com/bgk/vba-m/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -28,7 +29,7 @@ msgstr ""
#: audio/internal/openal.cpp:188
msgid "OpenAL: Failed to open audio device"
msgstr ""
msgstr "OpenAL: オーディオデバイスを開けませんでした"
#: audio/internal/openal.cpp:386 audio/internal/faudio.cpp:492
#: audio/internal/xaudio2.cpp:577
@ -41,7 +42,7 @@ msgid ""
"(*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game"
" Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "ゲームボーイアドバンスのファイル\n(*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game Boy Files (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:144
msgid "Open ROM file"
@ -51,7 +52,7 @@ msgstr "ROMファイルを開く"
msgid ""
"Game Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "ゲームボーイのファイル\n(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:171
msgid "Open GB ROM file"
@ -61,7 +62,7 @@ msgstr "ゲームボーイのROMファイルを開く"
msgid ""
"Game Boy Color Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "ゲームボーイカラーのファイル(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:198
msgid "Open GBC ROM file"
@ -73,7 +74,7 @@ msgstr "ドットコードファイルを選択"
#: cmdevents.cpp:365 cmdevents.cpp:387
msgid "E-Reader Dot Code (*.bin;*.raw)|*.bin;*.raw"
msgstr ""
msgstr "E-Reader Dot Code (*.bin;*.raw)|*.bin;*.raw"
#: cmdevents.cpp:406 cmdevents.cpp:601
msgid "Select battery file"
@ -87,7 +88,7 @@ msgstr "バッテリーファイル (*.sav) | *. sav|フラッシュセーブフ
msgid ""
"Importing a battery file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "バッテリー ファイルを読み込むと、保存したゲームがすべて消去されます (次回の書き込み後、完全に消去されます)続行しますか?"
#: cmdevents.cpp:416 cmdevents.cpp:444 cmdevents.cpp:564
msgid "Confirm import"
@ -109,17 +110,17 @@ msgstr "コードファイルを選択"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.spc;*.xpc)|*.spc;*.xpc"
msgstr ""
msgstr "ゲームシャークのコードファイル (*.spc;*.xpc)|*.spc;*.xpc"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.gcf)|*.gcf"
msgstr ""
msgstr "ゲームシャークのコードファイル(*.gcf)|*.gcf"
#: cmdevents.cpp:443
msgid ""
"Importing a code file will replace any loaded cheats. Do you want to "
"continue?"
msgstr ""
msgstr "コード ファイルを読み込むと、読み込まれたチートが置き換えられます。続行しますか?"
#: cmdevents.cpp:460
#, c-format
@ -149,17 +150,17 @@ msgstr "スナップショットファイルを選択"
msgid ""
"Game Shark & PAC Snapshots (*.sps;*.xps)|*.sps;*.xps|Game Shark SP Snapshots"
" (*.gsv)|*.gsv"
msgstr ""
msgstr "ゲームシャーク & PAC のスナップショット (*.sps;*.xps)|*.sps;*.xps|Game Shark SP Snapshots (*.gsv)|*.gsv"
#: cmdevents.cpp:554
msgid "Game Boy Snapshot (*.gbs)|*.gbs"
msgstr ""
msgstr "ゲームボーイのスナップショット(*.gbs)|*.gbs"
#: cmdevents.cpp:563
msgid ""
"Importing a snapshot file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "スナップショット ファイルをインポートすると、保存されたゲームはすべて消去されます (次回の書き込み後には永久に消去されます)。続行しますか?"
#: cmdevents.cpp:588
#, c-format

View File

@ -32,6 +32,7 @@
# Mateus, 2020
# Mateus Santos <sonicheats@gmail.com>, 2017
# Mateus, 2020
# Mauro Sokrates, 2025
msgid ""
msgstr ""
"Project-Id-Version: VBA-M\n"

View File

@ -4,6 +4,7 @@
#
# Translators:
# Claes-Göran Nydahl <goldug@gmail.com>, 2019
# Daniel Nylander <po@danielnylander.se>, 2025
# 59031d6847a58cccc64d8da23d16ff59_48f0fae, 2015
# [deleted], 2015
# Sebastian Rasmussen <sebras@gmail.com>, 2020,2022
@ -17,7 +18,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: Sebastian Rasmussen <sebras@gmail.com>, 2020,2022\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
"Language-Team: Swedish (http://app.transifex.com/bgk/vba-m/language/sv/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -27,7 +28,7 @@ msgstr ""
#: audio/internal/openal.cpp:188
msgid "OpenAL: Failed to open audio device"
msgstr ""
msgstr "OpenAL: Misslyckades med att öppna ljudenhet"
#: audio/internal/openal.cpp:386 audio/internal/faudio.cpp:492
#: audio/internal/xaudio2.cpp:577
@ -40,39 +41,39 @@ msgid ""
"(*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game"
" Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Game Boy Advance-filer (*.agb;*.gba;*.bin;*.elf;*.mb;*.zip;*.7z;*.rar)|*.agb;*.gba;*.bin;*.elf;*.mb;*.agb.gz;*.gba.gz;*.bin.gz;*.elf.gz;*.mb.gz;*.agb.z;*.gba.z;*.bin.z;*.elf.z;*.mb.z;*.zip;*.7z;*.rar|Game Boy-filer (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:144
msgid "Open ROM file"
msgstr "Öppna ROM fil"
msgstr "Öppna ROM-fil"
#: cmdevents.cpp:165
msgid ""
"Game Boy Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Game Boy-filer (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:171
msgid "Open GB ROM file"
msgstr "Öppna GB ROM fil"
msgstr "Öppna GB ROM-fil"
#: cmdevents.cpp:192
msgid ""
"Game Boy Color Files "
"(*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
msgstr ""
msgstr "Game Boy Color-filer (*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.zip;*.7z;*.rar)|*.dmg;*.gb;*.gbc;*.cgb;*.sgb;*.dmg.gz;*.gb.gz;*.gbc.gz;*.cgb.gz;*.sgb.gz;*.dmg.z;*.gb.z;*.gbc.z;*.cgb.z;*.sgb.z;*.zip;*.7z;*.rar|"
#: cmdevents.cpp:198
msgid "Open GBC ROM file"
msgstr "Öppna GBC ROM fil"
msgstr "Öppna GBC ROM-fil"
#: cmdevents.cpp:363 cmdevents.cpp:385
msgid "Select Dot Code file"
msgstr "Välj Dot Code fil"
msgstr "Välj Dot Code-fil"
#: cmdevents.cpp:365 cmdevents.cpp:387
msgid "E-Reader Dot Code (*.bin;*.raw)|*.bin;*.raw"
msgstr ""
msgstr "E-Reader-punktkod (*.bin;*.raw)|*.bin;*.raw"
#: cmdevents.cpp:406 cmdevents.cpp:601
msgid "Select battery file"
@ -86,7 +87,7 @@ msgstr "Batterifil (*.sav)|*.sav|Flash save (*.dat)|*.dat"
msgid ""
"Importing a battery file will erase any saved games (permanently after the "
"next write). Do you want to continue?"
msgstr ""
msgstr "Om du importerar en batterifil raderas alla sparade spel (permanent efter nästa skrivning). Vill du fortsätta?"
#: cmdevents.cpp:416 cmdevents.cpp:444 cmdevents.cpp:564
msgid "Confirm import"
@ -95,12 +96,12 @@ msgstr "Bekräfta import"
#: cmdevents.cpp:422 panel.cpp:493
#, c-format
msgid "Loaded battery %s"
msgstr "Laddade batteri %s"
msgstr "Läste in batteri %s"
#: cmdevents.cpp:424
#, c-format
msgid "Error loading battery %s"
msgstr "Fel vid laddning av batteri %s"
msgstr "Fel vid inläsning av batteri %s"
#: cmdevents.cpp:433
msgid "Select code file"
@ -108,22 +109,22 @@ msgstr "Välj kodfil"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.spc;*.xpc)|*.spc;*.xpc"
msgstr ""
msgstr "Game Shark-kodfil (*.spc;*.xpc)|*.spc;*.xpc"
#: cmdevents.cpp:434
msgid "Game Shark Code File (*.gcf)|*.gcf"
msgstr ""
msgstr "Game Shark-kodfil (*.gcf)|*.gcf"
#: cmdevents.cpp:443
msgid ""
"Importing a code file will replace any loaded cheats. Do you want to "
"continue?"
msgstr ""
msgstr "Att importera en kodfil kommer att ersätta alla inlästa fusk. Vill du fortsätta?"
#: cmdevents.cpp:460
#, c-format
msgid "Cannot open file %s"
msgstr "Kan inte öppna fil %s"
msgstr "Kan inte öppna filen %s"
#: cmdevents.cpp:470
#, c-format
@ -133,12 +134,12 @@ msgstr "Kodfilen stöds inte %s"
#: cmdevents.cpp:540
#, c-format
msgid "Loaded code file %s"
msgstr "Laddade kodfil %s"
msgstr "Läste in kodfilen %s"
#: cmdevents.cpp:542
#, c-format
msgid "Error loading code file %s"
msgstr "Fel vid laddning av kodfil %s"
msgstr "Fel vid inläsning av kodfilen %s"
#: cmdevents.cpp:553 cmdevents.cpp:629
msgid "Select snapshot file"
@ -163,12 +164,12 @@ msgstr ""
#: cmdevents.cpp:588
#, c-format
msgid "Loaded snapshot file %s"
msgstr "Laddade ögonblicksfil %s"
msgstr "Läste in ögonblicksfilen %s"
#: cmdevents.cpp:590
#, c-format
msgid "Error loading snapshot file %s"
msgstr "Fel vid laddning av ögonblicksfil %s"
msgstr "Fel vid inläsning av ögonblicksfilen %s"
#: cmdevents.cpp:613
#, c-format
@ -190,17 +191,17 @@ msgstr ""
#: cmdevents.cpp:644
msgid "Exported from Visual Boy Advance-M"
msgstr ""
msgstr "Exporterad från Visual Boy Advance-M"
#: cmdevents.cpp:656
#, c-format
msgid "Saved snapshot file %s"
msgstr "Sparade ögonblicksfil %s"
msgstr "Sparade ögonblicksfilen %s"
#: cmdevents.cpp:658
#, c-format
msgid "Error saving snapshot file %s"
msgstr "Fel vid sparandet av ögonblicksfil%s"
msgstr "Fel vid sparandet av ögonblicksfilen %s"
#: cmdevents.cpp:674 cmdevents.cpp:752 cmdevents.cpp:822 cmdevents.cpp:891
#: gfxviewers.cpp:1662 gfxviewers.cpp:1807 viewers.cpp:588 viewers.cpp:802
@ -210,12 +211,12 @@ msgstr "Välj utdatafil"
#: cmdevents.cpp:675 gfxviewers.cpp:1663 gfxviewers.cpp:1808 viewsupt.cpp:1200
msgid "PNG images|*.png|BMP images|*.bmp"
msgstr "PNG bilder|*.png|BMP bilder|*.bmp"
msgstr "PNG bilder|*.png|BMP-bilder|*.bmp"
#: cmdevents.cpp:699 sys.cpp:579
#, c-format
msgid "Wrote snapshot %s"
msgstr "Skrev ögonblicksfil %s"
msgstr "Skrev ögonblicksfilen %s"
#: cmdevents.cpp:720 cmdevents.cpp:790 cmdevents.cpp:859 cmdevents.cpp:925
msgid " files ("
@ -260,7 +261,7 @@ msgstr "Port att vänta på anslutning vid:"
#: cmdevents.cpp:1763
msgid "GDB Connection"
msgstr "GDB anslutning"
msgstr "GDB-anslutning"
#: cmdevents.cpp:1815
#, c-format
@ -281,15 +282,15 @@ msgid ""
"YOUR CONFIGURATION WILL BE DELETED!\n"
"\n"
"Are you sure?"
msgstr ""
msgstr "DIN KONFIGURATION KOMMER ATT TAS BORT!\n\nÄr du säker?"
#: cmdevents.cpp:2201
msgid "FACTORY RESET"
msgstr ""
msgstr "FABRIKSÅTERSTÄLLNING"
#: cmdevents.cpp:2236
msgid "Nintendo Game Boy / Color / Advance emulator."
msgstr ""
msgstr "Nintendo Game Boy / Color / Advance-emulator."
#: cmdevents.cpp:2237
msgid ""
@ -312,7 +313,7 @@ msgid ""
"\n"
"You should have received a copy of the GNU General Public License\n"
"along with this program. If not, see http://www.gnu.org/licenses ."
msgstr ""
msgstr "Detta program är fri programvara: du kan vidaredistribuera det och / eller ändra det enligt villkoren i GNU General Public License som publiceras av Free Software Foundation, antingen version 2 av licensen eller (efter eget val) någon senare version.\n\nDetta program distribueras i hopp om att det kommer att vara användbart, men UTAN NÅGON GARANTI; utan ens den underförstådda garantin om SÄLJBARHET eller LÄMPLIGHET FÖR ETT BESTÄMT SYFTE. Se GNU General Public License för mer information.\n\nDu bör ha fått en kopia av GNU General Public License tillsammans med detta program. Om inte, se http://www.gnu.org/licenses ."
#: cmdevents.cpp:2424
msgid "Cannot use Game Boy BIOS when Colorizer Hack is enabled."
@ -389,7 +390,7 @@ msgstr "Okänd"
#: dialogs/game-maker.cpp:235
msgid "Invalid"
msgstr ""
msgstr "Ogiltig"
#: dialogs/gb-rom-info.cpp:22
msgid "No mapper"
@ -401,15 +402,15 @@ msgstr ""
#: dialogs/gb-rom-info.cpp:68
msgid " + RAM"
msgstr ""
msgstr " + RAM"
#: dialogs/gb-rom-info.cpp:69
msgid " + RTC"
msgstr ""
msgstr " + RTC"
#: dialogs/gb-rom-info.cpp:70
msgid " + Battery"
msgstr ""
msgstr " + Batteri"
#: dialogs/gb-rom-info.cpp:71
msgid " + Rumble"
@ -422,122 +423,122 @@ msgstr ""
#: dialogs/gb-rom-info.cpp:74
#, c-format
msgid "%02X (%s%s%s%s%s%s)"
msgstr ""
msgstr "%02X (%s%s%s%s%s%s)"
#: dialogs/gb-rom-info.cpp:81 dialogs/gb-rom-info.cpp:93
#, c-format
msgid "%02X (Supported)"
msgstr ""
msgstr "%02X (stöds)"
#: dialogs/gb-rom-info.cpp:83 dialogs/gb-rom-info.cpp:91
#, c-format
msgid "%02X (Not supported)"
msgstr ""
msgstr "%02X (stöds inte)"
#: dialogs/gb-rom-info.cpp:95
#, c-format
msgid "%02X (Required)"
msgstr ""
msgstr "%02X (krävs)"
#: dialogs/gb-rom-info.cpp:107 dialogs/gb-rom-info.cpp:141
#, c-format
msgid "%02X (32 KiB)"
msgstr ""
msgstr "%02X (32 KiB)"
#: dialogs/gb-rom-info.cpp:109 dialogs/gb-rom-info.cpp:145
#, c-format
msgid "%02X (64 KiB)"
msgstr ""
msgstr "%02X (64 KiB)"
#: dialogs/gb-rom-info.cpp:111 dialogs/gb-rom-info.cpp:143
#, c-format
msgid "%02X (128 KiB)"
msgstr ""
msgstr "%02X (128 KiB)"
#: dialogs/gb-rom-info.cpp:113
#, c-format
msgid "%02X (256 KiB)"
msgstr ""
msgstr "%02X (256 KiB)"
#: dialogs/gb-rom-info.cpp:115
#, c-format
msgid "%02X (512 KiB)"
msgstr ""
msgstr "%02X (512 KiB)"
#: dialogs/gb-rom-info.cpp:117
#, c-format
msgid "%02X (1 MiB)"
msgstr ""
msgstr "%02X (1 MiB)"
#: dialogs/gb-rom-info.cpp:119
#, c-format
msgid "%02X (2 MiB)"
msgstr ""
msgstr "%02X (2 MiB)"
#: dialogs/gb-rom-info.cpp:121
#, c-format
msgid "%02X (4 MiB)"
msgstr ""
msgstr "%02X (4 MiB)"
#: dialogs/gb-rom-info.cpp:123 dialogs/gb-rom-info.cpp:147
#: dialogs/gb-rom-info.cpp:159
#, c-format
msgid "%02X (Unknown)"
msgstr ""
msgstr "%02X (okänt)"
#: dialogs/gb-rom-info.cpp:131
#, c-format
msgid "%02X (None)"
msgstr ""
msgstr "%02X (ingen)"
#: dialogs/gb-rom-info.cpp:133
#, c-format
msgid "%02X (256 B)"
msgstr ""
msgstr "%02X (256 B)"
#: dialogs/gb-rom-info.cpp:135
#, c-format
msgid "%02X (512 B)"
msgstr ""
msgstr "%02X (512 B)"
#: dialogs/gb-rom-info.cpp:137
#, c-format
msgid "%02X (2 KiB)"
msgstr ""
msgstr "%02X (2 KiB)"
#: dialogs/gb-rom-info.cpp:139
#, c-format
msgid "%02X (8 KiB)"
msgstr ""
msgstr "%02X (8 KiB)"
#: dialogs/gb-rom-info.cpp:155
#, c-format
msgid "%02X (Japan)"
msgstr ""
msgstr "%02X (Japan)"
#: dialogs/gb-rom-info.cpp:157
#, c-format
msgid "%02X (World)"
msgstr ""
msgstr "%02X (Världen)"
#: dialogs/gb-rom-info.cpp:201
#, c-format
msgid "%02X (Actual: %02X)"
msgstr ""
msgstr "%02X (Faktisk: %02X)"
#: dialogs/gb-rom-info.cpp:204
#, c-format
msgid "%04X (Actual: %04X)"
msgstr ""
msgstr "%04X (Faktisk: %04X)"
#: dialogs/sound-config.cpp:251
#, c-format
msgid "%d frame = %.2f ms"
msgstr ""
msgstr "%d bildruta = %.2f ms"
#: extra-translations.cpp:13
msgid "&Apply"
msgstr ""
msgstr "&Tillämpa"
#: extra-translations.cpp:14
msgid "Artists"
@ -545,23 +546,23 @@ msgstr ""
#: extra-translations.cpp:15
msgid "Cancel"
msgstr ""
msgstr "Avbryt"
#: extra-translations.cpp:16
msgid "Close"
msgstr ""
msgstr "Stäng"
#: extra-translations.cpp:17
msgid "Developers"
msgstr ""
msgstr "Utvecklare"
#: extra-translations.cpp:18
msgid "License"
msgstr ""
msgstr "Licens"
#: extra-translations.cpp:19
msgid "OK"
msgstr ""
msgstr "Ok"
#: gfxviewers.cpp:1202
msgid "Select output file and type"
@ -596,7 +597,7 @@ msgstr "Väntar på klienter..."
#: guiinit.cpp:147
#, c-format
msgid "Server IP address is: %s\n"
msgstr "Serverns IP adress är: %s\n"
msgstr "Serverns IP-adress är: %s\n"
#: guiinit.cpp:149
msgid "Waiting for connection..."
@ -808,7 +809,7 @@ msgstr ""
#: panel.cpp:1022
#, c-format
msgid "Valid mode: %d x %d - %d @ %d"
msgstr ""
msgstr "Giltigt läge: %d x %d - %d @ %d"
#: panel.cpp:1030
#, c-format
@ -919,7 +920,7 @@ msgstr "Fel i videoinspelning (%s); avbryter"
#: panel.cpp:2698
#, c-format
msgid "Volume: %d %%"
msgstr ""
msgstr "Volym: %d %%"
#: sys.cpp:205 sys.cpp:266
msgid "No game in progress to record"
@ -954,7 +955,7 @@ msgstr "Uppspelning slutade"
#: sys.cpp:458
#, c-format
msgid "%d %% (%d, %d fps)"
msgstr ""
msgstr "%d %% (%d, %d bilder/s)"
#: sys.cpp:899 xrc/GBPrinter.xrc:65
msgid "&Discard"
@ -1005,15 +1006,15 @@ msgstr "Välj minnesdumpsfil"
#: viewsupt.cpp:789
msgid "Red:"
msgstr ""
msgstr "Röd:"
#: viewsupt.cpp:798
msgid "Green:"
msgstr ""
msgstr "Grön:"
#: viewsupt.cpp:807
msgid "Blue:"
msgstr ""
msgstr "Blå:"
#: viewsupt.h:63
#, c-format
@ -1210,7 +1211,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/command.cpp:33
msgid "GameShark"
msgstr ""
msgstr "GameShark"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/command.cpp:107
#, c-format
@ -1378,7 +1379,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:461
msgid "Enable status bar"
msgstr ""
msgstr "Aktivera statusrad"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:462
msgid "INI file version (DO NOT MODIFY)"
@ -1601,7 +1602,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:563
msgid "Number of sound buffers"
msgstr ""
msgstr "Antal ljudbuffertar"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:564
msgid "Bit mask of sound channels to enable"
@ -1649,7 +1650,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:576
msgid "Sound volume (%)"
msgstr ""
msgstr "Ljudvolym (%)"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:645
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:665
@ -1781,31 +1782,31 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:54
msgid "Volume Mute"
msgstr ""
msgstr "Volym tyst"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:55
msgid "Volume Down"
msgstr ""
msgstr "Sänk volym"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:56
msgid "Volume Up"
msgstr ""
msgstr "Höj volym"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:57
msgid "Next Track"
msgstr ""
msgstr "Nästa spår"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:58
msgid "Previous Track"
msgstr ""
msgstr "Föregående spår"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:59
msgid "Stop"
msgstr ""
msgstr "Stoppa"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:60
msgid "Play/Pause"
msgstr ""
msgstr "Spela upp/Paus"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:93
msgid "Alt+"
@ -1845,7 +1846,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:272
#, c-format
msgid "%s: Button %d"
msgstr ""
msgstr "%s: Knapp %d"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/user-input.cpp:274
#, c-format
@ -1975,7 +1976,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1678
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1711
msgid "Network error."
msgstr ""
msgstr "Nätverksfel."
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1110
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1687
@ -1986,7 +1987,7 @@ msgstr ""
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1124
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1701
msgid "All players connected"
msgstr ""
msgstr "Alla spelare anslutna"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1145
#: /home/rkitover/source/repos/vbam-tx-pulls/src/core/gba/gbaLink.cpp:1723
@ -2477,7 +2478,7 @@ msgstr "ROM-information"
#: xrc/GBColorPrefPanel.xrc:9
msgid "Custom"
msgstr ""
msgstr "Anpassad"
#: xrc/GBColorPrefPanel.xrc:10 xrc/JoyPanel.xrc:247
msgid "Standard"
@ -2731,11 +2732,11 @@ msgstr ""
#: xrc/GameBoyAdvanceConfig.xrc:49 xrc/GameBoyAdvanceConfig.xrc:221
msgid "64 K"
msgstr ""
msgstr "64 K"
#: xrc/GameBoyAdvanceConfig.xrc:50 xrc/GameBoyAdvanceConfig.xrc:222
msgid "128 K"
msgstr ""
msgstr "128 K"
#: xrc/GameBoyAdvanceConfig.xrc:64
msgid "Detect Now"
@ -2751,7 +2752,7 @@ msgstr "Sparningstyp"
#: xrc/GameBoyAdvanceConfig.xrc:92
msgid "BIOS file:"
msgstr ""
msgstr "BIOS-fil:"
#: xrc/GameBoyAdvanceConfig.xrc:115
msgid "Current BIOS file:"
@ -3088,7 +3089,7 @@ msgstr "&Läs automatiskt in senaste"
#: xrc/MainMenu.xrc:89
msgid "From &File..."
msgstr ""
msgstr "Från &fil..."
#: xrc/MainMenu.xrc:93
msgid "Do not change &battery save"
@ -3152,7 +3153,7 @@ msgstr "1&0"
#: xrc/MainMenu.xrc:145
msgid "To &File..."
msgstr ""
msgstr "Till &fil..."
#: xrc/MainMenu.xrc:147
msgid "&Save state"
@ -3292,7 +3293,7 @@ msgstr "&Länk"
#: xrc/MainMenu.xrc:272
msgid "Start &Network Link..."
msgstr ""
msgstr "Starta &nätverkslänk..."
#: xrc/MainMenu.xrc:277
msgid "&Nothing"
@ -3321,7 +3322,7 @@ msgstr "&Hastighetshack"
#: xrc/MainMenu.xrc:310 xrc/MainMenu.xrc:316 xrc/MainMenu.xrc:383
#: xrc/MainMenu.xrc:417
msgid "&Configure..."
msgstr ""
msgstr "&Konfigurera..."
#: xrc/MainMenu.xrc:314
msgid "&Video"
@ -3457,7 +3458,7 @@ msgstr "&R"
#: xrc/MainMenu.xrc:494 xrc/MainMenu.xrc:517
msgid "Configure..."
msgstr ""
msgstr "Konfigurera..."
#: xrc/MainMenu.xrc:498
msgid "&Real-time clock"
@ -3505,7 +3506,7 @@ msgstr ""
#: xrc/MainMenu.xrc:555
msgid "&General..."
msgstr ""
msgstr "A&llmänt..."
#: xrc/MainMenu.xrc:558
msgid "&Speedup / Turbo..."
@ -3513,7 +3514,7 @@ msgstr ""
#: xrc/MainMenu.xrc:561
msgid "D&irectories..."
msgstr ""
msgstr "Ka&taloger..."
#: xrc/MainMenu.xrc:564
msgid "&Key Shortcuts..."
@ -3521,7 +3522,7 @@ msgstr ""
#: xrc/MainMenu.xrc:567
msgid "UI Settings"
msgstr ""
msgstr "Gränssnittsinställningar"
#: xrc/MainMenu.xrc:569
msgid "Enable &Status bar"
@ -3545,11 +3546,11 @@ msgstr "&Fusk"
#: xrc/MainMenu.xrc:587
msgid "List &cheats..."
msgstr ""
msgstr "Lista fu&sk..."
#: xrc/MainMenu.xrc:590
msgid "Find c&heat..."
msgstr ""
msgstr "Hitta f&usk..."
#: xrc/MainMenu.xrc:594
msgid "A&utomatically save / load cheats"
@ -3757,7 +3758,7 @@ msgstr "Spelare:"
#: xrc/NetLink.xrc:83
msgid "2"
msgstr ""
msgstr "2"
#: xrc/NetLink.xrc:107
msgid "Server:"
@ -3789,7 +3790,7 @@ msgstr "Ljudinställningar"
#: xrc/SoundConfig.xrc:18
msgid "Volume:"
msgstr ""
msgstr "Volym:"
#: xrc/SoundConfig.xrc:36
msgid "Mute"
@ -3801,7 +3802,7 @@ msgstr "Maximal"
#: xrc/SoundConfig.xrc:73
msgid "Sample rate:"
msgstr ""
msgstr "Samplingsfrekvens:"
#: xrc/SoundConfig.xrc:79
msgid "48 KHz"

View File

@ -4,6 +4,7 @@
#
# Translators:
# abc Def <hdogan1974@gmail.com>, 2020
# adalet Mustafa, 2025
# Ali Ozderya <ozozderya@gmail.com>, 2015,2017
# boran roni, 2021
# Justice League <denizden788@gmail.com>, 2020
@ -18,7 +19,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: Sinan H., 2016,2018,2022,2024\n"
"Last-Translator: adalet Mustafa, 2025\n"
"Language-Team: Turkish (http://app.transifex.com/bgk/vba-m/language/tr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@
# horcus Yuan <1257425379@qq.com>, 2019
# pngai <pngai@ymail.com>, 2016
# Rythm Tse <ksusix@gmail.com>, 2016
# Weiran Wu <wwrustc@mail.ustc.edu.cn>, 2024
# Weiran Wu <wwrustc@mail.ustc.edu.cn>, 2024-2025
# wr superboy, 2023
# Xuan Zheng, 2024
# Xuntao Chi <1139954766@qq.com>, 2019
@ -26,7 +26,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-07-05 20:00+0000\n"
"PO-Revision-Date: 2011-12-03 19:42+0000\n"
"Last-Translator: 王晨旭 <wcxu21@126.com>, 2021\n"
"Last-Translator: Weiran Wu <wwrustc@mail.ustc.edu.cn>, 2024-2025\n"
"Language-Team: Chinese (China) (http://app.transifex.com/bgk/vba-m/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -1526,19 +1526,19 @@ msgstr "加载状态时不覆盖原生 (电池) 存档"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:526
msgid "Throttle game speed, even when accelerated (0-450 %, 0 = no throttle)"
msgstr "阀门加快游戏速度即使已经在加速时0-450 %0 = 无阀门"
msgstr "限制游戏速度包括加速后的0-450 %0 = 无限制"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:529
msgid "Set throttle for speedup key (0-3000 %, 0 = no throttle)"
msgstr "设置加速键的阀门值0-3000 %0 = 无阀门"
msgstr "设置加速键的限制0-3000 %0 = 无限制"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:531
msgid "Number of frames to skip with speedup (instead of speedup throttle)"
msgstr "加速时跳过的帧数(而不是阀门加速)"
msgstr "加速时跳过的帧数(而不是加速限制"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:534
msgid "Use frame skip for speedup throttle"
msgstr "使用跳帧来阀门加速"
msgstr "使用跳帧来限制加速"
#: /home/rkitover/source/repos/vbam-tx-pulls/src/wx/config/internal/option-internal.cpp:536
msgid "Mute sound during speedup"
@ -2898,7 +2898,7 @@ msgstr "秒 (0-600); 0 = 禁用"
#: xrc/GeneralConfig.xrc:78
msgid "&Throttle"
msgstr "阀门(&T)"
msgstr "限速(&T)"
#: xrc/GeneralConfig.xrc:96 xrc/SpeedupConfig.xrc:27
msgid "Percent of normal:"
@ -2906,7 +2906,7 @@ msgstr "正常百分比:"
#: xrc/GeneralConfig.xrc:106
msgid "0 = no throttle"
msgstr "0 = 无阀门"
msgstr "0 = 无限制"
#: xrc/GeneralConfig.xrc:114
msgid "Unlimited"
@ -3085,7 +3085,7 @@ msgstr "保存点代码(&S)..."
#: xrc/MainMenu.xrc:47
msgid "Most &recent"
msgstr "最常用"
msgstr "最常用(&R)"
#: xrc/MainMenu.xrc:50
msgid "Load current state slot"
@ -3285,7 +3285,7 @@ msgstr "自动 IPS/UPS/IPF 补丁(&A)"
#: xrc/MainMenu.xrc:259
msgid "&Pause when inactive"
msgstr "非活状态时暂停(&P)"
msgstr "非活状态时暂停(&P)"
#: xrc/MainMenu.xrc:264
msgid "&Reset"
@ -3570,7 +3570,7 @@ msgstr "启用金手指(&E)"
#: xrc/MainMenu.xrc:605
msgid "&Break into GDB"
msgstr "入 GDB(&B)"
msgstr "中断进入 GDB(&B)"
#: xrc/MainMenu.xrc:609
msgid "&Configure port..."
@ -3578,7 +3578,7 @@ msgstr "配置端口(&C)..."
#: xrc/MainMenu.xrc:612
msgid "&Break on load"
msgstr "加载时切入(&B)"
msgstr "加载时中断(&B)"
#: xrc/MainMenu.xrc:617
msgid "&Disconnect"
@ -3846,7 +3846,7 @@ msgstr "启用硬件加速"
#: xrc/SoundConfig.xrc:184
msgid "Number of sound buffers:"
msgstr " 声音缓冲区数:"
msgstr "声音缓冲区数:"
#: xrc/SoundConfig.xrc:192
msgid "Advanced"
@ -3878,7 +3878,7 @@ msgstr "声音过滤"
#: xrc/TileViewer.xrc:4
msgid "Tile Viewer"
msgstr "片查看器"
msgstr "片查看器"
#: xrc/TileViewer.xrc:24
msgid "Colors"
@ -3890,7 +3890,7 @@ msgstr "加速/超频设置"
#: xrc/SpeedupConfig.xrc:9
msgid "Speedup Throttle"
msgstr "阀门加速"
msgstr "加速限制"
#: xrc/SpeedupConfig.xrc:54
msgid "Frame skip"

View File

@ -1,5 +1,13 @@
add_library(vbam-components-filters OBJECT)
unset(extra_src)
if(WINXP)
list(APPEND extra_src
${CMAKE_SOURCE_DIR}/third_party/quake3-sqrt/quake3-sqrt.h
)
target_include_directories(vbam-components-filters PRIVATE ${CMAKE_SOURCE_DIR}/third_party/quake3-sqrt)
endif()
target_sources(vbam-components-filters
PRIVATE
internal/2xSaI.cpp
@ -17,6 +25,7 @@ target_sources(vbam-components-filters
internal/xBRZ/xbrz_config.h
internal/xBRZ/xbrz_tools.h
internal/xbrzfilter.cpp
${extra_src}
PUBLIC
filters.h

View File

@ -21,6 +21,10 @@
#include <cmath> //std::sqrt
#include "xbrz_tools.h"
#ifdef WINXP
#include "quake3-sqrt.h"
#endif
// some gcc versions lie about having this C++17 feature
#define static_assert(x) static_assert(x, "assertion failed")
@ -66,7 +70,9 @@ uint32_t gradientARGB(uint32_t pixFront, uint32_t pixBack) //find intermediate c
inline double fastSqrt(double n)
{
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__))
#ifdef WINXP
return quake3_sqrt((float)n);
#elif (defined(__GNUC__) || defined(__clang__)) && (defined(__x86_64__) || defined(__i386__))
__asm__ ("fsqrt" : "+t" (n));
return n;
#elif defined(_MSC_VER) && defined(_M_IX86)

View File

@ -70,7 +70,7 @@ extern struct CoreOptions {
int skipSaveGameBattery = 1;
int skipSaveGameCheats = 0;
int useBios = 0;
int winGbPrinterEnabled = 1;
int gbPrinterEnabled = 0;
uint32_t speedup_throttle = 100;
uint32_t speedup_frame_skip = 9;
uint32_t throttle = 100;

View File

@ -1416,7 +1416,7 @@ void gbWriteMemory(uint16_t address, uint8_t value)
EmuReseted = false;
gbMemory[0xff02] = value;
if (gbSerialOn && (GetLinkMode() == LINK_GAMEBOY_IPC || GetLinkMode() == LINK_GAMEBOY_SOCKET
|| GetLinkMode() == LINK_DISCONNECTED || coreOptions.winGbPrinterEnabled)) {
|| GetLinkMode() == LINK_DISCONNECTED || coreOptions.gbPrinterEnabled)) {
gbSerialTicks = GBSERIAL_CLOCK_TICKS;
@ -2969,8 +2969,13 @@ void gbReset()
inBios = true;
} else if (gbHardware & 0xa) {
// Set compatibility mode if it is a DMG ROM.
const uint8_t gbcFlag = g_gbCartData.SupportsCGB() ? 0x80 : 0x00;
gbMemory[0xff6c] = 0xfe | gbcFlag;
if (g_gbCartData.SupportsCGB()) {
// OPRI with bit 0 set to 0 = CGB mode.
gbMemory[0xff6c] = 0xfe;
} else {
// OPRI with bit 0 set to 1 = DMG mode.
gbMemory[0xff6c] = 0xff;
}
}
gbLine99Ticks = 1;

View File

@ -481,7 +481,7 @@ void gbaUpdateRomSize(int size)
if (size > romSize) {
romSize = size;
uint8_t* tmp = (uint8_t*)realloc(g_rom, SIZE_ROM);
uint8_t* tmp = (uint8_t*)realloc(g_rom, romSize);
g_rom = tmp;
uint16_t* temp = (uint16_t*)(g_rom + ((romSize + 1) & ~1));

View File

@ -1822,6 +1822,16 @@ static INSN_REGPARM void thumbE0(uint32_t opcode)
busPrefetchCount = 0;
}
static INSN_REGPARM void thumbE8(uint32_t opcode)
{
#ifdef GBA_LOGGING
// TODO: This is (erroneously) used by some Wii U VC ROMs. We should have a configuration
// toggle to enable the correct hardware behavior, which would be to call CPUUndefinedException.
if (systemVerbose & VERBOSE_UNDEFINED)
log("Undefined Wii U THUMB instruction %04x at %08x (ignored)\n", opcode, armNextPC - 2);
#endif
}
// BLL #offset (forward)
static INSN_REGPARM void thumbF0(uint32_t opcode)
{
@ -1979,7 +1989,7 @@ static insnfunc_t thumbInsnTable[1024] = {
thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0,
thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0,
thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0, thumbE0,
thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, // E8
thumbE8, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, // E8
thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI,
thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI,
thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI, thumbUI,

View File

@ -41,17 +41,22 @@
#define snprintf _snprintf
#endif
#ifdef UPDATE_REG
#undef UPDATE_REG
#endif
#define UPDATE_REG(address, value) WRITE16LE(((uint16_t*)&g_ioMem[address]), value)
static int vbaid = 0;
const char* MakeInstanceFilename(const char* Input)
{
if (vbaid == 0)
if (vbaid == 0) {
return Input;
}
static char* result = NULL;
if (result != NULL)
if (result != NULL) {
free(result);
}
result = (char*)malloc(strlen(Input) + 3);
char* p = strrchr((char*)Input, '.');
@ -270,7 +275,7 @@ class RFUServer {
public:
sf::TcpSocket tcpsocket[5];
sf::IpAddress udpaddr[5];
sf::IpAddress udpaddr[5] = { sf::IpAddress{0}, sf::IpAddress{0}, sf::IpAddress{0}, sf::IpAddress{0}, sf::IpAddress{0} };
RFUServer(void);
sf::Packet& Serialize(sf::Packet& packet, int slave);
void DeSerialize(sf::Packet& packet, int slave);
@ -283,7 +288,7 @@ class RFUClient {
int numbytes;
public:
sf::IpAddress serveraddr;
sf::IpAddress serveraddr{0};
unsigned short serverport;
bool transferring;
RFUClient(void);
@ -392,7 +397,7 @@ enum {
typedef struct {
sf::TcpSocket tcpsocket;
sf::TcpListener tcplistener;
int numslaves;
uint16_t numslaves;
int connectedSlaves;
int type;
bool server;
@ -412,7 +417,7 @@ class CableServer {
public:
sf::TcpSocket tcpsocket[4];
sf::IpAddress udpaddr[4];
sf::IpAddress udpaddr[4] = { sf::IpAddress{0}, sf::IpAddress{0}, sf::IpAddress{0}, sf::IpAddress{0} };
CableServer(void);
void Send(void);
void Recv(void);
@ -430,7 +435,7 @@ class CableClient {
int numbytes;
public:
sf::IpAddress serveraddr;
sf::IpAddress serveraddr{0};
unsigned short serverport;
bool transferring;
CableClient(void);
@ -520,33 +525,48 @@ LinkMode GetLinkMode()
return LINK_DISCONNECTED;
}
void GetLinkServerHost(char* const host, size_t size)
bool GetLinkServerHost(char* const host, size_t size)
{
if (host == NULL || size == 0)
return;
if (host == NULL || size == 0) {
return false;
}
host[0] = '\0';
if (linkDriver && linkDriver->mode == LINK_GAMECUBE_DOLPHIN)
if (linkDriver && linkDriver->mode == LINK_GAMECUBE_DOLPHIN) {
strncpy(host, joybusHostAddr.toString().c_str(), size);
else if (lanlink.server) {
if (IP_LINK_BIND_ADDRESS == "*")
strncpy(host, sf::IpAddress::getLocalAddress().toString().c_str(), size);
else
} else if (lanlink.server) {
if (IP_LINK_BIND_ADDRESS == "*") {
auto local_addr = sf::IpAddress::getLocalAddress();
if (local_addr) {
strncpy(host, local_addr.value().toString().c_str(), size);
} else {
return false;
}
} else {
strncpy(host, IP_LINK_BIND_ADDRESS.c_str(), size);
}
}
else
else {
strncpy(host, lc.serveraddr.toString().c_str(), size);
}
return true;
}
bool SetLinkServerHost(const char* host)
{
sf::IpAddress addr = sf::IpAddress(host);
sf::IpAddress addr{0};
auto resolved = sf::IpAddress::resolve(host);
if (!resolved) {
return false;
}
addr = resolved.value();
lc.serveraddr = addr;
joybusHostAddr = addr;
return addr != sf::IpAddress::None;
return true;
}
int GetLinkPlayerId()
@ -1044,11 +1064,13 @@ static ConnectionState InitSocket()
{
linkid = 0;
for (int i = 0; i < 4; i++)
for (int i = 0; i < 4; i++) {
cable_data[i] = 0xffff;
}
for (int i = 0; i < 4; i++)
for (int i = 0; i < 4; i++) {
cable_gb_data[i] = 0xff;
}
if (lanlink.server) {
lanlink.connectedSlaves = 0;
@ -1057,26 +1079,33 @@ static ConnectionState InitSocket()
// too bad Listen() doesn't take an address as well
// then again, old code used INADDR_ANY anyway
sf::IpAddress bind_ip = IP_LINK_BIND_ADDRESS == "*" ? sf::IpAddress::Any : IP_LINK_BIND_ADDRESS;
sf::IpAddress bind_ip{0};
if (lanlink.tcplistener.listen(IP_LINK_PORT, bind_ip) == sf::Socket::Error)
if (IP_LINK_BIND_ADDRESS != "*") {
auto resolved = sf::IpAddress::resolve(IP_LINK_BIND_ADDRESS);
if (resolved) {
bind_ip = resolved.value();
} else {
return LINK_ERROR;
}
}
if (lanlink.tcplistener.listen(IP_LINK_PORT, bind_ip) == sf::Socket::Status::Error) {
// Note: old code closed socket & retried once on bind failure
return LINK_ERROR; // FIXME: error code?
else
} else {
return LINK_NEEDS_UPDATE;
}
} else {
lc.serverport = IP_LINK_PORT;
if (lc.serveraddr == sf::IpAddress::None) {
lanlink.tcpsocket.setBlocking(false);
sf::Socket::Status status = lanlink.tcpsocket.connect(lc.serveraddr, lc.serverport);
if (status == sf::Socket::Status::Error || status == sf::Socket::Status::Disconnected) {
return LINK_ERROR;
} else {
lanlink.tcpsocket.setBlocking(false);
sf::Socket::Status status = lanlink.tcpsocket.connect(lc.serveraddr, lc.serverport);
if (status == sf::Socket::Error || status == sf::Socket::Disconnected)
return LINK_ERROR;
else
return LINK_NEEDS_UPDATE;
return LINK_NEEDS_UPDATE;
}
}
}
@ -1090,11 +1119,11 @@ static ConnectionState ConnectUpdateSocket(char* const message, size_t size)
fdset.add(lanlink.tcplistener);
if (fdset.wait(sf::milliseconds(150))) {
int nextSlave = lanlink.connectedSlaves + 1;
uint16_t nextSlave = lanlink.connectedSlaves + 1;
sf::Socket::Status st = lanlink.tcplistener.accept(ls.tcpsocket[nextSlave]);
if (st == sf::Socket::Error) {
if (st == sf::Socket::Status::Error) {
for (int j = 1; j < nextSlave; j++)
ls.tcpsocket[j].disconnect();
@ -1102,8 +1131,7 @@ static ConnectionState ConnectUpdateSocket(char* const message, size_t size)
newState = LINK_ERROR;
} else {
sf::Packet packet;
packet << static_cast<sf::Uint16>(nextSlave)
<< static_cast<sf::Uint16>(lanlink.numslaves);
packet << nextSlave << lanlink.numslaves;
ls.tcpsocket[nextSlave].send(packet);
@ -1129,13 +1157,13 @@ static ConnectionState ConnectUpdateSocket(char* const message, size_t size)
sf::Packet packet;
sf::Socket::Status status = lanlink.tcpsocket.receive(packet);
if (status == sf::Socket::Error || status == sf::Socket::Disconnected) {
if (status == sf::Socket::Status::Error || status == sf::Socket::Status::Disconnected) {
snprintf(message, size, N_("Network error."));
newState = LINK_ERROR;
} else if (status == sf::Socket::Done) {
} else if (status == sf::Socket::Status::Done) {
if (linkid == 0) {
sf::Uint16 receivedId, receivedSlaves;
uint16_t receivedId, receivedSlaves;
packet >> receivedId >> receivedSlaves;
if (packet) {
@ -1540,7 +1568,7 @@ void RFUServer::Recv(void)
sf::Packet packet;
tcpsocket[i + 1].setBlocking(false);
sf::Socket::Status status = tcpsocket[i + 1].receive(packet);
if (status == sf::Socket::Disconnected) {
if (status == sf::Socket::Status::Disconnected) {
char message[30];
sprintf(message, _("Player %d disconnected."), i + 1);
systemScreenMessage(message);
@ -1650,7 +1678,7 @@ void RFUClient::Recv(void)
}
sf::Packet packet;
sf::Socket::Status status = lanlink.tcpsocket.receive(packet);
if (status == sf::Socket::Disconnected) {
if (status == sf::Socket::Status::Disconnected) {
systemScreenMessage(_("Server disconnected."));
CloseLink();
return;
@ -1671,7 +1699,7 @@ static ConnectionState ConnectUpdateRFUSocket(char* const message, size_t size)
sf::Socket::Status st = lanlink.tcplistener.accept(rfu_server.tcpsocket[nextSlave]);
if (st == sf::Socket::Error) {
if (st == sf::Socket::Status::Error) {
for (int j = 1; j < nextSlave; j++)
rfu_server.tcpsocket[j].disconnect();
@ -1679,8 +1707,7 @@ static ConnectionState ConnectUpdateRFUSocket(char* const message, size_t size)
newState = LINK_ERROR;
} else {
sf::Packet packet;
packet << static_cast<sf::Uint16>(nextSlave)
<< static_cast<sf::Uint16>(lanlink.numslaves);
packet << nextSlave << lanlink.numslaves;
rfu_server.tcpsocket[nextSlave].send(packet);
@ -1707,13 +1734,13 @@ static ConnectionState ConnectUpdateRFUSocket(char* const message, size_t size)
lanlink.tcpsocket.setBlocking(false);
sf::Socket::Status status = lanlink.tcpsocket.receive(packet);
if (status == sf::Socket::Error || status == sf::Socket::Disconnected) {
if (status == sf::Socket::Status::Error || status == sf::Socket::Status::Disconnected) {
snprintf(message, size, N_("Network error."));
newState = LINK_ERROR;
} else if (status == sf::Socket::Done) {
} else if (status == sf::Socket::Status::Done) {
if (linkid == 0) {
sf::Uint16 receivedId, receivedSlaves;
uint16_t receivedId, receivedSlaves;
packet >> receivedId >> receivedSlaves;
if (packet) {

View File

@ -86,8 +86,9 @@ extern bool SetLinkServerHost(const char* host);
* If in lan client mode, returns the IP adress of the host to connect to
* If in gamecube mode, returns the IP adress of the dolphin host
*
* @return false on error
*/
extern void GetLinkServerHost(char* const host, size_t size);
extern bool GetLinkServerHost(char* const host, size_t size);
/**
* Set the value in milliseconds of the timeout after which a connection is

View File

@ -8,10 +8,7 @@
GBASockClient::GBASockClient(sf::IpAddress _server_addr)
{
if (_server_addr == sf::IpAddress::None)
server_addr = sf::IpAddress::getPublicAddress();
else
server_addr = _server_addr;
server_addr = _server_addr;
client.connect(server_addr, 0xd6ba);
client.setBlocking(false);
@ -44,8 +41,9 @@ void GBASockClient::Send(std::vector<char> data)
// Returns cmd for convenience
char GBASockClient::ReceiveCmd(char* data_in, bool block)
{
if (IsDisconnected())
if (IsDisconnected()) {
return data_in[0];
}
std::size_t num_received = 0;
if (block || clock_sync == 0) {
@ -53,8 +51,9 @@ char GBASockClient::ReceiveCmd(char* data_in, bool block)
Selector.add(client);
Selector.wait(sf::seconds(6));
}
if (client.receive(data_in, 5, num_received) == sf::Socket::Disconnected)
if (client.receive(data_in, 5, num_received) == sf::Socket::Status::Disconnected) {
Disconnect();
}
return data_in[0];
}
@ -67,13 +66,15 @@ void GBASockClient::ReceiveClock(bool block)
char sync_ticks[4] = { 0, 0, 0, 0 };
std::size_t num_received = 0;
if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Disconnected)
if (clock_client.receive(sync_ticks, 4, num_received) == sf::Socket::Status::Disconnected) {
Disconnect();
}
if (num_received == 4) {
clock_sync_ticks = 0;
for (int i = 0; i < 4; i++)
for (int i = 0; i < 4; i++) {
clock_sync_ticks |= (uint8_t)(sync_ticks[i]) << ((3 - i) * 8);
}
clock_sync += clock_sync_ticks;
}
}

View File

@ -24,7 +24,7 @@ public:
bool IsDisconnected();
private:
sf::IpAddress server_addr;
sf::IpAddress server_addr{0};
sf::TcpSocket client;
sf::TcpSocket clock_client;

4
src/gb-over.ini Normal file
View File

@ -0,0 +1,4 @@
# Game Boy Overrrides
[ALLEY WAY]
gbPrinter = 0

View File

@ -590,7 +590,7 @@ void retro_init(void)
coreOptions.parseDebug = true;
coreOptions.cheatsEnabled = 0;
coreOptions.skipSaveGameBattery = 0;
coreOptions.winGbPrinterEnabled = 0;
coreOptions.gbPrinterEnabled = 0;
struct retro_log_callback log;
struct retro_rumble_interface rumble;

View File

@ -31,8 +31,8 @@ if(MSVC)
# We should probably use an external library for this.
target_sources(vbam
PRIVATE
${CMAKE_SOURCE_DIR}/dependencies/msvc/getopt.c
${CMAKE_SOURCE_DIR}/dependencies/msvc/getopt.h
${CMAKE_SOURCE_DIR}/win32-deps/msvc/getopt.c
${CMAKE_SOURCE_DIR}/win32-deps/msvc/getopt.h
)
endif()
@ -61,7 +61,7 @@ endif()
if(ENABLE_LIRC)
target_link_libraries(vbam lirc_client)
target_compile_definitions(vbam VBAM_ENABLE_LIRC)
target_compile_definitions(vbam PUBLIC VBAM_ENABLE_LIRC)
endif()
if(WIN32)
@ -71,15 +71,15 @@ endif()
# Installation scripts.
install(
PROGRAMS ${PROJECT_BINARY_DIR}/vbam${CMAKE_EXECUTABLE_SUFFIX}
DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(
FILES ${CMAKE_CURRENT_LIST_DIR}/vbam.cfg-example
DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}
RENAME vbam.cfg
)
if(UNIX)
# man pages.
install(FILES ${CMAKE_SOURCE_DIR}/src/debian/vbam.6 DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man6)
install(FILES ${CMAKE_SOURCE_DIR}/src/debian/vbam.6 DESTINATION ${CMAKE_INSTALL_MANDIR}/man6)
endif()

View File

@ -189,7 +189,7 @@ struct option argOptions[] = {
{ "gb-emulator-type", required_argument, 0, OPT_GB_EMULATOR_TYPE },
{ "gb-frame-skip", required_argument, 0, OPT_GB_FRAME_SKIP },
{ "gb-palette-option", required_argument, 0, OPT_GB_PALETTE_OPTION },
{ "gb-printer", no_argument, &coreOptions.winGbPrinterEnabled, 1 },
{ "gb-printer", no_argument, &coreOptions.gbPrinterEnabled, 1 },
{ "gdb", required_argument, 0, 'G' },
{ "help", no_argument, &optPrintUsage, 1 },
{ "ifb-filter", required_argument, 0, 'I' },
@ -236,7 +236,7 @@ struct option argOptions[] = {
{ "no-speedup-mute", no_argument, 0, OPT_NO_SPEEDUP_MUTE },
{ "use-bios", no_argument, &coreOptions.useBios, 1 },
{ "verbose", required_argument, 0, 'v' },
{ "win-gb-printer-enabled", no_argument, &coreOptions.winGbPrinterEnabled, 1 },
{ "win-gb-printer-enabled", no_argument, &coreOptions.gbPrinterEnabled, 1 },
{ NULL, no_argument, NULL, 0 }
@ -351,7 +351,7 @@ void LoadConfig()
coreOptions.speedup_throttle_frame_skip = ReadPref("speedupThrottleFrameSkip", 0);
coreOptions.speedup_mute = ReadPref("speedupMute", 1);
coreOptions.useBios = ReadPrefHex("useBiosGBA");
coreOptions.winGbPrinterEnabled = ReadPref("gbPrinter", 0);
coreOptions.gbPrinterEnabled = ReadPref("gbPrinter", 0);
int soundQuality = (ReadPrefHex("soundQuality", 1));
switch (soundQuality) {

View File

@ -364,6 +364,10 @@ mirroringEnabled=1
saveType=1
mirroringEnabled=1
# Higurashi no Nakukoroni (Japan)
[HGRS]
saveType=2
# Koro Koro Puzzle - Happy Panechu! (Japan)
[KHPJ]
saveType=4

View File

@ -59,6 +59,7 @@ set(VBAM_WX_COMMON
${VBAM_GENERATED_DIR}/wx/builtin-over.h
${VBAM_GENERATED_DIR}/wx/cmdhandlers.h
${VBAM_GENERATED_DIR}/wx/cmd-evtable.h
${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h
)
if(NOT ZIP_PROGRAM)
@ -141,7 +142,7 @@ endif()
# wxWidgets configuration.
set(wxWidgets_USE_UNICODE ON)
if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(wxWidgets_USE_DEBUG ON) # noop if wx is compiled with --disable-debug, like in Mac Homebrew atm
endif()
if(VBAM_STATIC)
@ -162,6 +163,13 @@ if(NOT wxWidgets_FOUND)
set(ENABLE_OPENGL FALSE)
endif()
# Fixup wxWidgets paths for vcpkg debug builds.
if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND CMAKE_TOOLCHAIN_FILE MATCHES "vcpkg")
set(wxWidgets_ROOT_DIR "${wxWidgets_ROOT_DIR}/debug" CACHE INTERNAL "wxWidgets root directory" FORCE)
string(REGEX REPLACE "/lib$" "/debug/lib" wxWidgets_LIB_DIR "${wxWidgets_LIB_DIR}")
set(wxWidgets_LIB_DIR "${wxWidgets_LIB_DIR}" CACHE INTERNAL "wxWidgets library directory" FORCE)
endif()
# Find OpenAL (required).
find_package(OpenAL REQUIRED)
@ -240,13 +248,17 @@ function(configure_wx_target target)
_add_include_directories(${wxWidgets_INCLUDE_DIRS})
_add_compile_options(${wxWidgets_CXX_FLAGS})
_add_compile_definitions(${wxWidgets_DEFINITIONS})
if(CMAKE_BUILD_TYPE MATCHES "^(Debug|RelWithDebInfo)$")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
_add_compile_definitions(${wxWidgets_DEFINITIONS_DEBUG})
endif()
# OpenAL.
if(OPENAL_STATIC)
_add_compile_definitions(AL_LIBTYPE_STATIC)
if(WIN32)
list(APPEND OPENAL_LIBRARY avrt)
endif()
endif()
_add_include_directories(${OPENAL_INCLUDE_DIR})
_add_link_libraries(${OPENAL_LIBRARY})
@ -262,9 +274,15 @@ function(configure_wx_target target)
if(MSVC)
_add_link_libraries(FAudio::FAudio)
else()
_add_link_libraries(FAudio)
if(WIN32)
if(MINGW AND VBAM_STATIC)
_add_link_libraries(FAudio.a)
else()
_add_link_libraries(FAudio)
endif()
_add_link_libraries(dxguid uuid winmm ole32 advapi32 user32 mfplat mfreadwrite mfuuid propsys)
else()
_add_link_libraries(FAudio)
endif()
endif()
endif()
@ -380,10 +398,6 @@ if(WIN32)
# Disable the auto-generated manifest from CMake.
target_link_options(visualboyadvance-m PRIVATE "/MANIFEST:NO")
endif()
# wxWidgets fails to bring in its dependency.
find_library(PCRE_LIB pcre2-16 REQUIRED)
target_link_libraries(visualboyadvance-m ${PCRE_LIB})
endif()
if(APPLE)
@ -510,7 +524,7 @@ host_compile(${CMAKE_CURRENT_SOURCE_DIR}/bin2c.c ${BIN2C})
# Override wxrc when cross-compiling.
if(CMAKE_HOST_WIN32 AND CMAKE_CROSSCOMPILING)
set(WXRC ${CMAKE_SOURCE_DIR}/dependencies/wxrc/wxrc.exe)
set(WXRC ${CMAKE_SOURCE_DIR}/win32-deps/wxrc/wxrc.exe)
endif()
# Configure wxrc.
@ -633,6 +647,12 @@ add_custom_command(
DEPENDS ${CMAKE_SOURCE_DIR}/src/vba-over.ini ${BIN2C}
)
add_custom_command(
OUTPUT ${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h
COMMAND ${BIN2C} ${CMAKE_SOURCE_DIR}/src/gb-over.ini ${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h gb_builtin_over
DEPENDS ${CMAKE_SOURCE_DIR}/src/gb-over.ini ${BIN2C}
)
set(VBAM_LOCALIZABLE_FILES ${VBAM_WX_COMMON} ${VBAM_LOCALIZABLE_WX_CONFIG_FILES})
list(APPEND VBAM_LOCALIZABLE_FILES
audio/internal/dsound.cpp
@ -655,9 +675,9 @@ if(APPLE)
set(CMAKE_INSTALL_RPATH "@loader_path/../Frameworks")
endif()
if(WIN32 AND (X86_64 OR X86_32) AND ENABLE_ONLINEUPDATES)
if(WIN32 AND (X86_64 OR ARM64 OR X86_32) AND ENABLE_ONLINEUPDATES)
if(NOT DEFINED WINSPARKLE_BIN_RELEASE_DIR)
set(WINSPARKLE_BIN_RELEASE_DIR ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0)
set(WINSPARKLE_BIN_RELEASE_DIR ${CMAKE_SOURCE_DIR}/win32-deps/WinSparkle-0.8.1)
endif()
target_include_directories(
@ -666,9 +686,11 @@ if(WIN32 AND (X86_64 OR X86_32) AND ENABLE_ONLINEUPDATES)
)
if(X86_64)
set(WINSPARKLE_DLL ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0/x64/Release/WinSparkle.dll)
else()
set(WINSPARKLE_DLL ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0/Release/WinSparkle.dll)
set(WINSPARKLE_DLL ${WINSPARKLE_BIN_RELEASE_DIR}/x64/Release/WinSparkle.dll)
elseif(ARM64)
set(WINSPARKLE_DLL ${WINSPARKLE_BIN_RELEASE_DIR}/ARM64/Release/WinSparkle.dll)
elseif(X86_32)
set(WINSPARKLE_DLL ${WINSPARKLE_BIN_RELEASE_DIR}/Release/WinSparkle.dll)
endif()
configure_file(autoupdater/wxmsw/winsparkle-path.h.in ${CMAKE_BINARY_DIR}/winsparkle-path.h)
@ -777,7 +799,7 @@ endif()
if(UPSTREAM_RELEASE AND WIN32)
set(home "$ENV{HOME}")
if((MSVC OR NOT CMAKE_CROSSCOMPILING) AND NOT DEFINED ENV{MSYSTEM_PREFIX})
if(NOT home OR ((MSVC OR NOT CMAKE_CROSSCOMPILING) AND NOT DEFINED ENV{MSYSTEM_PREFIX}))
set(home "$ENV{USERPROFILE}")
endif()
@ -785,8 +807,9 @@ if(UPSTREAM_RELEASE AND WIN32)
string(REGEX REPLACE "\\\\" "/" home "${home}")
set(cert "${home}/.codesign/windows_comodo.pkcs12")
file(STRINGS "${home}/.codesign/windows_comodo.pkcs12.password" cert_password)
if(EXISTS "${cert}")
if(EXISTS "${cert}" AND cert_password)
find_program(OSSLSIGNCODE_PROGRAM osslsigncode)
find_program(SIGNTOOL_PROGRAM signtool)
@ -795,7 +818,7 @@ if(UPSTREAM_RELEASE AND WIN32)
TARGET visualboyadvance-m
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rename visualboyadvance-m.exe visualboyadvance-m-unsigned.exe
COMMAND ${OSSLSIGNCODE_PROGRAM} sign -pkcs12 ${cert} -pass "vbam3!13" -t http://timestamp.digicert.com -n visualboyadvance-m -i https://github.com/visualboyadvance-m/visualboyadvance-m -in visualboyadvance-m-unsigned.exe -out visualboyadvance-m.exe
COMMAND ${OSSLSIGNCODE_PROGRAM} sign -pkcs12 ${cert} -pass "${cert_password}" -t http://timestamp.digicert.com -n visualboyadvance-m -i https://github.com/visualboyadvance-m/visualboyadvance-m -in visualboyadvance-m-unsigned.exe -out visualboyadvance-m.exe
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
elseif(SIGNTOOL_PROGRAM)
@ -803,7 +826,7 @@ if(UPSTREAM_RELEASE AND WIN32)
TARGET visualboyadvance-m
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy visualboyadvance-m.exe visualboyadvance-m-unsigned.exe
COMMAND ${SIGNTOOL_PROGRAM} sign /f ${cert} /fd certHash /td certHash /p "vbam3!13" /tr http://timestamp.digicert.com /du https://github.com/visualboyadvance-m/visualboyadvance-m /a visualboyadvance-m.exe
COMMAND ${SIGNTOOL_PROGRAM} sign /f ${cert} /fd certHash /td certHash /p "${cert_password}" /tr http://timestamp.digicert.com /du https://github.com/visualboyadvance-m/visualboyadvance-m /a visualboyadvance-m.exe
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endif()
@ -1008,13 +1031,13 @@ install(
# Installation scripts.
install(
PROGRAMS ${PROJECT_BINARY_DIR}/visualboyadvance-m${CMAKE_EXECUTABLE_SUFFIX}
DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(
FILES ${CMAKE_SOURCE_DIR}/src/vba-over.ini
DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/vbam
DESTINATION ${CMAKE_INSTALL_DATADIR}/vbam
)
if (UNIX)
install(FILES ${CMAKE_SOURCE_DIR}/src/debian/visualboyadvance-m.6 DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man6)
install(FILES ${CMAKE_SOURCE_DIR}/src/debian/visualboyadvance-m.6 DESTINATION ${CMAKE_INSTALL_MANDIR}/man6)
endif()

View File

@ -1990,7 +1990,7 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...")
XRCCTRL(*dlg, "GameCode", wxControl)
->SetLabel(s);
cmt = wxString((const char*)&g_rom[0xa0], wxConvLibc, 12);
wxFileConfig* cfg = wxGetApp().overrides;
wxFileConfig* cfg = wxGetApp().overrides_.get();
if (cfg->HasGroup(s)) {
cfg->SetPath(s);
@ -2024,7 +2024,7 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...")
if (panel->game_type() == IMAGE_GBA) {
agbPrintEnable(OPTION(kPrefAgbPrint));
wxString s = wxString((const char*)&g_rom[0xac], wxConvLibc, 4);
wxFileConfig* cfg = wxGetApp().overrides;
wxFileConfig* cfg = wxGetApp().overrides_.get();
bool chg;
if (cfg->HasGroup(s)) {
@ -2219,7 +2219,7 @@ EVT_HANDLER(FAQ, "VBA-M support forum")
EVT_HANDLER(Translate, "Translations")
{
wxLaunchDefaultBrowser(wxT("http://www.transifex.com/projects/p/vba-m"));
wxLaunchDefaultBrowser(wxT("https://explore.transifex.com/bgk/vba-m/"));
}
// was About
@ -2297,7 +2297,7 @@ EVT_HANDLER(RetainAspect, "Retain aspect ratio when resizing")
EVT_HANDLER(Printer, "Enable printer emulation")
{
GetMenuOptionInt("Printer", &coreOptions.winGbPrinterEnabled, 1);
GetMenuOptionInt("Printer", &coreOptions.gbPrinterEnabled, 1);
#if (defined __WIN32__ || defined _WIN32)
#ifndef NO_LINK
gbSerialFunction = gbStartLink;
@ -2305,7 +2305,7 @@ EVT_HANDLER(Printer, "Enable printer emulation")
gbSerialFunction = NULL;
#endif
#endif
if (coreOptions.winGbPrinterEnabled)
if (coreOptions.gbPrinterEnabled)
gbSerialFunction = gbPrinterSend;
update_opts();

View File

@ -31,7 +31,6 @@ LIST(SORT EVLINES)
STRING(REGEX REPLACE ",\n\$" "\n" EVLINES "${EVLINES}")
FILE(APPEND "${CMDTAB}" ${EVLINES})
FILE(APPEND "${CMDTAB}" "};\n")
FILE(APPEND "${CMDTAB}" "const int ncmds = sizeof(cmdtab) / sizeof(cmdtab[0]);\n")
# cmdhandlers.h contains prototypes for all handlers
FILE(WRITE "${EVPROTO}" "// Generated from cmdevents.cpp; do not edit\n")

View File

@ -312,7 +312,7 @@ std::array<Option, kNbOptions>& Option::All() {
Option(OptionID::kPrefFlashSize, &g_owned_opts.flash_size, 0, 1),
Option(OptionID::kPrefFrameSkip, &g_owned_opts.frame_skip, -1, 9),
Option(OptionID::kPrefGBPaletteOption, &gbPaletteOption, 0, 2),
Option(OptionID::kPrefGBPrinter, &coreOptions.winGbPrinterEnabled, 0, 1),
Option(OptionID::kPrefGBPrinter, &coreOptions.gbPrinterEnabled, 0, 1),
Option(OptionID::kPrefGDBBreakOnLoad, &g_owned_opts.gdb_break_on_load),
Option(OptionID::kPrefGDBPort, &gopts.gdb_port, 0, 65535),
#ifndef NO_LINK

View File

@ -145,9 +145,11 @@ AccelConfig::AccelConfig(wxWindow* parent,
PopulateTreeWithMenu(&command_to_item_id_, tree_, id, menu->GetMenu(i), recents,
menu->GetMenuLabelText(i) + '\n');
}
tree_->ExpandAll();
tree_->SelectItem(menu_id);
// Set a minimum size for the tree so the default dialog size is reasonable.
tree_->SetMinSize(wxSize(300, 300));
int w, h;
current_keys_->GetTextExtent("CTRL-ALT-SHIFT-ENTER", &w, &h);
wxSize size(w, h);

View File

@ -142,7 +142,10 @@ public:
if (server) {
char host[length];
GetLinkServerHost(host, length);
if (!GetLinkServerHost(host, length)) {
wxMessageBox(_("You must enter a valid host name"),
_("Host name invalid"), wxICON_ERROR | wxOK);
}
title.Printf(_("Waiting for clients..."));
connmsg.Printf(_("Server IP address is: %s\n"), wxString(host, wxConvLibc).c_str());
} else {

View File

@ -416,11 +416,9 @@ void update_shortcut_opts() {
// For keyboard shortcuts, it's easier to delete everything and start over.
cfg->DeleteGroup("/Keyboard");
cfg->SetPath("/Keyboard");
for (const auto& iter : wxGetApp().bindings()->GetKeyboardConfiguration()) {
cfg->Write(iter.first, iter.second);
}
cfg->SetPath("/");
// For joypads, we just compare the strings.
bool game_bindings_changed = false;

View File

@ -287,6 +287,15 @@ void GameArea::LoadGame(const wxString& name)
gbApplyPatch(UTF8(pfn.GetFullPath()));
}
// Apply overrides.
wxFileConfig* cfg = wxGetApp().gb_overrides_.get();
const std::string& title = g_gbCartData.title();
if (cfg->HasGroup(title)) {
cfg->SetPath(title);
coreOptions.gbPrinterEnabled = cfg->Read("gbPrinter", coreOptions.gbPrinterEnabled);
cfg->SetPath("/");
}
// start sound; this must happen before CPU stuff
gb_effects_config.enabled = OPTION(kSoundGBEnableEffects);
gb_effects_config.surround = OPTION(kSoundGBSurround);
@ -359,7 +368,7 @@ void GameArea::LoadGame(const wxString& name)
gbaUpdateRomSize(size);
}
wxFileConfig* cfg = wxGetApp().overrides;
wxFileConfig* cfg = wxGetApp().overrides_.get();
wxString id = wxString((const char*)&g_rom[0xac], wxConvLibc, 4);
if (cfg->HasGroup(id)) {
@ -428,6 +437,9 @@ void GameArea::LoadGame(const wxString& name)
emusys = &GBASystem;
}
// Set sound volume.
soundSetVolume((float)OPTION(kSoundVolume) / 100.0);
if (OPTION(kGeomFullScreen)) {
GameArea::ShowFullScreen(true);
}
@ -456,7 +468,7 @@ void GameArea::LoadGame(const wxString& name)
SuspendScreenSaver();
// probably only need to do this for GB carts
if (coreOptions.winGbPrinterEnabled)
if (coreOptions.gbPrinterEnabled)
gbSerialFunction = gbPrinterSend;
// probably only need to do this for GBA carts
@ -666,6 +678,9 @@ void GameArea::UnloadGame(bool destruct)
if (loaded == IMAGE_GB) {
gbCleanUp();
gbCheatRemoveAll();
// Reset overrides.
coreOptions.gbPrinterEnabled = OPTION(kPrefGBPrinter);
} else if (loaded == IMAGE_GBA) {
CPUCleanUp();
cheatsDeleteAll(false);
@ -952,10 +967,6 @@ void GameArea::ShowFullScreen(bool full)
while (!tlw->popups.empty())
tlw->popups.front()->Close();
// Some kbd accels can send a menu open event without a close event,
// this happens on Mac in HiDPI mode for the fullscreen toggle accel.
main_frame->SetMenusOpened(false);
// mouse stays blank whenever full-screen
HidePointer();
cursz_valid = true;

View File

@ -1,10 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<component type="desktop-application">
<id>org.visualboyadvance_m.visualboyadvance_m</id>
<metadata_license>CC-BY-SA-3.0</metadata_license>
<project_license>GPL-2.0</project_license>
<content_rating type="oars-1.1"/>
<name>VisualBoyAdvance-M</name>
<developer id="org.visualboyadvance-m">
<name>VisualBoyAdvance-M</name>
</developer>
<summary>VisualBoyAdvance-M, a high compatibility Gameboy Advance Emulator</summary>
<description>
<p>

View File

@ -11,6 +11,7 @@ target_sources(vbam-wx-widgets
$<IF:$<BOOL:${APPLE}>,dpi-support-mac.mm,dpi-support.cpp>
group-check-box.cpp
keep-on-top-styler.cpp
keyboard-input-handler.cpp
option-validator.cpp
render-plugin.cpp
user-input-ctrl.cpp
@ -28,6 +29,7 @@ target_sources(vbam-wx-widgets
event-handler-provider.h
group-check-box.h
keep-on-top-styler.h
keyboard-input-handler.h
option-validator.h
render-plugin.h
user-input-ctrl.h
@ -46,8 +48,10 @@ if(BUILD_TESTING)
client-data-test.cpp
group-check-box-test.cpp
keep-on-top-styler-test.cpp
keyboard-input-handler-test.cpp
option-validator-test.cpp
user-input-ctrl-test.cpp
user-input-event-test.cpp
)
target_link_libraries(vbam-wx-widgets-tests
@ -61,6 +65,7 @@ if(BUILD_TESTING)
vbam-wx-config
vbam-wx-widgets
GTest::gtest_main
GTest::gmock_main
)
configure_wx_target(vbam-wx-widgets-tests)

View File

@ -0,0 +1,197 @@
#include "wx/widgets/keyboard-input-handler.h"
#include <algorithm>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <wx/event.h>
#include "wx/config/user-input.h"
#include "wx/widgets/event-handler-provider.h"
#include "wx/widgets/test/widgets-test.h"
#include "wx/widgets/user-input-event.h"
namespace widgets {
namespace {
class KeyboardInputHandlerTest : public WidgetsTest,
public wxEvtHandler,
public EventHandlerProvider {
public:
KeyboardInputHandlerTest() : handler_(this) {
Bind(VBAM_EVT_USER_INPUT, &KeyboardInputHandlerTest::OnUserInputEvent, this);
}
protected:
// Processes `key_event` and returns the data from the generated events.
std::vector<UserInputEvent::Data> ProcessKeyEvent(wxKeyEvent key_event) {
handler_.ProcessKeyEvent(key_event);
ProcessPendingEvents();
std::vector<UserInputEvent::Data> data;
std::swap(data, pending_data_);
return data;
}
private:
void OnUserInputEvent(UserInputEvent& event) {
// Do not let the event propagate.
event.Skip(false);
for (const auto& data : event.data()) {
pending_data_.emplace_back(data);
}
}
// EventHandlerProvider implementation.
wxEvtHandler* event_handler() override { return this; }
KeyboardInputHandler handler_;
std::vector<UserInputEvent::Data> pending_data_;
};
static constexpr config::KeyboardInput kF1(wxKeyCode::WXK_F1);
static constexpr config::KeyboardInput kCtrlF1(wxKeyCode::WXK_F1, wxMOD_CONTROL);
static constexpr config::KeyboardInput kCtrlShiftF1(wxKeyCode::WXK_F1,
static_cast<wxKeyModifier>(wxMOD_CONTROL |
wxMOD_SHIFT));
static constexpr config::KeyboardInput kCtrl(wxKeyCode::WXK_CONTROL, wxMOD_CONTROL);
static constexpr config::KeyboardInput kShift(wxKeyCode::WXK_SHIFT, wxMOD_SHIFT);
static const UserInputEvent::Data kF1Pressed(kF1, true);
static const UserInputEvent::Data kF1Released(kF1, false);
static const UserInputEvent::Data kCtrlF1Pressed(kCtrlF1, true);
static const UserInputEvent::Data kCtrlF1Released(kCtrlF1, false);
static const UserInputEvent::Data kCtrlShiftF1Pressed(kCtrlShiftF1, true);
static const UserInputEvent::Data kCtrlShiftF1Released(kCtrlShiftF1, false);
static const UserInputEvent::Data kCtrlPressed(kCtrl, true);
static const UserInputEvent::Data kCtrlReleased(kCtrl, false);
static const UserInputEvent::Data kShiftPressed(kShift, true);
static const UserInputEvent::Data kShiftReleased(kShift, false);
wxKeyEvent F1DownEvent() {
wxKeyEvent event(wxEVT_KEY_DOWN);
event.m_keyCode = WXK_F1;
return event;
}
wxKeyEvent F1UpEvent() {
wxKeyEvent event(wxEVT_KEY_UP);
event.m_keyCode = WXK_F1;
return event;
}
wxKeyEvent CtrlF1DownEvent() {
wxKeyEvent event(wxEVT_KEY_DOWN);
event.m_keyCode = WXK_F1;
event.m_controlDown = true;
return event;
}
wxKeyEvent CtrlF1UpEvent() {
wxKeyEvent event(wxEVT_KEY_UP);
event.m_keyCode = WXK_F1;
event.m_controlDown = true;
return event;
}
wxKeyEvent CtrlShiftF1DownEvent() {
wxKeyEvent event(wxEVT_KEY_DOWN);
event.m_keyCode = WXK_F1;
event.m_controlDown = true;
event.m_shiftDown = true;
return event;
}
wxKeyEvent CtrlShiftF1UpEvent() {
wxKeyEvent event(wxEVT_KEY_UP);
event.m_keyCode = WXK_F1;
event.m_controlDown = true;
event.m_shiftDown = true;
return event;
}
wxKeyEvent CtrlDownEvent() {
wxKeyEvent event(wxEVT_KEY_DOWN);
event.m_keyCode = WXK_CONTROL;
return event;
}
wxKeyEvent CtrlUpEvent() {
wxKeyEvent event(wxEVT_KEY_UP);
event.m_keyCode = WXK_CONTROL;
return event;
}
wxKeyEvent ShiftDownEvent() {
wxKeyEvent event(wxEVT_KEY_DOWN);
event.m_keyCode = WXK_SHIFT;
return event;
}
wxKeyEvent ShiftUpEvent() {
wxKeyEvent event(wxEVT_KEY_UP);
event.m_keyCode = WXK_SHIFT;
return event;
}
} // namespace
TEST_F(KeyboardInputHandlerTest, SimpleKeyDownUp) {
// Send F1 down event.
ASSERT_THAT(ProcessKeyEvent(F1DownEvent()), testing::ElementsAre(kF1Pressed));
// Send F1 up event.
ASSERT_THAT(ProcessKeyEvent(F1UpEvent()), testing::ElementsAre(kF1Released));
}
TEST_F(KeyboardInputHandlerTest, ModifierThenKey) {
// Ctrl Down -> F1 Down -> F1 Up -> Ctrl Up
ASSERT_THAT(ProcessKeyEvent(CtrlDownEvent()), testing::ElementsAre(kCtrlPressed));
ASSERT_THAT(ProcessKeyEvent(CtrlF1DownEvent()),
testing::ElementsAre(kCtrlF1Pressed, kF1Pressed));
ASSERT_THAT(ProcessKeyEvent(CtrlF1UpEvent()),
testing::ElementsAre(kCtrlF1Released, kF1Released));
ASSERT_THAT(ProcessKeyEvent(CtrlUpEvent()), testing::ElementsAre(kCtrlReleased));
}
TEST_F(KeyboardInputHandlerTest, KeyThenModifier) {
// F1 Down -> Ctrl Down -> Ctrl Up -> F1 Up
// In this case, no Ctrl+F1 event should be generated.
ASSERT_THAT(ProcessKeyEvent(F1DownEvent()), testing::ElementsAre(kF1Pressed));
ASSERT_THAT(ProcessKeyEvent(CtrlDownEvent()), testing::ElementsAre(kCtrlPressed));
ASSERT_THAT(ProcessKeyEvent(CtrlUpEvent()), testing::ElementsAre(kCtrlReleased));
ASSERT_THAT(ProcessKeyEvent(F1UpEvent()), testing::ElementsAre(kF1Released));
// F1 Down -> Ctrl Down -> F1 Up -> Ctrl Up
// In this case, a Ctrl+F1 event should be generated when F1 is released.
ASSERT_THAT(ProcessKeyEvent(F1DownEvent()), testing::ElementsAre(kF1Pressed));
ASSERT_THAT(ProcessKeyEvent(CtrlDownEvent()), testing::ElementsAre(kCtrlPressed));
ASSERT_THAT(ProcessKeyEvent(F1UpEvent()),
testing::ElementsAre(kCtrlF1Pressed, kCtrlF1Released, kF1Released));
ASSERT_THAT(ProcessKeyEvent(CtrlUpEvent()), testing::ElementsAre(kCtrlReleased));
}
TEST_F(KeyboardInputHandlerTest, Multiplemodifiers) {
// F1 Down -> Ctrl Down -> Shift Down -> F1 Up -> Ctrl Up -> Shift Up
// In this case, a Ctrl+Shift+F1 event should be generated when F1 is released.
ASSERT_THAT(ProcessKeyEvent(F1DownEvent()), testing::ElementsAre(kF1Pressed));
ASSERT_THAT(ProcessKeyEvent(CtrlDownEvent()), testing::ElementsAre(kCtrlPressed));
ASSERT_THAT(ProcessKeyEvent(ShiftDownEvent()), testing::ElementsAre(kShiftPressed));
ASSERT_THAT(ProcessKeyEvent(F1UpEvent()),
testing::ElementsAre(kCtrlShiftF1Pressed, kCtrlShiftF1Released, kF1Released));
ASSERT_THAT(ProcessKeyEvent(CtrlUpEvent()), testing::ElementsAre(kCtrlReleased));
ASSERT_THAT(ProcessKeyEvent(ShiftUpEvent()), testing::ElementsAre(kShiftReleased));
// Ctrl Down -> Shift Down -> F1 Down -> F1 Up -> Shift Up -> Ctrl Up
// In this case, a Ctrl+Shift+F1 event should be generated when F1 is pressed.
ASSERT_THAT(ProcessKeyEvent(CtrlDownEvent()), testing::ElementsAre(kCtrlPressed));
ASSERT_THAT(ProcessKeyEvent(ShiftDownEvent()), testing::ElementsAre(kShiftPressed));
ASSERT_THAT(ProcessKeyEvent(CtrlShiftF1DownEvent()),
testing::ElementsAre(kCtrlShiftF1Pressed, kF1Pressed));
ASSERT_THAT(ProcessKeyEvent(CtrlShiftF1UpEvent()),
testing::ElementsAre(kCtrlShiftF1Released, kF1Released));
ASSERT_THAT(ProcessKeyEvent(ShiftUpEvent()), testing::ElementsAre(kShiftReleased));
ASSERT_THAT(ProcessKeyEvent(CtrlUpEvent()), testing::ElementsAre(kCtrlReleased));
}
} // namespace widgets

View File

@ -0,0 +1,273 @@
#include "wx/widgets/keyboard-input-handler.h"
#include "wx/config/user-input.h"
#include "wx/widgets/user-input-event.h"
#include <wx/log.h>
namespace widgets {
namespace {
// Filters the received key code in the key event for something we can use.
wxKeyCode FilterKeyCode(const wxKeyEvent& event) {
const wxKeyCode unicode_key = static_cast<wxKeyCode>(event.GetUnicodeKey());
if (unicode_key == WXK_NONE) {
// We need to filter out modifier keys here so we can differentiate
// between a key press and a modifier press.
const wxKeyCode keycode = static_cast<wxKeyCode>(event.GetKeyCode());
switch (keycode) {
case WXK_CONTROL:
case WXK_ALT:
case WXK_SHIFT:
#ifdef __WXMAC__
case WXK_RAW_CONTROL:
#endif
return WXK_NONE;
default:
return keycode;
}
}
if (unicode_key < 32) {
switch (unicode_key) {
case WXK_BACK:
case WXK_TAB:
case WXK_RETURN:
case WXK_ESCAPE:
return unicode_key;
default:
return WXK_NONE;
}
}
return unicode_key;
}
// Returns the set of modifiers for the given key event.
std::unordered_set<wxKeyModifier> GetModifiers(const wxKeyEvent& event) {
// Standalone modifier are treated as keys and do not set the keyboard modifiers.
switch (event.GetKeyCode()) {
case WXK_CONTROL:
return {wxMOD_CONTROL};
case WXK_ALT:
return {wxMOD_ALT};
case WXK_SHIFT:
return {wxMOD_SHIFT};
#ifdef __WXMAC__
case WXK_RAW_CONTROL:
return {wxMOD_RAW_CONTROL};
#endif
}
std::unordered_set<wxKeyModifier> mods;
if (event.ControlDown()) {
mods.insert(wxMOD_CONTROL);
}
if (event.AltDown()) {
mods.insert(wxMOD_ALT);
}
if (event.ShiftDown()) {
mods.insert(wxMOD_SHIFT);
}
#ifdef __WXMAC__
if (event.RawControlDown()) {
mods.insert(wxMOD_RAW_CONTROL);
}
#endif
return mods;
}
// Builds a wxKeyModifier from a set of modifiers.
wxKeyModifier GetModifiersFromSet(const std::unordered_set<wxKeyModifier>& mods) {
int mod = wxMOD_NONE;
for (const wxKeyModifier m : mods) {
mod |= m;
}
return static_cast<wxKeyModifier>(mod);
}
// Returns the key code for a standalone modifier.
wxKeyCode KeyFromModifier(const wxKeyModifier mod) {
switch (mod) {
case wxMOD_CONTROL:
return WXK_CONTROL;
case wxMOD_ALT:
return WXK_ALT;
case wxMOD_SHIFT:
return WXK_SHIFT;
#ifdef __WXMAC__
case wxMOD_RAW_CONTROL:
return WXK_RAW_CONTROL;
#endif
default:
return WXK_NONE;
}
}
} // namespace
KeyboardInputHandler::KeyboardInputHandler(EventHandlerProvider* const handler_provider)
: handler_provider_(handler_provider) {
VBAM_CHECK(handler_provider_);
}
KeyboardInputHandler::~KeyboardInputHandler() = default;
void KeyboardInputHandler::ProcessKeyEvent(wxKeyEvent& event) {
if (!handler_provider_->event_handler()) {
// No event handler to send the event to.
return;
}
if (event.GetEventType() == wxEVT_KEY_DOWN) {
OnKeyDown(event);
} else if (event.GetEventType() == wxEVT_KEY_UP) {
OnKeyUp(event);
}
}
void KeyboardInputHandler::Reset() {
active_keys_.clear();
active_mods_.clear();
active_mod_inputs_.clear();
}
void KeyboardInputHandler::OnKeyDown(wxKeyEvent& event) {
// Stop propagation of the event.
event.Skip(false);
const wxKeyCode key = FilterKeyCode(event);
const std::unordered_set<wxKeyModifier> mods = GetModifiers(event);
wxKeyCode key_pressed = WXK_NONE;
if (key != WXK_NONE) {
if (active_keys_.find(key) == active_keys_.end()) {
// Key was not pressed before.
key_pressed = key;
active_keys_.insert(key);
}
}
wxKeyModifier mod_pressed = wxMOD_NONE;
for (const wxKeyModifier mod : mods) {
if (active_mods_.find(mod) == active_mods_.end()) {
// Mod was not pressed before.
active_mods_.insert(mod);
mod_pressed = mod;
break;
}
}
if (key_pressed == WXK_NONE && mod_pressed == wxMOD_NONE) {
// No new keys or mods were pressed.
return;
}
const wxKeyModifier active_mods = GetModifiersFromSet(active_mods_);
std::vector<UserInputEvent::Data> event_data;
if (key_pressed == WXK_NONE) {
// A new standalone modifier was pressed, send the event.
event_data.emplace_back(config::KeyboardInput(KeyFromModifier(mod_pressed), mod_pressed),
true);
} else {
// A new key was pressed, send the event with modifiers, first.
event_data.emplace_back(config::KeyboardInput(key, active_mods), true);
if (active_mods != wxMOD_NONE) {
// Keep track of the key pressed with the active modifiers.
active_mod_inputs_.emplace(key, active_mods);
// Also send the key press event without modifiers.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), true);
}
}
wxQueueEvent(handler_provider_->event_handler(), new UserInputEvent(std::move(event_data)));
}
void KeyboardInputHandler::OnKeyUp(wxKeyEvent& event) {
// Stop propagation of the event.
event.Skip(false);
const wxKeyCode key = FilterKeyCode(event);
const std::unordered_set<wxKeyModifier> mods = GetModifiers(event);
const wxKeyModifier previous_mods = GetModifiersFromSet(active_mods_);
wxKeyCode key_released = WXK_NONE;
if (key != WXK_NONE) {
auto iter = active_keys_.find(key);
if (iter != active_keys_.end()) {
// Key was pressed before.
key_released = key;
active_keys_.erase(iter);
}
}
wxKeyModifier mod_released = wxMOD_NONE;
if (key_released == WXK_NONE) {
// Only look for a standalone modifier if no key was released.
for (const wxKeyModifier mod : mods) {
auto iter = active_mods_.find(mod);
if (iter != active_mods_.end()) {
// Mod was pressed before.
mod_released = mod;
active_mods_.erase(iter);
break;
}
}
}
if (key_released == WXK_NONE && mod_released == wxMOD_NONE) {
// No keys or mods were released.
return;
}
std::vector<UserInputEvent::Data> event_data;
if (key_released == WXK_NONE) {
// A standalone modifier was released, send it.
event_data.emplace_back(config::KeyboardInput(KeyFromModifier(mod_released), mod_released),
false);
} else {
// A key was released.
if (previous_mods == wxMOD_NONE) {
// The key was pressed without modifiers, just send the key release event.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), false);
} else {
// Check if the key was pressed with the active modifiers.
const config::KeyboardInput input_with_modifiers(key, previous_mods);
auto iter = active_mod_inputs_.find(input_with_modifiers);
if (iter == active_mod_inputs_.end()) {
// The key press event was never sent, so do it now.
event_data.emplace_back(input_with_modifiers, true);
} else {
active_mod_inputs_.erase(iter);
}
// Send the key release event with the active modifiers.
event_data.emplace_back(input_with_modifiers, false);
// Also send the key release event without modifiers.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), false);
}
}
// Also check for any key that were pressed with the previously active
// modifiers and release them.
for (const wxKeyCode active_key : active_keys_) {
const config::KeyboardInput input(active_key, previous_mods);
auto iter = active_mod_inputs_.find(input);
if (iter != active_mod_inputs_.end()) {
active_mod_inputs_.erase(iter);
event_data.emplace_back(std::move(input), false);
}
}
for (const auto& data : event_data) {
active_mod_inputs_.erase(data.input.keyboard_input());
}
wxQueueEvent(handler_provider_->event_handler(), new UserInputEvent(std::move(event_data)));
}
} // namespace widgets

View File

@ -0,0 +1,49 @@
#ifndef VBAM_WX_WIDGETS_KEYBOARD_INPUT_HANDLER_H_
#define VBAM_WX_WIDGETS_KEYBOARD_INPUT_HANDLER_H_
#include <unordered_set>
#include <wx/event.h>
#include "wx/config/user-input.h"
#include "wx/widgets/event-handler-provider.h"
namespace widgets {
// Object that is used to fire user input events when a keyboard key is pressed
// or released. This class should be kept as a singleton owned by the
// application object. It is meant to be used in the FilterEvent() method of the
// app to create user input events globally whenever the keyboard is used.
class KeyboardInputHandler final {
public:
explicit KeyboardInputHandler(EventHandlerProvider* const handler_provider);
~KeyboardInputHandler();
// Disable copy and copy assignment.
KeyboardInputHandler(const KeyboardInputHandler&) = delete;
KeyboardInputHandler& operator=(const KeyboardInputHandler&) = delete;
// Processes the provided key event and sends the appropriate user input
// event to the current event handler.
void ProcessKeyEvent(wxKeyEvent& event);
// Resets the state of the sender. This should be called when the main frame
// loses focus to prevent stuck keys.
void Reset();
private:
// Keyboard event handlers.
void OnKeyDown(wxKeyEvent& event);
void OnKeyUp(wxKeyEvent& event);
std::unordered_set<wxKeyCode> active_keys_;
std::unordered_set<wxKeyModifier> active_mods_;
std::unordered_set<config::KeyboardInput> active_mod_inputs_;
// The provider of event handlers to send the events to.
EventHandlerProvider* const handler_provider_;
};
} // namespace widgets
#endif // VBAM_WX_WIDGETS_KEYBOARD_INPUT_HANDLER_H_

View File

@ -0,0 +1,53 @@
#include "wx/widgets/user-input-event.h"
#include <gtest/gtest.h>
#include <wx/eventfilter.h>
#include "wx/config/user-input.h"
namespace widgets {
namespace {
static constexpr config::KeyboardInput kF1(wxKeyCode::WXK_F1);
static constexpr config::KeyboardInput kCtrlF1(wxKeyCode::WXK_F1, wxMOD_CONTROL);
static constexpr config::JoyInput kButton0(config::JoyId(0), config::JoyControl::Button, 0);
} // namespace
TEST(UserInputEventTest, KeyboardInputEvent) {
// Press Ctrl+F1.
UserInputEvent pressed_event({{kCtrlF1, true}});
EXPECT_EQ(pressed_event.FirstReleasedInput(), nonstd::nullopt);
// Process Ctrl+F1.
EXPECT_EQ(pressed_event.FilterProcessedInput(kCtrlF1), wxEventFilter::Event_Processed);
EXPECT_EQ(pressed_event.data().size(), 0);
}
TEST(UserInputEventTest, JoystickInputEvent) {
// Press button 0.
UserInputEvent pressed_event({{kButton0, true}});
EXPECT_EQ(pressed_event.FirstReleasedInput(), nonstd::nullopt);
// Process button 0.
EXPECT_EQ(pressed_event.FilterProcessedInput(kButton0), wxEventFilter::Event_Processed);
EXPECT_EQ(pressed_event.data().size(), 0);
}
TEST(UserInputeventTest, MultipleInput) {
// Release F1 and Ctrl+F1.
UserInputEvent pressed_event({{kCtrlF1, false}, {kF1, false}});
EXPECT_EQ(pressed_event.FirstReleasedInput(), kCtrlF1);
// Process Ctrl+F1.
EXPECT_EQ(pressed_event.FilterProcessedInput(kCtrlF1), wxEventFilter::Event_Skip);
EXPECT_EQ(pressed_event.data().size(), 1);
// Process button 0.
EXPECT_EQ(pressed_event.FilterProcessedInput(kF1), wxEventFilter::Event_Processed);
EXPECT_EQ(pressed_event.data().size(), 0);
}
} // namespace widgets

View File

@ -1,116 +1,15 @@
#include "wx/widgets/user-input-event.h"
#include <algorithm>
#include <utility>
#include <vector>
#include <wx/event.h>
#include <wx/eventfilter.h>
#include <wx/window.h>
#include "wx/config/user-input.h"
namespace widgets {
namespace {
// Filters the received key code in the key event for something we can use.
wxKeyCode FilterKeyCode(const wxKeyEvent& event) {
const wxKeyCode unicode_key = static_cast<wxKeyCode>(event.GetUnicodeKey());
if (unicode_key == WXK_NONE) {
// We need to filter out modifier keys here so we can differentiate
// between a key press and a modifier press.
const wxKeyCode keycode = static_cast<wxKeyCode>(event.GetKeyCode());
switch (keycode) {
case WXK_CONTROL:
case WXK_ALT:
case WXK_SHIFT:
#ifdef __WXMAC__
case WXK_RAW_CONTROL:
#endif
return WXK_NONE;
default:
return keycode;
}
}
if (unicode_key < 32) {
switch (unicode_key) {
case WXK_BACK:
case WXK_TAB:
case WXK_RETURN:
case WXK_ESCAPE:
return unicode_key;
default:
return WXK_NONE;
}
}
return unicode_key;
}
// Returns the set of modifiers for the given key event.
std::unordered_set<wxKeyModifier> GetModifiers(const wxKeyEvent& event) {
// Standalone modifier are treated as keys and do not set the keyboard modifiers.
switch (event.GetKeyCode()) {
case WXK_CONTROL:
return {wxMOD_CONTROL};
case WXK_ALT:
return {wxMOD_ALT};
case WXK_SHIFT:
return {wxMOD_SHIFT};
#ifdef __WXMAC__
case WXK_RAW_CONTROL:
return {wxMOD_RAW_CONTROL};
#endif
}
std::unordered_set<wxKeyModifier> mods;
if (event.ControlDown()) {
mods.insert(wxMOD_CONTROL);
}
if (event.AltDown()) {
mods.insert(wxMOD_ALT);
}
if (event.ShiftDown()) {
mods.insert(wxMOD_SHIFT);
}
#ifdef __WXMAC__
if (event.RawControlDown()) {
mods.insert(wxMOD_RAW_CONTROL);
}
#endif
return mods;
}
// Builds a wxKeyModifier from a set of modifiers.
wxKeyModifier GetModifiersFromSet(const std::unordered_set<wxKeyModifier>& mods) {
int mod = wxMOD_NONE;
for (const wxKeyModifier m : mods) {
mod |= m;
}
return static_cast<wxKeyModifier>(mod);
}
// Returns the key code for a standalone modifier.
wxKeyCode KeyFromModifier(const wxKeyModifier mod) {
switch (mod) {
case wxMOD_CONTROL:
return WXK_CONTROL;
case wxMOD_ALT:
return WXK_ALT;
case wxMOD_SHIFT:
return WXK_SHIFT;
#ifdef __WXMAC__
case wxMOD_RAW_CONTROL:
return WXK_RAW_CONTROL;
#endif
default:
return WXK_NONE;
}
}
} // namespace
UserInputEvent::UserInputEvent(std::vector<Data> event_data)
: wxEvent(0, VBAM_EVT_USER_INPUT), data_(std::move(event_data)) {}
@ -119,7 +18,7 @@ nonstd::optional<config::UserInput> UserInputEvent::FirstReleasedInput() const {
std::find_if(data_.begin(), data_.end(), [](const auto& data) { return !data.pressed; });
if (iter == data_.end()) {
// No pressed inputs.
// No released inputs.
return nonstd::nullopt;
}
@ -151,163 +50,6 @@ wxEvent* UserInputEvent::Clone() const {
return new UserInputEvent(this->data_);
}
KeyboardInputSender::KeyboardInputSender(EventHandlerProvider* const handler_provider)
: handler_provider_(handler_provider) {
VBAM_CHECK(handler_provider_);
}
KeyboardInputSender::~KeyboardInputSender() = default;
void KeyboardInputSender::ProcessKeyEvent(wxKeyEvent& event) {
if (!handler_provider_->event_handler()) {
// No event handler to send the event to.
return;
}
if (event.GetEventType() == wxEVT_KEY_DOWN) {
OnKeyDown(event);
} else if (event.GetEventType() == wxEVT_KEY_UP) {
OnKeyUp(event);
}
}
void KeyboardInputSender::OnKeyDown(wxKeyEvent& event) {
// Stop propagation of the event.
event.Skip(false);
const wxKeyCode key = FilterKeyCode(event);
const std::unordered_set<wxKeyModifier> mods = GetModifiers(event);
wxKeyCode key_pressed = WXK_NONE;
if (key != WXK_NONE) {
if (active_keys_.find(key) == active_keys_.end()) {
// Key was not pressed before.
key_pressed = key;
active_keys_.insert(key);
}
}
wxKeyModifier mod_pressed = wxMOD_NONE;
for (const wxKeyModifier mod : mods) {
if (active_mods_.find(mod) == active_mods_.end()) {
// Mod was not pressed before.
active_mods_.insert(mod);
mod_pressed = mod;
break;
}
}
if (key_pressed == WXK_NONE && mod_pressed == wxMOD_NONE) {
// No new keys or mods were pressed.
return;
}
const wxKeyModifier active_mods = GetModifiersFromSet(active_mods_);
std::vector<UserInputEvent::Data> event_data;
if (key_pressed == WXK_NONE) {
// A new standalone modifier was pressed, send the event.
event_data.emplace_back(config::KeyboardInput(KeyFromModifier(mod_pressed), mod_pressed),
true);
} else {
// A new key was pressed, send the event with modifiers, first.
event_data.emplace_back(config::KeyboardInput(key, active_mods), true);
if (active_mods != wxMOD_NONE) {
// Keep track of the key pressed with the active modifiers.
active_mod_inputs_.emplace(key, active_mods);
// Also send the key press event without modifiers.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), true);
}
}
wxQueueEvent(handler_provider_->event_handler(), new UserInputEvent(std::move(event_data)));
}
void KeyboardInputSender::OnKeyUp(wxKeyEvent& event) {
// Stop propagation of the event.
event.Skip(false);
const wxKeyCode key = FilterKeyCode(event);
const std::unordered_set<wxKeyModifier> mods = GetModifiers(event);
const wxKeyModifier previous_mods = GetModifiersFromSet(active_mods_);
wxKeyCode key_released = WXK_NONE;
if (key != WXK_NONE) {
auto iter = active_keys_.find(key);
if (iter != active_keys_.end()) {
// Key was pressed before.
key_released = key;
active_keys_.erase(iter);
}
}
wxKeyModifier mod_released = wxMOD_NONE;
if (key_released == WXK_NONE) {
// Only look for a standalone modifier if no key was released.
for (const wxKeyModifier mod : mods) {
auto iter = active_mods_.find(mod);
if (iter != active_mods_.end()) {
// Mod was pressed before.
mod_released = mod;
active_mods_.erase(iter);
break;
}
}
}
if (key_released == WXK_NONE && mod_released == wxMOD_NONE) {
// No keys or mods were released.
return;
}
std::vector<UserInputEvent::Data> event_data;
if (key_released == WXK_NONE) {
// A standalone modifier was released, send it.
event_data.emplace_back(config::KeyboardInput(KeyFromModifier(mod_released), mod_released),
false);
} else {
// A key was released.
if (previous_mods == wxMOD_NONE) {
// The key was pressed without modifiers, just send the key release event.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), false);
} else {
// Check if the key was pressed with the active modifiers.
const config::KeyboardInput input_with_modifiers(key, previous_mods);
auto iter = active_mod_inputs_.find(input_with_modifiers);
if (iter == active_mod_inputs_.end()) {
// The key press event was never sent, so do it now.
event_data.emplace_back(input_with_modifiers, true);
} else {
active_mod_inputs_.erase(iter);
}
// Send the key release event with the active modifiers.
event_data.emplace_back(config::KeyboardInput(key, previous_mods), false);
// Also send the key release event without modifiers.
event_data.emplace_back(config::KeyboardInput(key, wxMOD_NONE), false);
}
}
// Also check for any key that were pressed with the previously active
// modifiers and release them.
for (const wxKeyCode active_key : active_keys_) {
const config::KeyboardInput input(active_key, previous_mods);
auto iter = active_mod_inputs_.find(input);
if (iter != active_mod_inputs_.end()) {
active_mod_inputs_.erase(iter);
event_data.emplace_back(std::move(input), false);
}
}
for (const auto& data : event_data) {
active_mod_inputs_.erase(data.input.keyboard_input());
}
wxQueueEvent(handler_provider_->event_handler(), new UserInputEvent(std::move(event_data)));
}
} // namespace widgets
wxDEFINE_EVENT(VBAM_EVT_USER_INPUT, widgets::UserInputEvent);
wxDEFINE_EVENT(VBAM_EVT_USER_INPUT, ::widgets::UserInputEvent);

View File

@ -1,7 +1,6 @@
#ifndef WX_WIDGETS_USER_INPUT_EVENT_H_
#define WX_WIDGETS_USER_INPUT_EVENT_H_
#ifndef VBAM_WX_WIDGETS_USER_INPUT_EVENT_H_
#define VBAM_WX_WIDGETS_USER_INPUT_EVENT_H_
#include <unordered_set>
#include <vector>
#include <optional.hpp>
@ -10,7 +9,6 @@
#include <wx/event.h>
#include "wx/config/user-input.h"
#include "wx/widgets/event-handler-provider.h"
namespace widgets {
@ -18,6 +16,8 @@ namespace widgets {
// contains the set of user input that were pressed or released. The order
// in the vector matters, this is the order in which the inputs were pressed or
// released.
// Note that a single event can contain multiple inputs pressed and/or released.
// These should be processed in the same order as they are in the vector.
class UserInputEvent final : public wxEvent {
public:
// Data for the event. Contains the user input and whether it was pressed or
@ -26,7 +26,13 @@ public:
const config::UserInput input;
const bool pressed;
Data(config::UserInput input, bool pressed) : input(input), pressed(pressed){};
Data(config::UserInput input, bool pressed) : input(input), pressed(pressed) {};
// Equality operators.
bool operator==(const Data& other) const {
return input == other.input && pressed == other.pressed;
}
bool operator!=(const Data& other) const { return !(*this == other); }
};
UserInputEvent(std::vector<Data> event_data);
@ -36,7 +42,7 @@ public:
UserInputEvent(const UserInputEvent&) = delete;
UserInputEvent& operator=(const UserInputEvent&) = delete;
// Returns the first pressed input, if any.
// Returns the first released input, if any.
nonstd::optional<config::UserInput> FirstReleasedInput() const;
// Marks `user_input` as processed and returns the new event filter. This is
@ -53,38 +59,9 @@ private:
std::vector<Data> data_;
};
// Object that is used to fire user input events when a key is pressed or
// released. This class should be kept as a singleton owned by the application
// object. It is meant to be used in the FilterEvent() method of the app.
class KeyboardInputSender final : public wxClientData {
public:
explicit KeyboardInputSender(EventHandlerProvider* const handler_provider);
~KeyboardInputSender() override;
// Disable copy and copy assignment.
KeyboardInputSender(const KeyboardInputSender&) = delete;
KeyboardInputSender& operator=(const KeyboardInputSender&) = delete;
// Processes the provided key event and sends the appropriate user input
// event to the current event handler.
void ProcessKeyEvent(wxKeyEvent& event);
private:
// Keyboard event handlers.
void OnKeyDown(wxKeyEvent& event);
void OnKeyUp(wxKeyEvent& event);
std::unordered_set<wxKeyCode> active_keys_;
std::unordered_set<wxKeyModifier> active_mods_;
std::unordered_set<config::KeyboardInput> active_mod_inputs_;
// The provider of event handlers to send the events to.
EventHandlerProvider* const handler_provider_;
};
} // namespace widgets
// Fired when a set of user inputs are pressed or released.
wxDECLARE_EVENT(VBAM_EVT_USER_INPUT, widgets::UserInputEvent);
wxDECLARE_EVENT(VBAM_EVT_USER_INPUT, ::widgets::UserInputEvent);
#endif // WX_WIDGETS_USER_INPUT_EVENT_H_
#endif // VBAM_WX_WIDGETS_USER_INPUT_EVENT_H_

View File

@ -20,6 +20,7 @@
#include <wx/progdlg.h>
#include <wx/protocol/http.h>
#include <wx/regex.h>
#include <wx/spinctrl.h>
#include <wx/sstream.h>
#include <wx/stdpaths.h>
#include <wx/string.h>
@ -31,6 +32,7 @@
#include "components/user_config/user_config.h"
#include "core/gba/gbaSound.h"
#include "wx/gb-builtin-over.h"
#include "wx/builtin-over.h"
#include "wx/builtin-xrc.h"
#include "wx/config/cmdtab.h"
@ -248,7 +250,14 @@ wxvbamApp::wxvbamApp()
using_wayland(false),
emulated_gamepad_(std::bind(&wxvbamApp::bindings, this)),
sdl_poller_(this),
keyboard_input_sender_(this) {}
keyboard_input_handler_(this) {
Bind(wxEVT_ACTIVATE_APP, [this](wxActivateEvent& event) {
if (!event.GetActive()) {
keyboard_input_handler_.Reset();
}
event.Skip();
});
}
const wxString wxvbamApp::GetPluginsDir()
{
@ -463,13 +472,17 @@ bool wxvbamApp::OnInit() {
}
}
// load gb-over.ini
wxMemoryInputStream stream(gb_builtin_over, sizeof(gb_builtin_over));
gb_overrides_ = std::make_unique<wxFileConfig>(stream);
// load vba-over.ini
// rather than dealing with wxConfig's broken search path, just use
// the same one that the xrc overrides use
// this also allows us to override a group at a time, add commments, and
// add the file from which the group came
wxMemoryInputStream mis(builtin_over, sizeof(builtin_over));
overrides = new wxFileConfig(mis);
overrides_ = std::make_unique<wxFileConfig>(mis);
wxRegEx cmtre;
// not the most efficient thing to do: read entire file into a string
// just to parse the comments out
@ -479,8 +492,8 @@ bool wxvbamApp::OnInit() {
long grp_idx;
#define CMT_RE_START wxT("(^|[\n\r])# ?([^\n\r]*)(\r?\n|\r)\\[")
for (cont = overrides->GetFirstGroup(s, grp_idx); cont;
cont = overrides->GetNextGroup(s, grp_idx)) {
for (cont = overrides_->GetFirstGroup(s, grp_idx); cont;
cont = overrides_->GetNextGroup(s, grp_idx)) {
// apparently even MacOSX sometimes uses the old \r by itself
wxString cmt(CMT_RE_START);
cmt += s + wxT("\\]");
@ -490,7 +503,7 @@ bool wxvbamApp::OnInit() {
else
cmt = wxEmptyString;
overrides->Write(s + wxT("/comment"), cmt);
overrides_->Write(s + wxT("/comment"), cmt);
}
if (vba_over.FileExists()) {
@ -506,10 +519,10 @@ bool wxvbamApp::OnInit() {
for (cont = ov.GetFirstGroup(s, grp_idx); cont;
cont = ov.GetNextGroup(s, grp_idx)) {
overrides->DeleteGroup(s);
overrides->SetPath(s);
overrides_->DeleteGroup(s);
overrides_->SetPath(s);
ov.SetPath(s);
overrides->Write(wxT("path"), GetConfigurationPath());
overrides_->Write(wxT("path"), GetConfigurationPath());
// apparently even MacOSX sometimes uses \r by itself
wxString cmt(CMT_RE_START);
cmt += s + wxT("\\]");
@ -519,15 +532,15 @@ bool wxvbamApp::OnInit() {
else
cmt = wxEmptyString;
overrides->Write(wxT("comment"), cmt);
overrides_->Write(wxT("comment"), cmt);
long ent_idx;
for (cont = ov.GetFirstEntry(s, ent_idx); cont;
cont = ov.GetNextEntry(s, ent_idx))
overrides->Write(s, ov.Read(s, wxEmptyString));
overrides_->Write(s, ov.Read(s, wxEmptyString));
ov.SetPath(wxT("/"));
overrides->SetPath(wxT("/"));
overrides_->SetPath(wxT("/"));
}
}
@ -815,7 +828,6 @@ wxvbamApp::~wxvbamApp() {
free(home);
home = NULL;
}
delete overrides;
#ifndef NO_ONLINEUPDATES
shutdownAutoupdater();
@ -851,7 +863,6 @@ MainFrame::MainFrame()
paused(false),
menus_opened(0),
dialog_opened(0),
focused(false),
#ifndef NO_LINK
gba_link_observer_(config::OptionID::kGBALinkHost,
std::bind(&MainFrame::EnableNetworkMenu, this)),
@ -894,25 +905,35 @@ EVT_MOVE_START(MainFrame::OnMoveStart)
EVT_MOVE_END(MainFrame::OnMoveEnd)
EVT_SIZE(MainFrame::OnSize)
#if defined(__WXMSW__)
// For tracking menubar state.
EVT_MENU_OPEN(MainFrame::MenuPopped)
EVT_MENU_CLOSE(MainFrame::MenuPopped)
EVT_MENU_HIGHLIGHT_ALL(MainFrame::MenuPopped)
#endif // defined(__WXMSW__)
END_EVENT_TABLE()
void MainFrame::OnActivate(wxActivateEvent& event)
{
focused = event.GetActive();
void MainFrame::OnActivate(wxActivateEvent& event) {
const bool focused = event.GetActive();
if (panel && focused)
if (!panel) {
// Nothing more to do if no game is active.
return;
}
if (focused) {
// Set the focus to the game panel.
panel->SetFocus();
}
if (OPTION(kPrefPauseWhenInactive)) {
if (panel && focused && !paused) {
// Handle user preferences for pausing the game when the window is inactive.
if (focused && !paused) {
panel->Resume();
}
else if (panel && !focused) {
} else if (!focused) {
panel->Pause();
}
}
@ -1152,8 +1173,9 @@ void MainFrame::ResetMenuAccelerators() {
ResetRecentAccelerators();
}
void MainFrame::MenuPopped(wxMenuEvent& evt)
{
#if defined(__WXMSW__)
void MainFrame::MenuPopped(wxMenuEvent& evt) {
// We consider the menu closed when the main menubar or system menu is closed, not any submenus.
// On Windows nullptr is the system menu.
if (evt.GetEventType() == wxEVT_MENU_CLOSE && (evt.GetMenu() == nullptr || evt.GetMenu()->GetMenuBar() == GetMenuBar()))
@ -1166,18 +1188,16 @@ void MainFrame::MenuPopped(wxMenuEvent& evt)
// On Windows, opening the menubar will stop the app, but DirectSound will
// loop, so we pause audio here.
void MainFrame::SetMenusOpened(bool state)
{
void MainFrame::SetMenusOpened(bool state) {
menus_opened = state;
#ifdef __WXMSW__
if (menus_opened)
soundPause();
else if (!paused)
soundResume();
#endif
}
#endif // defined(__WXMSW__)
// ShowModal that also disables emulator loop
// uses dialog_opened as a nesting counter
int MainFrame::ShowModal(wxDialog* dlg)
@ -1334,11 +1354,7 @@ int wxvbamApp::FilterEvent(wxEvent& event)
if (event.GetEventType() == wxEVT_KEY_DOWN || event.GetEventType() == wxEVT_KEY_UP) {
// Handle keyboard input events here to generate user input events.
keyboard_input_sender_.ProcessKeyEvent(static_cast<wxKeyEvent&>(event));
return wxEventFilter::Event_Skip;
}
if (!frame->CanProcessShortcuts()) {
keyboard_input_handler_.ProcessKeyEvent(static_cast<wxKeyEvent&>(event));
return wxEventFilter::Event_Skip;
}
@ -1347,6 +1363,10 @@ int wxvbamApp::FilterEvent(wxEvent& event)
return wxEventFilter::Event_Skip;
}
if (!frame->CanProcessShortcuts()) {
return wxEventFilter::Event_Skip;
}
widgets::UserInputEvent& user_input_event = static_cast<widgets::UserInputEvent&>(event);
int command_id = wxID_NONE;
nonstd::optional<config::UserInput> user_input;
@ -1372,10 +1392,41 @@ int wxvbamApp::FilterEvent(wxEvent& event)
return wxEventFilter::Event_Skip;
}
// Queue the associated shortcut command.
wxCommandEvent* command_event = new wxCommandEvent(wxEVT_COMMAND_MENU_SELECTED, command_id);
// Find the associated checkable menu item (if any).
for (const cmditem& cmd_item : cmdtab) {
if (cmd_item.cmd_id == command_id) {
if (cmd_item.mi && cmd_item.mi->IsCheckable()) {
// Toggle the checkable menu item.
cmd_item.mi->Check(!cmd_item.mi->IsChecked());
}
break;
}
}
// Queue the associated shortcut command event.
wxCommandEvent* command_event = new wxCommandEvent(wxEVT_MENU, command_id);
command_event->SetEventObject(this);
frame->GetEventHandler()->QueueEvent(command_event);
return user_input_event.FilterProcessedInput(user_input.value());
}
bool wxvbamApp::ProcessEvent(wxEvent& event) {
if (event.GetEventType() == wxEVT_KEY_DOWN) {
// First, figure out if the focused window can process the key down event.
wxWindow* focused_window = wxWindow::FindFocus();
wxTextCtrl* text_ctrl = wxDynamicCast(focused_window, wxTextCtrl);
if (text_ctrl) {
return wxApp::ProcessEvent(event);
}
wxSpinCtrl* spin_ctrl = wxDynamicCast(focused_window, wxSpinCtrl);
if (spin_ctrl) {
return wxApp::ProcessEvent(event);
}
// Mark the event as processed. This prevents wxWidgets from firing alerts on macOS.
// See https://github.com/wxWidgets/wxWidgets/issues/25262 for details.
return true;
}
return wxApp::ProcessEvent(event);
}

View File

@ -1,12 +1,13 @@
#ifndef VBAM_WX_WXVBAM_H_
#define VBAM_WX_WXVBAM_H_
#include <cstdio>
#include <ctime>
#include <list>
#include <memory>
#include <stdexcept>
#include <typeinfo>
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <wx/log.h>
#include <wx/propdlg.h>
#include <wx/datetime.h>
@ -20,6 +21,7 @@
#include "wx/widgets/dpi-support.h"
#include "wx/widgets/event-handler-provider.h"
#include "wx/widgets/keep-on-top-styler.h"
#include "wx/widgets/keyboard-input-handler.h"
#include "wx/widgets/sdl-poller.h"
#include "wx/widgets/user-input-event.h"
#include "wx/widgets/wxmisc.h"
@ -82,6 +84,7 @@ public:
return false;
}
}
bool ProcessEvent(wxEvent& event) final;
wxString GetConfigDir();
wxString GetDataDir();
@ -97,7 +100,7 @@ public:
bool pending_fullscreen;
#if __WXMAC__
// I suppose making this work will require tweaking the bundle
void MacOpenFile(const wxString& f)
void MacOpenFile(const wxString& f) override
{
pending_load = f;
};
@ -106,7 +109,8 @@ public:
widgets::SdlPoller* sdl_poller() { return &sdl_poller_; }
// vba-over.ini
wxFileConfig* overrides = nullptr;
std::unique_ptr<wxFileConfig> overrides_;
std::unique_ptr<wxFileConfig> gb_overrides_;
wxFileName rom_database;
wxFileName rom_database_scene;
@ -144,7 +148,7 @@ private:
char* home = nullptr;
widgets::SdlPoller sdl_poller_;
widgets::KeyboardInputSender keyboard_input_sender_;
widgets::KeyboardInputHandler keyboard_input_handler_;
// Main configuration file.
wxFileName config_file_;
@ -219,10 +223,15 @@ public:
// possible
void StartModal();
void StopModal();
// however, adding a handler for open/close menu to do the same is unsafe.
// there is no guarantee every show will be matched by a hide.
#if defined(__WXMSW__)
// On Windows, we need to disable the audio loop when the menu is open. We also disable
// shortcuts to prevent issues. This is not necessary on other systems.
void MenuPopped(wxMenuEvent& evt);
#endif // defined(__WXMSW__)
// flags for enabling commands
int cmd_enable;
@ -246,9 +255,6 @@ public:
// Resets all menu accelerators.
void ResetMenuAccelerators();
// 2.8 has no HasFocus(), and FindFocus() doesn't work right
bool HasFocus() const override { return focused; }
#ifndef NO_LINK
// Returns the link mode to set according to the options
LinkMode GetConfiguredLinkMode();
@ -285,7 +291,9 @@ public:
virtual bool MenusOpened() { return menus_opened; }
virtual void SetMenusOpened(bool state);
#if defined(__WXMSW__)
void SetMenusOpened(bool state);
#endif // defined(__WXMSW__)
virtual bool DialogOpened() { return dialog_opened != 0; }
@ -319,8 +327,6 @@ private:
checkable_mi_array_t checkable_mi;
// recent menu item accels
wxMenu* recent;
// quicker & more accurate than FindFocus() != NULL
bool focused;
// One-time toggle to indicate that this object is fully initialized. This
// used to filter events that are sent during initialization.
bool init_complete_ = false;

View File

@ -2,7 +2,7 @@
<resource xmlns="http://www.wxwidgets.org/wxxrc" version="2.5.3.0">
<object class="wxDialog" name="AccelConfig">
<title>Key Shortcuts</title>
<style>wxRESIZE_BORDER</style>
<style>wxRESIZE_BORDER|wxCLOSE_BOX</style>
<object class="wxBoxSizer">
<orient>wxVERTICAL</orient>
<flag>wxEXPAND</flag>
@ -56,6 +56,7 @@
</object>
</object>
<object class="sizeritem">
<flag>wxEXPAND</flag>
<object class="wxBoxSizer">
<object class="sizeritem">
<object class="wxButton" name="Assign">
@ -80,7 +81,6 @@
</object>
<orient>wxVERTICAL</orient>
</object>
<flag>wxEXPAND</flag>
</object>
<object class="sizeritem">
<flag>wxALL</flag>
@ -98,6 +98,7 @@
</object>
</object>
<object class="sizeritem">
<flag>wxEXPAND</flag>
<object class="wxBoxSizer">
<object class="sizeritem">
<flag>wxALL</flag>
@ -113,7 +114,6 @@
</object>
<orient>wxVERTICAL</orient>
</object>
<flag>wxEXPAND</flag>
</object>
</object>
</object>

1
third_party/googletest vendored Submodule

@ -0,0 +1 @@
Subproject commit b514bdc898e2951020cbdca1304b75f5950d1f59

12
third_party/quake3-sqrt/quake3-sqrt.h vendored Normal file
View File

@ -0,0 +1,12 @@
// From Quake 3 Arena.
#include <immintrin.h>
inline float quake3_sqrt(float x) {
__m128 y = _mm_set_ss(x);
__m128 approx = _mm_rsqrt_ss(y);
__m128 half_x = _mm_mul_ss(y, _mm_set_ss(0.5f));
__m128 three_half = _mm_set_ss(1.5f);
__m128 refined = _mm_mul_ss(approx, _mm_sub_ss(three_half, _mm_mul_ss(half_x, _mm_mul_ss(approx, approx))));
return _mm_cvtss_f32(_mm_mul_ss(refined, y));
}

View File

@ -34,8 +34,6 @@ case "\$CC" in
CMAKE_REQUIRED_ARGS="\$CMAKE_REQUIRED_ARGS -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER=\$CC -DCMAKE_CXX_COMPILER=\$CXX"
;;
esac
export CC="ccache \$CC"
export CXX="ccache \$CXX"
fi
;;
esac
@ -179,14 +177,14 @@ DISTS=$DISTS'
libgpg-error https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.45.tar.bz2 lib/libgpg-error.a
libgcrypt https://gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.10.1.tar.bz2 lib/libgcrypt.a
libsecret https://gitlab.gnome.org/GNOME/libsecret/-/archive/0.20.5/libsecret-0.20.5.tar.bz2 lib/libsecret-1.a
sdl2 https://github.com/libsdl-org/SDL/releases/download/release-2.30.3/SDL2-2.30.3.tar.gz lib/libSDL2.a
faudio https://github.com/FNA-XNA/FAudio/archive/refs/tags/24.06.tar.gz lib/libFAudio.a
sdl2 https://github.com/libsdl-org/SDL/releases/download/release-2.30.7/SDL2-2.30.7.tar.gz lib/libSDL2.a
faudio https://github.com/FNA-XNA/FAudio/archive/refs/tags/24.09.tar.gz lib/libFAudio.a
flac https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.4.tar.xz lib/libFLAC.a
harfbuzz https://github.com/harfbuzz/harfbuzz/releases/download/5.1.0/harfbuzz-5.1.0.tar.xz lib/libharfbuzz.a
harfbuzz https://github.com/harfbuzz/harfbuzz/releases/download/10.0.1/harfbuzz-10.0.1.tar.xz lib/libharfbuzz.a
sfml https://github.com/SFML/SFML/archive/refs/tags/2.6.1.tar.gz lib/libsfml-system-s.a
shared-mime-info https://gitlab.freedesktop.org/xdg/shared-mime-info/-/archive/2.2/shared-mime-info-2.2.tar.bz2 bin/update-mime-database
wxwidgets https://github.com/wxWidgets/wxWidgets/releases/download/v3.2.5/wxWidgets-3.2.5.tar.bz2 lib/libwx_baseu-3.*.a
ffmpeg http://ffmpeg.org/releases/ffmpeg-7.0.1.tar.xz lib/libavformat.a
wxwidgets https://github.com/wxWidgets/wxWidgets/releases/download/v3.2.6/wxWidgets-3.2.6.tar.bz2 lib/libwx_baseu-3.*.a
ffmpeg http://ffmpeg.org/releases/ffmpeg-7.0.2.tar.xz lib/libavformat.a
'
BUILD_FFMPEG=1
@ -238,7 +236,6 @@ DIST_CONFIGURE_TYPES="$DIST_CONFIGURE_TYPES
pkgconf autoreconf_noargs
fontconfig autoreconf
libgd autoreconf
harfbuzz autoconf
python2 autoreconf
python3 autoreconf
graphviz autoreconf
@ -274,7 +271,6 @@ DIST_PRE_BUILD="$DIST_PRE_BUILD
sed -i.bak '/SUBDIRS/{; s/ doc//; }' Makefile.am;
graphviz sed -i.bak 's/ -export-symbols/ -Wl,-export-symbols/g' \$(find . -name Makefile.am); \
putsln '#define __declspec(x)' > declspec.h;
harfbuzz touch test/CMakeLists.txt;
xvidcore cd build/generic; \
sed -i.bak '/^all:/{ s/ *\\\$(SHARED_LIB)//; }; \
/^install:/{ s, *\\\$(BUILD_DIR)/\\\$(SHARED_LIB),,; }; \
@ -294,6 +290,7 @@ DIST_PRE_BUILD="$DIST_PRE_BUILD
DIST_POST_BUILD="$DIST_POST_BUILD
pkgconf ln -sf \"\$BUILD_ROOT/root/bin/pkgconf\" \"\$BUILD_ROOT/root/bin/pkg-config\";
ccache setup_ccache
harfbuzz rebuild_dist freetype -Dharfbuzz=enabled;
flex-2.6.3 build_dist flex || :;
libtool ln -sf \"\$BUILD_ROOT/root/bin/libtoolize\" \"\$BUILD_ROOT/root/bin/glibtoolize\";
@ -371,7 +368,7 @@ DIST_ARGS="$DIST_ARGS
libjpeg-turbo -DWITH_JPEG8=ON -DWITH_SIMD=OFF
libtiff --disable-lzma --disable-webp
freetype -Dharfbuzz=disabled
harfbuzz --with-cairo=no --with-icu=no
harfbuzz -Dcairo=disabled -Dicu=disabled
graphite2 -DGRAPHITE2_NFILEFACE=ON -DGRAPHITE2_TESTS=OFF -DGRAPHITE2_DOCS=OFF
flac --disable-ogg
libsoxr -DWITH_OPENMP=NO
@ -445,6 +442,7 @@ builder() {
install_core_deps
setup_perl
setup_meson
setup_ccache
setup_ninja
delete_outdated_dists
pre_build_all
@ -623,6 +621,13 @@ setup_meson() {
fi
}
setup_ccache() {
if command -v ccache >/dev/null; then
ln -sf "$(command -v ccache)" "$BUILD_ROOT/root/bin/${CC##*/}"
ln -sf "$(command -v ccache)" "$BUILD_ROOT/root/bin/${CXX##*/}"
fi
}
setup_ninja() {
if [ -x /usr/local/bin/ninja ]; then
ninja=/usr/local/bin/ninja

1
win32-deps Submodule

@ -0,0 +1 @@
Subproject commit a1e3f425080015a86c9cd53875aa3602230b8b72