diff --git a/.clang-format b/.clang-format index 5041249e9..5a5d0edec 100644 --- a/.clang-format +++ b/.clang-format @@ -1,10 +1,9 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # .clang-format # -# Style configuration file for automatic C++ code formatting using clang-format. -# This file requires at least clang-format version 11.0. +# Style configuration file for automatic C++ and Java code formatting using clang-format. # --- @@ -141,3 +140,17 @@ TabWidth: 8 UseCRLF: false UseTab: Never ... +--- +Language: Java +BraceWrapping: + AfterClass: true + AfterFunction: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBraces: Custom +ColumnLimit: 100 +IndentWidth: 4 +TabWidth: 8 +UseCRLF: false +UseTab: Never diff --git a/.gitignore b/.gitignore index bca68e074..48b3a92b6 100644 --- a/.gitignore +++ b/.gitignore @@ -18,27 +18,33 @@ *.d # Compiled executable -emulationstation -EmulationStation -EmulationStation.exe -es-pdf-convert -es-pdf-convert.exe +/es-de +/ES-DE +/ES-DE.exe +/es-pdf-convert +/es-pdf-converter/es-pdf-convert.exe # Emscripten build -emulationstation.data -emulationstation.html -emulationstation.js -emulationstation.wasm -emulationstation.worker.js +es-de.data +es-de.html +es-de.js +es-de.wasm +es-de.worker.js /index.html /ROMs +# Android +/android +/logback.log +es-core/src/InputOverlay.* +es-core/src/utils/PlatformUtilAndroid.* + # AppImage AppDir *.AppImage # Core dumps -emulationstation.core +es-de.core # Profiling data callgrind.out.* @@ -60,21 +66,21 @@ CMakeFiles cmake_install.cmake Makefile install_manifest.txt -EmulationStation.exe.manifest +ES-DE.exe.manifest # CPack _CPack_Packages -emulationstation-de*.deb -emulationstation-de*.rpm -EmulationStation-DE*.dmg -EmulationStation-DE*.exe +es-de*.deb +es-de*.rpm +ES-DE*.dmg +ES-DE*.exe # macOS .DS_Store # MSVC -EmulationStation.ilk -EmulationStation.pdb +ES-DE.ilk +ES-DE.pdb es-pdf-convert.ilk es-pdf-convert.pdb lunasvg.exp diff --git a/ANDROID.md b/ANDROID.md new file mode 100644 index 000000000..0c7e8bf1b --- /dev/null +++ b/ANDROID.md @@ -0,0 +1,532 @@ +# ES-DE (EmulationStation Desktop Edition) v3.0 (development version) - Android documentation + +This document contains information specific to the Android release, for more general ES-DE documentation refer to the [User guide](USERGUIDE-DEV.md). + +Table of contents: + +[[_TOC_]] + +## First startup and onboarding + +When you first start ES-DE you will be greeted by a welcome screen, this is part of the _configurator_, the ES-DE onboarding interface. The configurator is easy to use and will guide you through the necessary setup steps. + +As a first step you need to give ES-DE the required storage access permission or it will not be able to function. Just enable the setting and the configurator will proceed to the next step. Next you will need to define a application data directory where your settings, scraped media, custom collections and so on will be stored. By default this will be placed in the _ES-DE_ directory in the root of your device's internal storage, and this directory will be created for you automatically. + +After this step you need to select a ROMs directory where your game files will be stored, by default this will be named _ROMs_ and will be located in the root of you device's internal storage. You can however choose to place this on an SD card if you want to, just change the path using the Android file selector GUI. If you do change the path to the SD card you will however need to manually create the ROMs directory as well as to delete the empty directory that was created for you in the built-in storage. + +The next step is optional, and it's whether to create the game systems directory structure inside your ROMs folder. Performing this will also create _systeminfo.txt_ files in each system directory. These files contain information about the system such as what file extensions and emulators that are supported. They are not mandatory for the app to function, they are only there for your convenience. In general it's recommended to create the system directories, although you could remove the ones you don't need afterwards for a slightly faster app startup speed. + +This is basically the onboarding process, and ES-DE should now start up. Just be aware that you need to place at least one game with a supported file extension in the ROMs directory tree or ES-DE will only show an information dialog about missing games. + +Also note that ES-DE does not install any emulators, you need to install those separately. There is more information about that topic later in this document. + +If you need to re-run the configurator for some reason then the easiest way is to go into the Android Apps setting screen and revoke the storage access permissions under _Special app access_. This will make the configurator run automatically next time you start ES-DE. Another way to force it to start is to clear the app's storage under _Storage & cache_ but this is normally not recommended as it also deletes all themes you have downloaded using the theme downloader. A third option would be to rename either the ES-DE or ROMs directory as this will also trigger the configurator on next app startup. + +## Touch input overlay + +By default the touch input overlay will be enabled which makes it possible to use ES-DE without a controller or physical keyboard by overlaying virtual buttons on top of the ES-DE interface. If you are using a device which has a built-in controller you may however want to disable this feature. That is done via the _Enable touch overlay_ option in the _Input device settings_ menu on the main menu. Just be aware that disabling this option on a device where you have no other input method than touch will lock you out of the application. + +If you accidentally disable the touch overlay you can force the configurator to run as explained in the previous section above, this will always reset the touch overlay setting. Another option would of course be to temporarily plug in a controller or keyboard to enable the setting via its menu entry. A third option would be to manually edit the es_settings.xml file in the ES-DE application data directory. The setting you are after is named _InputTouchOverlay_ which should be changed from _false_ to _true_. + +Apart from this there are numerous options for the touch overlay, like the ability to change its size, opacity and fade-out time. Setting the fade-out to zero will make it permanently visible. See the [User guide](USERGUIDE-DEV.md) for a complete reference of all app settings and features. + +## Retention of files and data + +Almost all files saved and used by ES-DE are kept in the shared storage on either the device's built-in storage or on the SD card. This means that uninstalling the ES-DE app will not remove any of that data. The only thing that will be deleted are themes that have been downloaded using the built-in theme downloader, as it's not possible to store these in the ES-DE application data directory for technical reasons. + +## Emulation on Android in general + +There are some challenges with emulation on Android. Some emulators on the Google Play store have not been updated for a long time, or like in the case with RetroArch they are crippled to comply with Google's rules and policies. And some emulators are not available on the Play store at all. For these reasons you will need to sideload some manually downloaded APKs for a good emulation setup. There is a section later in this document describing the best place to get hold of each supported emulator. + +Thankfully sideloading emulators is not very difficult to do, the exact producedure for how to install APKs manually is not covered here but there are many resources available online on how to accomplish this. + +There is also the [F-Droid](https://f-droid.org/) app store as an alternative to Google Play, and this service contains a couple of emulators that are not present on the Play store, or that are present there but haven't been updated for a very long time. + +A number of emulators support the [FileProvider](https://developer.android.com/reference/androidx/core/content/FileProvider) API which makes it possible for ES-DE to temporarily provide storage access to the game ROMs on launch. This means that no access permission needs to be setup in the emulator upfront. For those emulators which do not support the FileProvider API, you will generally need to manually provide scoped storage access to each game system directory. Note that it's not supported to give access to the root of the entire ROM directory for emulators that use scoped storage, it has to be for the specific system. For instance `/storage/emulated/0/ROMs/n64` rather than `/storage/emulated/0/ROMs`. + +Some emulators like RetroArch are still using an older storage access method and for those emulators this is not something you need to consider. + +The following emulators are configured for FileProvider access: +* 2600.emu +* C64.emu +* GBA.emu +* GBC.emu +* Lynx.emu +* MD.emu +* MAME4droid 2024 +* MAME4droid +* NES.emu +* NGP.emu +* PCE.emu +* Play! +* Ruffle +* Saturn.emu +* Swan.emu +* Yuzu + +Some of these emulators still require BIOS files, so not all of them will be completely free from manual configuration. + +The following emulators have partial FileProvider access support but are currently not configured for that in ES-DE: +* Dolphin (the FileProvider interface is broken on some devices) +* M64Plus FZ (the FileProvider interface doesn't work reliably and game launching randomly fails when using it) +* PPSSPP (the FileProvider interface doesn't work with .chd files specifically) + +## Issues with the Ayn Odin 2 + +There are two serious issues that seem to be specific to the Ayn Odin 2, although it remains to be seen whether the problem exists also on other devices. + +The first problem is that some emulators refuse to run games that you place inside directories that contain dots in their names. This is quite problematic as the [directories interpreted as files](USERGUIDE.md#directories-interpreted-as-files) functionality depends on the ability to add file extensions to directory names. + +This has been observed with M64Plus FZ, Play!, Saturn.emu, FPse and FPseNG and it's working fine with RetroArch, NetherSX2, ePSXe, DuckStation and Yuzu. Note however that this is not a complete list as not all emulators have been tested for this problem. + +If you run into this issue you can use the _folder link_ functionality as an alternative to the _directories interpreted as files_ functionality. How to use folder links is described in the [User guide](USERGUIDE.md). + +The second problem is that a number of emulators can't be launched from ES-DE at all. When attempting to run such an emulator an error popup with the game name followed by "ERROR CODE -1" is displayed. The affected emulators are ColEm, fMSX, iNES, MasterGear, My Boy!, My OldBoy!, Redream and Speccy. + +The following devices have been tested and do **not** experience either of these two problems: + +* Ayn Odin Lite (Android 11) +* Retroid Pocket 4 Pro (Android 13) +* Google Pixel 4a (Android 13) +* Google Pixel Tablet (Android 14) + +There are also some issues with sound quality on the Odin 2, such as large fluctuations in volume where some sounds are quite loud and some are quite silent. There are also some strange aliasing effects when playing samples rapidly. + +## Known ES-DE problems + +In addition to the issues specific to the Ayn Odin 2 there are a couple of other problems that will hopefully be resolved in the near future: + +* Poor performance/low frame rate after startup on some devices, which seems to happen randomly and is usually resolved by itself within 10 to 30 seconds. +* The Android soft keyboard causes rendering issues when navigating using a controller or physical keyboard, as such the ES-DE built-in keyboard is enabled by default for the time being. For testing purposes the Android soft keyboard can be enabled via the _Enable virtual keyboard_ option in the _UI settings_ menu. If only using touch input the issue is not present. This problem is believed to be caused by a bug in the SDL library so it probably needs to be resolved there. + +## Emulator installation and setup + +Below are specific instructions and considerations for all supported emulators. + +### RetroArch + +The RetroArch release in the Play Store is not very good and is therefore not recommended. To get access to all cores make sure to instead manually download and install the 64-bit/aarch64 APK from their website. + +https://retroarch.com/ + +Or you could alternatively install their release on the F-Droid store. + +https://f-droid.org/en/packages/com.retroarch + +Be aware that you need to manually install every core you want to use from inside the RetroArch user interface, and you also need to install all necessary BIOS files. The Android release of RetroArch is pretty unforgiving and will usually just present a black screen on game launch if the core file or the BIOS file is missing, and it will hang there until Android realizes the app is not responding and displays a popup where you can choose to kill the process. + +### AetherSX2 / NetherSX2 + +Although the emulator entry is named AetherSX2 the recommended release of this emulator is actually the NetherSX2 patched version as the AetherSX2 release on the Google Play store doesn't work correctly and probably can't be used with ES-DE at all. You'll need to search for this APK online, the filename you'll want is `15210-v1.5-4248-noads.apk` + +If you prefer to apply the NetherSX2 patch yourself (i.e. build the APK) then you can find all relevant information here: + +https://github.com/Trixarian/NetherSX2-patch + +### Citra + +The version of Citra on the Google Play store is very old and barely works. Instead download either the Canary or Nightly builds from the Citra website or use the Citra MMJ fork: + +https://citra-emu.org/download \ +https://github.com/weihuoya/citra/releases + +### ColEm + +This emulator can be installed from the Play store. There is a paid version as well named ColEm Deluxe (ColEm+ ColecoVision Emulator is the store listing name). + +Although this emulator supports both the Adam and ColecoVision systems it can unfortunately not do both interchangeably. In order to play Adam games you need to go into the Emulation settings in ColEm and tick the _Coleco Adam_ box. And likewise you'll need to untick it any time you want to play a ColecoVision game. This is true for launching games from ES-DE as well as starting them from inside the emulator GUI. + +https://play.google.com/store/apps/details?id=com.fms.colem \ +https://play.google.com/store/apps/details?id=com.fms.colem.deluxe + +### Dolphin + +The Play store version is somehow up to date and could be used, otherwise the F-Droid store version is up to date, or you could download the latest release directly from their website. + +https://play.google.com/store/apps/details?id=org.dolphinemu.dolphinemu \ +https://f-droid.org/en/packages/org.dolphinemu.dolphinemu \ +https://dolphin-emu.org/download/ + +In the past there were multiple unofficial ports, but these are not really recommended any longer as most of them don't seem to have been updated in a long time and are likely to have been surpassed by the official Dolphin release. + +### DraStic + +This emulator can be installed from the Play store as a paid app. Note that it does not support launching of zipped game files. + +https://play.google.com/store/apps/details?id=com.dsemu.drastic + +### DuckStation + +The Play store version of this emulator is getting frequent updates and is therefore recommended. + +https://play.google.com/store/apps/details?id=com.github.stenzek.duckstation + +### EKA2L1 + +This emulator can be downloaded from their GitHub site. + +https://github.com/EKA2L1/EKA2L1/releases + +There does not seem to be a way to launch individual EKA2L1 games from a frontend application on Android, instead ES-DE will simply launch the EKA2L1 user interface and you'll have to manually start your game from there. + +### ePSXe + +This emulator can be installed from the Play store as a paid app. + +https://play.google.com/store/apps/details?id=com.epsxe.ePSXe + +### EX Plus Alpha emulators + +These set of emulators also known as the "Robert Broglia" emulators consist of 2600.emu, C64.emu, GBA.emu, GBC.emu, Lynx.emu, NEO.emu, NES.emu, NGP.emu, MD.emu, MSX.emu, PCE.emu, Snes9x EX+, Saturn.emu and Swan.emu + +You can install them via Google Play (as paid apps) or download them from their GitHub automatic build system. + +https://play.google.com/store/apps/developer?id=Robert+Broglia \ +https://github.com/Rakashazi/emu-ex-plus-alpha/actions + +There are also some BIOS files and similar that are needed to run these emulators, and which can be downloaded from their website. + +https://www.explusalpha.com/ + +### Fake-08 + +This RetroArch core is a good port of the official PICO-8 game engine which does not exist on Android. It's not shipped with RetroArch by default though so you need to manaully install it. After download you'll need to place it inside's RetroArch's downloads directory and then install it from the RetroArch app. Details on how to accomplish this can be found on the Internet. Fake-08 can be downloaded from their GitHub site. + +https://github.com/jtothebell/fake-08/releases + +### Flycast + +Flycast is not available on the Play store or the F-Droid store, but it can be downloaded from their GitHub site. + +https://github.com/flyinghead/flycast/releases + +### fMSX + +This emulator can be installed from the Play store. There is a paid version as well named fMSX Deluxe (fMSX+ MSX/MSX2 Emulator is the store listing name). + +https://play.google.com/store/apps/details?id=com.fms.fmsx \ +https://play.google.com/store/apps/details?id=com.fms.fmsx.deluxe + +### FPseNG and FPse + +These emulators can be installed from the Play store as a paid apps. FPseNG is the more modern version so it's probably best to go for that. Note that these emulators do not support .chd files. + +https://play.google.com/store/apps/details?id=com.emulator.fpse64 \ +https://play.google.com/store/apps/details?id=com.emulator.fpse + +### iNES + +This emulator can be installed from the Play store. + +https://play.google.com/store/apps/details?id=com.fms.ines.free + +### MAME4droid 2024 and MAME4droid + +These emulators can be installed from the Play store. It's strongly recommended to go for the _MAME4droid 2024_ version as this is updated with a frequent MAME release while the older _MAME4droid_ is using an ancient MAME release. + +https://play.google.com/store/apps/details?id=com.seleuco.mame4d2024 \ +https://play.google.com/store/apps/details?id=com.seleuco.mame4droid + +### MasterGear + +This emulator can be installed from the Play store as a paid app. + +https://play.google.com/store/apps/details?id=com.fms.mg + +### melonDS + +This emulator can be installed from the Play store but it's quite buggy. Every time you add a new game to the ROM directory you need to start the emulator and manually refresh the game list or you won't be able to launch the game from ES-DE. Filenames containing parentheses also don't work and need to be renamed or they can't be launched from ES-DE. The same is probably true for a number of additional characters. + +https://play.google.com/store/apps/details?id=me.magnum.melonds + +### M64Plus FZ + +This emulator can be installed from the Play store. The Pro version is recommended to avoid annoying ads. + +https://play.google.com/store/apps/details?id=org.mupen64plusae.v3.fzurita.pro \ +https://play.google.com/store/apps/details?id=org.mupen64plusae.v3.fzurita + +### My Boy! and My OldBoy! + +These emulators can be installed from the Play store as paid apps. There are also free/Lite versions availble for these emulators but they have not been updated in years and don't run on modern devices. As such they are not supported by ES-DE. + +https://play.google.com/store/apps/details?id=com.fastemulator.gba \ +https://play.google.com/store/apps/details?id=com.fastemulator.gbc + +### Nesoid + +Nesoid is not available on the Play store but it can be installed from the F-Droid store, or it can be downloaded from their GitHub site. + +https://f-droid.org/en/packages/com.androidemu.nes \ +https://github.com/proninyaroslav/nesoid/releases + +### OpenBOR + +Although OpenBOR is working fine on Android it's not possible to properly integrate it with a frontend, you'll instead need to install your game PAKs into the `/sdcard/OpenBOR/Paks` directory and create dummy .openbor files for your games in `ROMs/openbor` and after launching a game from ES-DE you need to manually start it from inside the OpenBOR GUI. There are more detailed setup instructions in the _OpenBOR_ section of the [User guide](USERGUIDE-DEV.md#openbor). + +You can download OpenBOR from their GitHub site, the version named _OpenBOR v3.0 Build 6391_ has for example been proven to work well. + +https://github.com/DCurrent/openbor/releases + +### Pizza Boy GBA and Pizza Boy GBC + +The Pizza Boy GBA and Pizza Boy GBC emulators can be installed from the Play store. There are Basic (free) versions and Pro (paid) versions available. + +As of writing this, the Basic version of the GBA emulator does not seem to be able to launch games from ES-DE, but the Pro version is working fine. Both the Basic and Pro versions of the GBC emulator are working correctly. + +https://play.google.com/store/apps/details?id=it.dbtecno.pizzaboygba \ +https://play.google.com/store/apps/details?id=it.dbtecno.pizzaboygbapro \ +https://play.google.com/store/apps/details?id=it.dbtecno.pizzaboy \ +https://play.google.com/store/apps/details?id=it.dbtecno.pizzaboypro + +### Play! + +This PlayStation 2 emulator can be downloaded from their website. + +https://www.purei.org/downloads.php + +### PPSSPP + +The Play store version of this emulator is getting frequent updates and is therefore recommended. There is a paid Gold version as well which is functionally identical to the free version. + +https://play.google.com/store/apps/details?id=org.ppsspp.ppsspp \ +https://play.google.com/store/apps/details?id=org.ppsspp.ppssppgold + +### Ruffle + +This emulator can be downloaded from their GitHub site. + +https://github.com/torokati44/ruffle-android/releases + +### Real3DOPlayer + +This 3DO Interactive Multiplayer emulator can be downloaded from their website. + +http://www.arts-union.ru/node/23 + +### Redream + +This emulator can be installed for free from the Play store and can later be upgraded to the Premium version from inside the application. + +https://play.google.com/store/apps/details?id=io.recompiled.redream + +### Speccy + +This emulator can be installed from the Play store. There is a paid version as well named Speccy Deluxe (Speccy+ ZX Spectrum Emulator is the store listing name). + +Although this emulator supports both the Sinclar ZX Spectrum and MGT SAM Coupé systems it can unfortunately not do both interchangeably. In order to play SAM Coupé games you need to go into the Emulation settings in Speccy and select _Sam Coupe_ from the _Computer Model_ selection screen. And likewise you'll need to change it back any time you want to play a ZX Spectrum game. This is true for launching games from ES-DE as well as starting them from inside the emulator GUI. + +https://play.google.com/store/apps/details?id=com.fms.speccy \ +https://play.google.com/store/apps/details?id=com.fms.speccy.deluxe + +### Vita3K + +This PlayStation Vita emulator can be downloaded from their GitHub site. Refer to the User guide for detailed game setup instructions. + +https://github.com/Vita3K/Vita3K-Android/releases + +### Yuzu + +The Play store version of this emulator is getting frequent updates and is therefore recommended. There's an Early Access version as well which is also recommended. + +https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu \ +https://play.google.com/store/apps/details?id=org.yuzu.yuzu_emu.ea + +## Supported game systems + +All emulators are RetroArch cores unless marked as **(Standalone)** + +The **@** symbol indicates that the emulator is _deprecated_ and will be removed in a future ES-DE release. + +| System name | Full name | Default emulator | Alternative emulators | Needs BIOS | Recommended game setup | +| :-------------------- | :--------------------------------------------- | :-------------------------------- | :-------------------------------- | :----------- | :----------------------------------- | +| 3do | 3DO Interactive Multiplayer | Opera | Real3DOPlayer **(Standalone)** | Yes | | +| adam | Coleco Adam | ColEm **(Standalone)** | | No | | +| ags | Adventure Game Studio Game Engine | _Placeholder_ | | | | +| amiga | Commodore Amiga | PUAE | PUAE 2021 | Yes | | +| amiga1200 | Commodore Amiga 1200 | PUAE | PUAE 2021 | Yes | | +| amiga600 | Commodore Amiga 600 | PUAE | PUAE 2021 | Yes | | +| amigacd32 | Commodore Amiga CD32 | PUAE | PUAE 2021 | Yes | | +| amstradcpc | Amstrad CPC | Caprice32 | CrocoDS | No | Single archive or disk file | +| android | Google Android | _Placeholder_ | | | | +| apple2 | Apple II | _Placeholder_ | | | | +| apple2gs | Apple IIGS | _Placeholder_ | | | | +| arcade | Arcade | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
NEO.emu **(Standalone)**,
FinalBurn Neo,
FB Alpha 2012,
Flycast,
Flycast **(Standalone)** | Depends | | +| arcadia | Emerson Arcadia 2001 | _Placeholder_ | | | | +| archimedes | Acorn Archimedes | _Placeholder_ | | | | +| arduboy | Arduboy Miniature Game System | Arduous | | No | Single archive or .hex file | +| astrocde | Bally Astrocade | _Placeholder_ | | | | +| atari2600 | Atari 2600 | Stella | Stella 2014,
2600.emu **(Standalone)** | No | Single archive or ROM file | +| atari5200 | Atari 5200 | a5200 | Atari800 | Yes | Single archive or ROM file | +| atari7800 | Atari 7800 ProSystem | ProSystem | | Yes | Single archive or ROM file | +| atari800 | Atari 800 | Atari800 | | Yes | | +| atarijaguar | Atari Jaguar | Virtual Jaguar | | No | | +| atarijaguarcd | Atari Jaguar CD | _Placeholder_ | | | | +| atarilynx | Atari Lynx | Handy | Beetle Lynx,
Lynx.emu **(Standalone)** | No | Single archive or ROM file | +| atarist | Atari ST [also STE and Falcon] | Hatari | | Yes | Single archive or image file for single-diskette games, .m3u playlist for multi-diskette games | +| atarixe | Atari XE | Atari800 | | Yes | | +| atomiswave | Sammy Corporation Atomiswave | Flycast | Flycast **(Standalone)** | Depends | Single archive file | +| bbcmicro | Acorn Computers BBC Micro | _Placeholder_ | | | | +| c64 | Commodore 64 | VICE x64sc Accurate | VICE x64 Fast,
VICE x64 SuperCPU,
VICE x128,
C64.emu **(Standalone)** | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | +| cdimono1 | Philips CD-i | SAME CDi | | Yes | Single .bin/.cue pair | +| cdtv | Commodore CDTV | PUAE | PUAE 2021 | Yes | | +| chailove | ChaiLove Game Engine | ChaiLove | | | | +| channelf | Fairchild Channel F | FreeChaF | | Yes | Single archive or ROM file | +| coco | Tandy Color Computer | _Placeholder_ | | | | +| colecovision | Coleco ColecoVision | blueMSX | Gearcoleco,
MSX.emu **(Standalone)**,
ColEm **(Standalone)** | Yes | Single archive or ROM file | +| consolearcade | Console Arcade Systems | _Placeholder_ | | | | +| cps | Capcom Play System | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
FinalBurn Neo,
FB Alpha 2012,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Depends | | +| cps1 | Capcom Play System I | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
FinalBurn Neo,
FB Alpha 2012,
FB Alpha 2012 CPS-1 | Depends | | +| cps2 | Capcom Play System II | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
FB Alpha 2012,
FB Alpha 2012 CPS-2 | Depends | | +| cps3 | Capcom Play System III | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
FB Alpha 2012,
FB Alpha 2012 CPS-3 | Depends | | +| crvision | VTech CreatiVision | _Placeholder_ | | | | +| daphne | Daphne Arcade LaserDisc Emulator | DirkSimple | | No | | +| desktop | Desktop Applications | _Placeholder_ | | | | +| doom | Doom | PrBoom | | No | | +| dos | DOS (PC) | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN | No | | +| dragon32 | Dragon Data Dragon 32 | _Placeholder_ | | | | +| dreamcast | Sega Dreamcast | Flycast | Flycast **(Standalone)**,
Redream **(Standalone)** | No | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | +| easyrpg | EasyRPG Game Engine | EasyRPG | | No | | +| electron | Acorn Electron | _Placeholder_ | | | | +| emulators | Emulators | _Placeholder_ | | | | +| epic | Epic Games Store | _Placeholder_ | | | | +| famicom | Nintendo Family Computer | Mesen | Nestopia UE,
FCEUmm,
QuickNES,
NES.emu **(Standalone)**,
iNES **(Standalone)**,
Nesoid **(Standalone)** | No | Single archive or ROM file | +| fba | FinalBurn Alpha | FB Alpha 2012 | FB Alpha 2012 Neo Geo,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Yes | | +| fbneo | FinalBurn Neo | FinalBurn Neo | | Yes | | +| fds | Nintendo Famicom Disk System | Mesen | Nestopia UE,
FCEUmm,
NES.emu **(Standalone)**,
iNES **(Standalone)**,
Nesoid **(Standalone)** | Yes | Single archive or ROM file | +| flash | Adobe Flash | Ruffle **(Standalone)** | | No | Single .swf file | +| fm7 | Fujitsu FM-7 | _Placeholder_ | | | | +| fmtowns | Fujitsu FM Towns | _Placeholder_ | | | | +| fpinball | Future Pinball | _Placeholder_ | | | | +| gamate | Bit Corporation Gamate | _Placeholder_ | | | | +| gameandwatch | Nintendo Game and Watch | Multi (MESS) | MAME4droid 2024 **(Standalone)**,
Handheld Electronic (GW) | No | Single archive or ROM file | +| gamecom | Tiger Electronics Game.com | _Placeholder_ | | | | +| gamegear | Sega Game Gear | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
SMS Plus GX,
PicoDrive,
MasterGear **(Standalone)** | No | Single archive or ROM file | +| gb | Nintendo Game Boy | Gambatte | SameBoy,
Gearboy,
TGB Dual,
DoubleCherryGB,
Mesen-S,
bsnes,
mGBA,
VBA-M,
GBC.emu **(Standalone)**,
My OldBoy! **(Standalone**),
Pizza Boy GBC **(Standalone)** | No | Single archive or ROM file | +| gba | Nintendo Game Boy Advance | mGBA | VBA-M,
VBA Next,
gpSP,
GBA.emu **(Standalone)**,
My Boy! **(Standalone)**,
Pizza Boy GBA **(Standalone)** | No | Single archive or ROM file | +| gbc | Nintendo Game Boy Color | Gambatte | SameBoy,
Gearboy,
TGB Dual,
DoubleCherryGB,
Mesen-S,
bsnes,
mGBA,
VBA-M,
GBC.emu **(Standalone)**,
My OldBoy! **(Standalone**),
Pizza Boy GBC **(Standalone)** | No | Single archive or ROM file | +| gc | Nintendo GameCube | Dolphin | Dolphin **(Standalone)** | No | Disc image file for single-disc games, .m3u playlist for multi-disc games | +| genesis | Sega Genesis | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | No | Single archive or ROM file | +| gmaster | Hartung Game Master | _Placeholder_ | | | | +| gx4000 | Amstrad GX4000 | Caprice32 | CrocoDS | No | Single archive or ROM file | +| intellivision | Mattel Electronics Intellivision | FreeIntv | | Yes | Single archive or ROM file | +| j2me | Java 2 Micro Edition (J2ME) | SquirrelJME | | No | Single .jar file | +| kodi | Kodi Home Theatre Software | _Placeholder_ | | | | +| laserdisc | LaserDisc Games | DirkSimple | | No | | +| lcdgames | LCD Handheld Games | Multi (MESS) | MAME4droid 2024 **(Standalone)**,
Handheld Electronic (GW) | No | Single archive or ROM file | +| lowresnx | LowRes NX Fantasy Console | LowRes NX | | No | Single ROM file | +| lutris | Lutris Open Gaming Platform | _Placeholder_ | | | | +| lutro | Lutro Game Engine | Lutro | | | | +| macintosh | Apple Macintosh | _Placeholder_ | | | | +| mame | Multiple Arcade Machine Emulator | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)**,
NEO.emu **(Standalone)**,
FinalBurn Neo,
FB Alpha 2012,
Flycast,
Flycast **(Standalone)** | Depends | | +| mame-advmame | AdvanceMAME | _Placeholder_ | | | | +| mastersystem | Sega Master System | Genesis Plus GX | Genesis Plus GX Wide,
SMS Plus GX,
Gearsystem,
PicoDrive,
MD.emu **(Standalone)**,
MasterGear **(Standalone)** | No | Single archive or ROM file | +| megacd | Sega Mega-CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | Yes | | +| megacdjp | Sega Mega-CD [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | Yes | | +| megadrive | Sega Mega Drive | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | No | Single archive or ROM file | +| megadrivejp | Sega Mega Drive [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | No | Single archive or ROM file | +| megaduck | Creatronic Mega Duck | SameDuck | | No | Single archive or ROM file | +| mess | Multi Emulator Super System | Multi (MESS) | | | | +| model2 | Sega Model 2 | MAME - Current | | Yes | | +| model3 | Sega Model 3 | _Placeholder_ | | | | +| moto | Thomson MO/TO Series | Theodore | | | | +| msx | MSX | blueMSX | fMSX,
fMSX **(Standalone)**,
MSX.emu **(Standalone)** | Yes except for fMSX standalone | | +| msx1 | MSX1 | blueMSX | fMSX,
fMSX **(Standalone)**,
MSX.emu **(Standalone)** | Yes except for fMSX standalone | | +| msx2 | MSX2 | blueMSX | fMSX,
fMSX **(Standalone)**,
MSX.emu **(Standalone)** | Yes except for fMSX standalone | | +| msxturbor | MSX Turbo R | blueMSX | fMSX,
MSX.emu **(Standalone)** | Yes | | +| mugen | M.U.G.E.N Game Engine | _Placeholder_ | | Yes | | +| multivision | Othello Multivision | Gearsystem | MasterGear **(Standalone)** | No | Single archive or ROM file | +| naomi | Sega NAOMI | Flycast | Flycast **(Standalone)** | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | +| naomi2 | Sega NAOMI 2 | Flycast | Flycast **(Standalone)** | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | +| naomigd | Sega NAOMI GD-ROM | Flycast | Flycast **(Standalone)** | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | +| n3ds | Nintendo 3DS | Citra | Citra **(Standalone)** [Play store version or Nightly],
Citra Canary **(Standalone)**,
Citra MMJ **(Standalone)** | No | Single ROM file | +| n64 | Nintendo 64 | Mupen64Plus-Next | M64Plus FZ **(Standalone)**,
ParaLLEl N64 | No | Single archive or ROM file | +| n64dd | Nintendo 64DD | Mupen64Plus-Next | M64Plus FZ **(Standalone)**,
ParaLLEl N64 | Yes | | +| nds | Nintendo DS | melonDS DS | melonDS **(Standalone)**,
DeSmuME,
DeSmuME 2015,
DraStic **(Standalone)** | No | Single archive or ROM file | +| neogeo | SNK Neo Geo | FinalBurn Neo | NEO.emu **(Standalone)**,
MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)** | Yes | Single archive or ROM file | +| neogeocd | SNK Neo Geo CD | NeoCD | FinalBurn Neo | Yes | | +| neogeocdjp | SNK Neo Geo CD [Japan] | NeoCD | FinalBurn Neo | Yes | | +| nes | Nintendo Entertainment System | Mesen | Nestopia UE,
FCEUmm,
QuickNES,
NES.emu **(Standalone)**,
iNES **(Standalone)**,
Nesoid **(Standalone)** | No | Single archive or ROM file | +| ngage | Nokia N-Gage | EKA2L1 **(Standalone)** | | Yes | See the specific _Symbian and Nokia N-Gage_ section in the User guide | +| ngp | SNK Neo Geo Pocket | Beetle NeoPop | RACE,
NGP.emu **(Standalone)** | No | Single archive or ROM file | +| ngpc | SNK Neo Geo Pocket Color | Beetle NeoPop | RACE,
NGP.emu **(Standalone)** | No | Single archive or ROM file | +| odyssey2 | Magnavox Odyssey 2 | O2EM | | Yes | Single archive or ROM file | +| openbor | OpenBOR Game Engine | OpenBOR **(Standalone)** | | No | See the specific _OpenBOR_ section in the User guide | +| oric | Tangerine Computer Systems Oric | _Placeholder_ | | | | +| palm | Palm OS | Mu | | | | +| pc | IBM PC | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN | No | | +| pc88 | NEC PC-8800 Series | QUASI88 | | Yes | | +| pc98 | NEC PC-9800 Series | Neko Project II Kai | Neko Project II | | | +| pcarcade | PC Arcade Systems | _Placeholder_ | | | | | +| pcengine | NEC PC Engine | Beetle PCE | Beetle PCE FAST,
PCE.emu **(Standalone)** | No | Single archive or ROM file | +| pcenginecd | NEC PC Engine CD | Beetle PCE | Beetle PCE FAST,
PCE.emu **(Standalone)** | Yes | | +| pcfx | NEC PC-FX | Beetle PC-FX | | Yes | | +| pico8 | PICO-8 Fantasy Console | Fake-08 | Retro8 | No | See the specific _PICO-8_ section in the User guide | +| plus4 | Commodore Plus/4 | VICE xplus4 | | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | +| pokemini | Nintendo Pokémon Mini | PokeMini | | No | | +| ports | Ports | ECWolf (Wolfenstein 3D) | NXEngine (Cave Story),
OpenLara (Tomb Raider),
Super Bros War | Yes for ECWolf | | +| ps2 | Sony PlayStation 2 | AetherSX2 **(Standalone)** | Play! **(Standalone)** | Yes for AetherSX2 | | +| ps3 | Sony PlayStation 3 | _Placeholder_ | | | | +| ps4 | Sony PlayStation 4 | _Placeholder_ | | | | +| psp | Sony PlayStation Portable | PPSSPP | PPSSPP **(Standalone)** | No | Single disc image file | +| psvita | Sony PlayStation Vita | Vita3K **(Standalone)** | | Yes | See the specific _Sony PlayStation Vita_ section in the User guide | +| psx | Sony PlayStation | Beetle PSX | Beetle PSX HW,
PCSX ReARMed,
SwanStation,
DuckStation **(Standalone)**,
ePSXe **(Standalone)**,
FPseNG **(Standalone)**,
FPse **(Standalone)** | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | +| pv1000 | Casio PV-1000 | _Placeholder_ | | | | +| quake | Quake | TyrQuake | vitaQuake 2,
vitaQuake 2 [Rogue],
vitaQuake 2 [Xatrix],
vitaQuake 2 [Zaero] | No | | +| samcoupe | MGT SAM Coupé | Speccy **(Standalone)** | | No | Single archive or ROM file | +| satellaview | Nintendo Satellaview | Snes9x - Current | Snes9x 2010,
Snes9x EX+ **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
Mesen-S | | | +| saturn | Sega Saturn | Beetle Saturn | YabaSanshiro,
Yabause,
Saturn.emu **(Standalone)** | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | +| saturnjp | Sega Saturn [Japan] | Beetle Saturn | YabaSanshiro,
Yabause,
Saturn.emu **(Standalone)** | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | +| scummvm | ScummVM Game Engine | ScummVM | | No | | +| scv | Epoch Super Cassette Vision | _Placeholder_ | | | | +| sega32x | Sega Mega Drive 32X | PicoDrive | | No | Single archive or ROM file | +| sega32xjp | Sega Super 32X [Japan] | PicoDrive | | No | Single archive or ROM file | +| sega32xna | Sega Genesis 32X [North America] | PicoDrive | | No | Single archive or ROM file | +| segacd | Sega CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
MD.emu **(Standalone)** | Yes | | +| sfc | Nintendo SFC (Super Famicom) | Snes9x - Current | Snes9x 2010,
Snes9x EX+ **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
Beetle Supafaust,
Mesen-S | No | Single archive or ROM file | +| sg-1000 | Sega SG-1000 | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
blueMSX,
MasterGear **(Standalone)** | No | Single archive or ROM file | +| sgb | Nintendo Super Game Boy | Mesen-S | SameBoy,
mGBA | | Single archive or ROM file | +| snes | Nintendo SNES (Super Nintendo) | Snes9x - Current | Snes9x 2010,
Snes9x EX+ **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
Beetle Supafaust,
Mesen-S | No | Single archive or ROM file | +| snesna | Nintendo SNES (Super Nintendo) [North America] | Snes9x - Current | Snes9x 2010,
Snes9x EX+ **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
Beetle Supafaust,
Mesen-S | No | Single archive or ROM file | +| solarus | Solarus Game Engine | _Placeholder_ | | | | +| spectravideo | Spectravideo | blueMSX | | | | +| steam | Valve Steam | _Placeholder_ | | | | +| stv | Sega Titan Video Game System | MAME - Current | MAME4droid 2024 **(Standalone)**,
MAME4droid **(Standalone)** | Yes | Single archive file | +| sufami | Bandai SuFami Turbo | Snes9x - Current | Snes9x 2010,
Snes9x EX+ **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy | | | +| supergrafx | NEC SuperGrafx | Beetle SuperGrafx | Beetle PCE,
PCE.emu **(Standalone)** | No | Single archive or ROM file | +| supervision | Watara Supervision | Potator | | No | Single archive or ROM file | +| supracan | Funtech Super A'Can | _Placeholder_ | | | | +| switch | Nintendo Switch | Yuzu **(Standalone)** | | Yes | | +| symbian | Symbian | EKA2L1 **(Standalone)** | | Yes | See the specific _Symbian and Nokia N-Gage_ section in the User guide | +| tanodragon | Tano Dragon | _Placeholder_ | | | | +| tg16 | NEC TurboGrafx-16 | Beetle PCE | Beetle PCE FAST,
PCE.emu **(Standalone)** | No | Single archive or ROM file | +| tg-cd | NEC TurboGrafx-CD | Beetle PCE | Beetle PCE FAST,
PCE.emu **(Standalone)** | Yes | | +| ti99 | Texas Instruments TI-99 | _Placeholder_ | | | | +| tic80 | TIC-80 Fantasy Computer | TIC-80 | | No | Single .tic file | +| to8 | Thomson TO8 | Theodore | | | | +| triforce | Namco-Sega-Nintendo Triforce | _Placeholder_ | | | | +| trs-80 | Tandy TRS-80 | _Placeholder_ | | | | +| type-x | Taito Type X | _Placeholder_ | | | | +| uzebox | Uzebox Open Source Console | Uzem | | | | +| vectrex | GCE Vectrex | vecx | | No | Single archive or ROM file | +| vic20 | Commodore VIC-20 | VICE xvic | | No | Single archive or tape, cartridge or diskette image file | +| videopac | Philips Videopac G7000 | O2EM | | Yes | Single archive or ROM file | +| virtualboy | Nintendo Virtual Boy | Beetle VB | | No | | +| vpinball | Visual Pinball | _Placeholder_ | | | | +| vsmile | VTech V.Smile | _Placeholder_ | | | | +| wasm4 | WASM-4 Fantasy Console | WASM-4 | | No | Single .wasm file | +| wii | Nintendo Wii | Dolphin | Dolphin **(Standalone)** | No | | +| wiiu | Nintendo Wii U | _Placeholder_ | | | | +| windows | Microsoft Windows | _Placeholder_ | | | | +| windows3x | Microsoft Windows 3.x | DOSBox-Pure | | No | | +| windows9x | Microsoft Windows 9x | DOSBox-Pure | | No | | +| wonderswan | Bandai WonderSwan | Beetle Cygne | Swan.emu **(Standalone)** | No | Single archive or ROM file | +| wonderswancolor | Bandai WonderSwan Color | Beetle Cygne | Swan.emu **(Standalone)** | No | Single archive or ROM file | +| x1 | Sharp X1 | X Millennium | | No | Single archive or diskette/tape file | +| x68000 | Sharp X68000 | PX68k | | Yes | | +| xbox | Microsoft Xbox | _Placeholder_ | | | | +| xbox360 | Microsoft Xbox 360 | _Placeholder_ | | | | +| zmachine | Infocom Z-machine | _Placeholder_ | | | | +| zx81 | Sinclair ZX81 | EightyOne | | | | +| zxnext | Sinclair ZX Spectrum Next | _Placeholder_ | | | | +| zxspectrum | Sinclair ZX Spectrum | Fuse | Speccy **(Standalone)** | No | Single archive or ROM file | diff --git a/CHANGELOG.md b/CHANGELOG.md index e4894ca69..9e0bad016 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,84 @@ -# EmulationStation Desktop Edition (ES-DE) - Changelog +# ES-DE (EmulationStation Desktop Edition) - Changelog + +## Version 3.0.0 + +**Release date:** 2024-02-17 + +### Release overview + +The 3.0 release rebrands the application from EmulationStation Desktop Edition to simply ES-DE. And as part of this the application data directory has changed from .emulationstation to ES-DE and its internal structure has been improved. There is also a new default theme named Linear that is bundled with the application. + +Support for configurable font sizes has also been added, so assuming the theme supports it, it's now possible to select between these sizes from the _UI settings_ menu. + +A number of minor improvements and bug fixes are also part of this release. + +### Detailed list of changes + +* Renamed the application from EmulationStation Desktop Edition to ES-DE +* Renamed the application data directory from .emulationstation to ES-DE +* Updated the splash screen to reflect the new application name +* Added a new default theme named "Linear" +* Split the es_find_rules.xml and es_systems.xml files for Linux and BSD Unix into separate directories +* Added support for defining font sizes from the theme configuration and selecting these from the UI settings menu +* Added the theme font sizes count to the theme downloader interface +* Added support for medium and large font sizes to the Slate and Modern themes +* Added an option to the Input device settings menu to swap the A/B and X/Y buttons +* Added support for .webp, .svg and unanimated .gif files to the slideshow screensaver when using a custom image directory +* Changed the default slideshow custom image directory from slideshow/custom_images to screensavers/custom_slideshow +* Changed the custom slideshow image directory setting from ScreensaverSlideshowImageDir to ScreensaverSlideshowCustomDir +* The HTTP error code will now be shown on scraper errors instead of the "File is smaller than 350 bytes" message +* Removed the ScraperHaltOnInvalidMedia option and corresponding menu entry as it has been superseded by the HTTP error code logic +* Added a ScraperIgnoreHTTP404Errors option that can be manually set in es_settings.xml to ignore 404 errors (i.e. resource not found) +* Added Mednafen standalone as an alternative emulator for the gb, gba, gbc and supergrafx systems +* Added Mesen standalone as an alternative emulator for the gamegear, mastersystem and multivision systems on Linux, Unix and Windows +* Added Mesen standalone as an alternative emulator for the sg-1000 and supergrafx systems on Linux, Unix and Windows +* Set Mesen standalone to specifically run in Super Game Boy mode for the sgb system on Linux, Unix and Windows +* Added the DoubleCherryGB RetroArch core as an alternative emulator for the gb and gbc systems on Linux, Unix and Windows +* Added the MAME - Current RetroArch core as the default emulator for the gameandwatch and lcdgames systems +* Added the melonDS DS RetroArch core as the default emulator for the nds system +* (Linux) Added support for the AppImage release of Vita3K +* (Linux) Added support for the Flatpak release of puNES +* Added the .zso file extension to the ps2 system +* Added the .zar file extension to the xbox360 system on Linux and Windows +* Added the .pk3 and .ipk3 file extensions to the doom system on Linux, Unix and Windows +* Added the .dirksimple file extension to the daphne and laserdisc systems +* (Unix) Removed the -Minimized flag from the Visual Pinball launch command +* (Windows) Updated the find rules for Visual Pinball to match the actual filenames of the official releases +* (Windows) Added the %RUNINBACKGROUND% variable for the epic system +* When scraping using ScreenScraper, the wheel and wheel-hd media types are now considered equivalent +* Added conversion of an additional HTML character code when scraping using ScreenScraper +* Added a "renderDuringTransitions" property to the image element +* Added a "selectorWidth" property to the textlist element +* Added a "hideIfZero" property to the rating element +* Putting the computer to sleep while a video is playing will no longer result in a massive fast-forward on resume +* Combining video pillarboxes with rounded corners will no longer round corners for the actual video frame (except for extreme values) +* Made the text element "defaultValue" property usable with the metadata types systemName, systemFullname, sourceSystemName and sourceSystemFullname +* Replaced the default d-pad helpsystem images to make them more legible when using smaller screen sizes +* Placeholder entries in es_systems.xml are now skipped by default when creating the system directories and systeminfo.txt files +* Added a CreatePlaceholderSystemDirectories option that can be manually set in es_settings.xml to still create placeholder directories +* Changed the ScreenScraper URL from https://www.screenscraper.fr/api2 to https://api.screenscraper.fr/api2 +* Added support for more extreme vertical resolutions than previously allowed +* Added support for the 19.5:9, 20:9 and 1:1 display aspect ratios +* If any legacy theme configuration is encountered the error messages now simply state that the config is unsupported +* (Windows) Removed support for building the application using MinGW +* The relevant SDL error message is now printed to the log if a controller could not be added +* Added rendering workarounds for some mobile GPUs which do not support all OpenGL operations when using the BGRA pixel format +* Added the UTF8-CPP library as a dependency +* Updated SDL to 2.30.0 on Windows, macOS and the Linux AppImage builds +* Bundled the December 2023 release of the Mozilla TLS/SSL certificates + +### Bug fixes + +* Attempting to create the system directories with invalid entries in es_systems.xml could crash the application +* Sometimes controllers were not added correctly when there was a mix of supported and unsupported devices present +* The last grid row would sometimes not render correctly if fractionalRows was set to true +* Stationary image elements could sometimes glitch out during carousel navigation +* Videos were sometimes positioned incorrectly if combining pillarboxes with rounded corners while using an origin value higher than 0.5 +* An extra space character was appended to text elements when setting the systemdata property to gamecountGames or gamecountGamesNoText +* Theme loading debug output would sometimes print incorrect paths when the configuration included files using variables +* Font textures were sometimes updated with empty glyhps which generated OpenGL errors on some mobile GPUs +* The custom collection editing popup did not show the correct button name if the controller type was a PlayStation variant +* The UI mode confirmation dialog did not show the correct button descriptions if the controller type was PlayStation 1/2/3 ## Version 2.2.1 @@ -18,6 +98,8 @@ Some improvements were also made to the systems sorting functionality. * The Orphaned data cleanup utility will now skip any system where a flatten.txt file is present * Changed a number of error messages in the Orphaned data cleanup utility from uppercase to lowercase * The application release number is now tracked on startup instead of the application version +* (macOS) Reclassified the application as a non-game to disable Game Mode on macOS 14 Sonoma +* (macOS) Added support for the Visual Pinball (vpinball) game system * (slate-es-de) Added console graphics for the adam system * Changed the systems sorting platform from "Peripheral" to "Console" for the fds, megacd, megacdjp, n64dd, pcenginecd and satellaview systems * Changed the systems sorting platform from "Peripheral" to "Console" for the sega32x, sega32xjp, sega32xna, segacd, sgb, sufami and tg-cd systems diff --git a/CMake/Packages/FindOpenGLES3.cmake b/CMake/Packages/FindOpenGLES3.cmake new file mode 100644 index 000000000..5370cdd6e --- /dev/null +++ b/CMake/Packages/FindOpenGLES3.cmake @@ -0,0 +1,32 @@ +# FindOpenGLES +# ------------ +# Finds the OpenGLES3 library +# +# This will define the following variables:: +# +# OPENGLES3_FOUND - system has OpenGLES +# OPENGLES3_INCLUDE_DIRS - the OpenGLES include directory +# OPENGLES3_LIBRARIES - the OpenGLES libraries + +if(NOT HINT_GLES_LIBNAME) + set(HINT_GLES_LIBNAME GLESv3) +endif() + +find_path(OPENGLES3_INCLUDE_DIR GLES3/gl3.h + PATHS "${CMAKE_FIND_ROOT_PATH}/usr/include" + HINTS ${HINT_GLES_INCDIR} +) + +find_library(OPENGLES3_gl_LIBRARY + NAMES ${HINT_GLES_LIBNAME} + HINTS ${HINT_GLES_LIBDIR} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(OpenGLES3 REQUIRED_VARS OPENGLES3_gl_LIBRARY OPENGLES3_INCLUDE_DIR) + +if(OPENGLES3_FOUND) + set(OPENGLES3_LIBRARIES ${OPENGLES3_gl_LIBRARY}) + set(OPENGLES3_INCLUDE_DIRS ${OPENGLES3_INCLUDE_DIR}) + mark_as_advanced(OPENGLES3_INCLUDE_DIR OPENGLES3_gl_LIBRARY) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 4aeec12e7..be3672282 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt # # Main CMake configuration file. @@ -11,15 +11,15 @@ cmake_minimum_required(VERSION 3.13) if(APPLE) # Set this to the minimum supported macOS version, and also update - # es-app/assets/EmulationStation-DE_Info.plist accordingly. + # es-app/assets/ES-DE_Info.plist accordingly. set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "macOS deployment target") # This optional variable is used for code signing the DMG installer. set(MACOS_CODESIGN_IDENTITY "" CACHE STRING "macOS code signing certificate identity") endif() -project(emulationstation-de) +project(es-de) # Application version, update this when making a new release. -set(ES_VERSION 2.2.1) +set(ES_VERSION 3.0.0) # Set this to ON to show verbose compiler output (e.g. compiler flags, include directories etc.) set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "Show verbose compiler output" FORCE) @@ -114,6 +114,8 @@ set_property(CACHE GLSYSTEM PROPERTY STRINGS "Desktop OpenGL" "Embedded OpenGL") if(GLSYSTEM MATCHES "Desktop OpenGL") set(OpenGL_GL_PREFERENCE GLVND) find_package(OpenGL REQUIRED) +elseif(ANDROID) + find_package(OpenGLES3 REQUIRED) elseif(GLES AND NOT EMSCRIPTEN) find_package(OpenGLES2 REQUIRED) endif() @@ -125,11 +127,10 @@ if(APPLE) endif() find_package(CURL REQUIRED) elseif(WIN32) - if(NOT EXISTS ${PROJECT_SOURCE_DIR}/external/pugixml/libpugixml.dll AND # MinGW - NOT EXISTS ${PROJECT_SOURCE_DIR}/external/pugixml/pugixml.dll) # MSVC + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/external/pugixml/pugixml.dll) message(FATAL_ERROR "-- You need to build the dependencies in ./external first") endif() -elseif(NOT EMSCRIPTEN) +elseif(NOT EMSCRIPTEN AND NOT ANDROID) find_package(CURL REQUIRED) find_package(FFmpeg REQUIRED) find_package(FreeImage REQUIRED) @@ -155,19 +156,16 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES Clang) message("-- Compiler is Clang/LLVM") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0.0) - message(SEND_ERROR "You need at least Clang 5.0.0 to compile EmulationStation-DE") + message(SEND_ERROR "You need at least Clang 5.0.0 to compile ES-DE") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES GNU) message("-- Compiler is GNU/GCC") if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.1) - message(SEND_ERROR "You need at least GCC 7.1 to compile EmulationStation-DE") - endif() - if(WIN32) - set(CMAKE_CXX_FLAGS "-mwindows ${CMAKE_CXX_FLAGS}") + message(SEND_ERROR "You need at least GCC 7.1 to compile ES-DE") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES MSVC) message("-- Compiler is MSVC") - # If using the MSVC compiler on Windows, disable the built-in min() and max() macros. + # Disable the built-in min() and max() macros. add_compile_definitions(NOMINMAX) endif() @@ -218,12 +216,17 @@ if(APPLE AND CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 15.0.0) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-utf8") endif() +if(ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -llog") +endif() + if(EMSCRIPTEN) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s USE_SDL=2 -pthread") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s INITIAL_MEMORY=33554432 -s ALLOW_MEMORY_GROWTH=1 -s WASM=1 -s ASSERTIONS=1 -s EXIT_RUNTIME=1 -s USE_SDL=2 \ -pthread -s PTHREAD_POOL_SIZE=4 -s DEMANGLE_SUPPORT=1 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s ASYNCIFY \ - --preload-file ${PROJECT_SOURCE_DIR}/resources@/home/web_user/.emulationstation/resources/ \ - --preload-file ${PROJECT_SOURCE_DIR}/themes/slate-es-de@/home/web_user/.emulationstation/themes/slate-es-de/ \ + --preload-file ${PROJECT_SOURCE_DIR}/resources@/home/web_user/ES-DE/resources/ \ + --preload-file ${PROJECT_SOURCE_DIR}/themes/slate-es-de@/home/web_user/ES-DE/themes/slate-es-de/ \ --preload-file ${PROJECT_SOURCE_DIR}/ROMs@/home/web_user/ROMs/") endif() @@ -278,6 +281,16 @@ if(APPLE) endif() endif() +if(ANDROID) + set(BUNDLED_CERTS ON) + if(ANDROID_LITE_RELEASE) + add_compile_definitions(ANDROID_APPLICATION_ID="org.es_de.frontend.lite") + add_compile_definitions(ANDROID_LITE_RELEASE) + else() + add_compile_definitions(ANDROID_APPLICATION_ID="org.es_de.frontend") + endif() +endif() + if(WIN32) set(BUNDLED_CERTS ON) add_compile_definitions(UNICODE) @@ -348,7 +361,7 @@ if(VIDEO_HW_DECODING) message("-- Building with FFmpeg HW decoding") endif() -if(AUR_BUILD OR FLATPAK_BUILD OR RETRODECK OR RPI) +if(AUR_BUILD OR FLATPAK_BUILD OR RETRODECK OR RPI OR ANDROID) set(APPLICATION_UPDATER OFF) endif() @@ -379,6 +392,23 @@ if(APPLE) endif() endif() +if(ANDROID) + if(ANDROID_ABI MATCHES arm64-v8a) + message("-- Building for Android arm64-v8a on API level ${ANDROID_PLATFORM}") + set(ANDROID_CPU_ARCH arm64-v8a) + elseif(ANDROID_ABI MATCHES x86_64) + message("-- Building for Android x86_64 on API level ${ANDROID_PLATFORM}") + set(ANDROID_CPU_ARCH x86_64) + else() + message(FATAL_ERROR "-- Unsupported Android ABI: " ${ANDROID_ABI}) + endif() + if(ANDROID_LITE_RELEASE) + message("-- Building Lite release") + else() + message("-- Building full release") + endif() +endif() + # Affects the application updater and is used for displaying version info in the main menu. if(ES_VERSION MATCHES alpha OR ES_VERSION MATCHES beta OR ES_VERSION MATCHES dev) add_compile_definitions(IS_PRERELEASE) @@ -390,7 +420,7 @@ add_compile_definitions(GLM_FORCE_XYZW_ONLY) # For Unix systems, assign the installation prefix. If it's not explicitly set, # we use /usr on Linux, /usr/pkg on NetBSD and /usr/local on FreeBSD and OpenBSD. -if(NOT WIN32 AND NOT APPLE) +if(NOT WIN32 AND NOT APPLE AND NOT ANDROID) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(CMAKE_SYSTEM_NAME MATCHES Linux) set(CMAKE_INSTALL_PREFIX /usr CACHE INTERNAL CMAKE_INSTALL_PREFIX) @@ -419,7 +449,9 @@ set(COMMON_INCLUDE_DIRS ${CURL_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/external/lunasvg/include ${CMAKE_CURRENT_SOURCE_DIR}/external/rapidjson/include ${CMAKE_CURRENT_SOURCE_DIR}/external/rlottie/inc - ${CMAKE_CURRENT_SOURCE_DIR}/es-core/src) + ${CMAKE_CURRENT_SOURCE_DIR}/external/utfcpp/source + ${CMAKE_CURRENT_SOURCE_DIR}/es-core/src + ${CMAKE_CURRENT_SOURCE_DIR}/es-pdf-converter/src) if(APPLE) set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} @@ -446,6 +478,15 @@ elseif(EMSCRIPTEN) ${CMAKE_CURRENT_SOURCE_DIR}/external/FreeImage-CMake/FreeImage/Source ${CMAKE_CURRENT_SOURCE_DIR}/external/freetype/include ${CMAKE_CURRENT_SOURCE_DIR}/external/pugixml/src) +elseif(ANDROID) + set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/external/curl/include + ${CMAKE_CURRENT_SOURCE_DIR}/external/ffmpeg-kit/src/ffmpeg + ${CMAKE_CURRENT_SOURCE_DIR}/external/freeimage/FreeImage/Source + ${CMAKE_CURRENT_SOURCE_DIR}/external/freetype/include + ${CMAKE_CURRENT_SOURCE_DIR}/external/libgit2/include + ${CMAKE_CURRENT_SOURCE_DIR}/external/pugixml/src + ${CMAKE_CURRENT_SOURCE_DIR}/external/SDL_Android) else() set(COMMON_INCLUDE_DIRS ${COMMON_INCLUDE_DIRS} ${FFMPEG_INCLUDE_DIRS} @@ -491,44 +532,43 @@ if(APPLE) ${PROJECT_SOURCE_DIR}/libpugixml.a ${PROJECT_SOURCE_DIR}/libSDL2-2.0.0.dylib) elseif(WIN32) - if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(COMMON_LIBRARIES ${PROJECT_SOURCE_DIR}/avcodec.lib - ${PROJECT_SOURCE_DIR}/avfilter.lib - ${PROJECT_SOURCE_DIR}/avformat.lib - ${PROJECT_SOURCE_DIR}/avutil.lib - ${PROJECT_SOURCE_DIR}/swresample.lib - ${PROJECT_SOURCE_DIR}/swscale.lib - ${PROJECT_SOURCE_DIR}/FreeImage.lib - ${PROJECT_SOURCE_DIR}/git2.lib - ${PROJECT_SOURCE_DIR}/glew32.lib - ${PROJECT_SOURCE_DIR}/libcurl-x64.lib - ${PROJECT_SOURCE_DIR}/freetype.lib - ${PROJECT_SOURCE_DIR}/lunasvg.lib - ${PROJECT_SOURCE_DIR}/pugixml.lib - ${PROJECT_SOURCE_DIR}/rlottie.lib - ${PROJECT_SOURCE_DIR}/SDL2main.lib - ${PROJECT_SOURCE_DIR}/SDL2.lib - Winmm.dll) - else() - set(COMMON_LIBRARIES ${PROJECT_SOURCE_DIR}/avcodec-60.dll - ${PROJECT_SOURCE_DIR}/avfilter-9.dll - ${PROJECT_SOURCE_DIR}/avformat-60.dll - ${PROJECT_SOURCE_DIR}/avutil-58.dll - ${PROJECT_SOURCE_DIR}/swresample-4.dll - ${PROJECT_SOURCE_DIR}/swscale-7.dll - ${PROJECT_SOURCE_DIR}/FreeImage.dll - ${PROJECT_SOURCE_DIR}/libgit2.dll - ${PROJECT_SOURCE_DIR}/glew32.dll - ${PROJECT_SOURCE_DIR}/libcurl-x64.dll - ${PROJECT_SOURCE_DIR}/libfreetype.dll - ${PROJECT_SOURCE_DIR}/liblunasvg.dll - ${PROJECT_SOURCE_DIR}/libpugixml.dll - ${PROJECT_SOURCE_DIR}/libSDL2main.a - ${PROJECT_SOURCE_DIR}/librlottie.dll - ${PROJECT_SOURCE_DIR}/SDL2.dll - mingw32 - Winmm.dll) - endif() + set(COMMON_LIBRARIES ${PROJECT_SOURCE_DIR}/avcodec.lib + ${PROJECT_SOURCE_DIR}/avfilter.lib + ${PROJECT_SOURCE_DIR}/avformat.lib + ${PROJECT_SOURCE_DIR}/avutil.lib + ${PROJECT_SOURCE_DIR}/swresample.lib + ${PROJECT_SOURCE_DIR}/swscale.lib + ${PROJECT_SOURCE_DIR}/FreeImage.lib + ${PROJECT_SOURCE_DIR}/git2.lib + ${PROJECT_SOURCE_DIR}/glew32.lib + ${PROJECT_SOURCE_DIR}/libcurl-x64.lib + ${PROJECT_SOURCE_DIR}/freetype.lib + ${PROJECT_SOURCE_DIR}/lunasvg.lib + ${PROJECT_SOURCE_DIR}/pugixml.lib + ${PROJECT_SOURCE_DIR}/rlottie.lib + ${PROJECT_SOURCE_DIR}/SDL2main.lib + ${PROJECT_SOURCE_DIR}/SDL2.lib + Winmm.dll) +elseif(ANDROID) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} + # FFmpeg libraries. + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libavcodec.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libavfilter.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libavformat.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libavutil.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libswresample.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libswscale.so + # Other dependencies. + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libcurl.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libcrypto.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libfreeimage.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libfreetype.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libgit2.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libjpeg.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libpoppler.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libpugixml.a + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libSDL2.so + ${PROJECT_SOURCE_DIR}/android/libs/${ANDROID_CPU_ARCH}/libssl.so) elseif(EMSCRIPTEN) set(COMMON_LIBRARIES ${COMMON_LIBRARIES} # FFmpeg core libraries. @@ -573,16 +613,25 @@ else() endif() if(NOT WIN32) - # SVG rendering library LunaSVG. - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/liblunasvg.a) - # Lottie animation library rlottie. - set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/librlottie.a) + # SVG rendering library LunaSVG and Lottie animation library rlottie. + if(ANDROID) + if(ANDROID_LITE_RELEASE) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/android_lite_${ANDROID_ABI}/liblunasvg.a) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/android_lite_${ANDROID_ABI}/librlottie.a) + else() + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/android_${ANDROID_ABI}/liblunasvg.a) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/android_${ANDROID_ABI}/librlottie.a) + endif() + else() + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/liblunasvg.a) + set(COMMON_LIBRARIES ${COMMON_LIBRARIES} ${PROJECT_SOURCE_DIR}/librlottie.a) + endif() endif() if(APPLE) # See es-app/CMakeLists.txt for an explation for why an extra "Resources" directory # has been added to the install prefix. - set(CMAKE_INSTALL_PREFIX "/Applications/EmulationStation Desktop Edition.app/Contents/Resources") + set(CMAKE_INSTALL_PREFIX "/Applications/ES-DE.app/Contents/Resources") # Set the same rpath links for the install executable as for the build executable. set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -611,6 +660,8 @@ endif() # OpenGL. if(GLSYSTEM MATCHES "Desktop OpenGL") list(APPEND COMMON_LIBRARIES ${OPENGL_LIBRARIES}) +elseif(GLES AND ANDROID) + list(APPEND COMMON_LIBRARIES ${OPENGLES3_LIBRARIES}) elseif(GLES) list(APPEND COMMON_LIBRARIES ${OPENGLES2_LIBRARIES}) endif() @@ -631,5 +682,6 @@ add_subdirectory(es-app) # Make sure that es-pdf-convert is built first, and then that rlottie is built before es-core. # Also set lottie2gif to not be built. add_dependencies(lunasvg es-pdf-convert) + add_dependencies(es-core rlottie) set_target_properties(lottie2gif PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 66fd2d33d..aeeb03431 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) - Contributing +# ES-DE (EmulationStation Desktop Edition) - Contributing ### Help needed diff --git a/CREDITS.md b/CREDITS.md index 60df4ea0a..02c14c5a9 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -1,11 +1,10 @@ -# EmulationStation Desktop Edition (ES-DE) - Credits +# ES-DE (EmulationStation Desktop Edition) - Credits # Programming -**Desktop Edition**\ +**ES-DE**\ Leon Styhre \ -Sophia Hadash \ -Joseph Geumlek +Sophia Hadash **RetroPie fork**\ RetroPie community @@ -74,6 +73,9 @@ https://github.com/Samsung/rlottie SDL \ https://www.libsdl.org +UTF8-CPP \ +https://github.com/nemtrif/utfcpp + Vorbis \ https://gitlab.xiph.org/xiph/vorbis diff --git a/FAQ.md b/FAQ.md index f97782154..594b8ac05 100644 --- a/FAQ.md +++ b/FAQ.md @@ -1,20 +1,16 @@ -# EmulationStation Desktop Edition (ES-DE) - Frequently Asked Questions +# ES-DE (EmulationStation Desktop Edition) - Frequently Asked Questions -## What is this project and how is it related to other EmulationStation forks? +## What's the correct name for the application? ES-DE, EmulationStation etc? -This project started in 2020 as a fork of RetroPie EmulationStation and it has been in very active development ever since. Large parts of the application have been rewritten and much functionality has been added, so overall it's a quite different application by now. - -## What's the correct name? EmulationStation, ES-DE, Emulation Station, EmuStation etc? - -The correct name is EmulationStation Desktop Edition, which is for practical reasons often shortened to EmulationStation-DE or more commonly ES-DE. It's not spelled Emulation Station (i.e. two separate words) in the same manner as you don't write Sony Play Station or Nintendo Game Cube. +As of the 3.0.0 release the official name for the project and application is ES-DE or sometimes ES-DE Frontend. This stands for EmulationStation Desktop Edition as the project originated from the RetroPie fork of EmulationStation in 2020, and was originally intended for desktop computers. However the application has now changed so much that it would just cause confusion to keep the EmulationStation name. During a transition period EmulationStation Desktop Edition will be included as a subtitle on the splash screen and mentioned in some documentation entries, but long term this will be dropped entirely. The red version of the EmulationStation logo will however remain as it's part of the application legacy. ## Is this software available for free, and is it open source? -ES-DE is available for free. Voluntary donations to support the project are however very welcome. The application is released under the MIT open source license with the source code readily available to anyone via the project's [GitLab site](https://gitlab.com/es-de/emulationstation-de). +ES-DE is available for free on Windows, macOS and Linux and it's released under the MIT open source license. ## Which operating systems are supported? -ES-DE runs on Windows, macOS and BSD Unix as well as on multiple Linux distributions including Ubuntu, Fedora, Arch, Manjaro, SteamOS etc. +ES-DE runs on Windows, macOS and multiple Linux distributions including Ubuntu, Fedora, Arch, Manjaro, SteamOS etc. ## What is the relationship between ES-DE and RetroDECK? @@ -22,7 +18,7 @@ ES-DE and [RetroDECK](http://retrodeck.net) are completely separate projects, bu ## What is the relationship between ES-DE and EmuDeck? -[EmuDeck](http://www.emudeck.com) is an installer that installs ES-DE and a number of emulators. There is no relationship between the two projects apart from this, and it's generally not recommended to use EmuDeck as this will lead to a non-standard installation. There are few tangible benefits to using EmuDeck over a manual installation apart from some convenience for the initial setup. Instead it's recommended to setup your emulators manually which will allow you to configure everything exactly to your liking. That is also a fun and interesting experience. +EmuDeck is an installer that installs ES-DE and a number of emulators. There is no relationship between the two projects apart from this, and it's not recommended to use EmuDeck as this will lead to a non-standard installation and can cause a lot of other issues as well. Instead it's recommended to setup your emulators manually which will allow you to configure everything exactly to your liking. ## What game systems/platforms and emulators are supported by ES-DE? @@ -34,7 +30,7 @@ Menus in ES-DE are not lists but grids, sometimes there is only a list but somet ## Can I change the system sorting to not sort by full system names? -Yes the systems sorting configuration file can be selected via the _Systems sorting_ option in the _UI Settings_ menu. There are four such files bundled with ES-DE to sort by _"Release year", "Manufacturer, release year", "Hardware type, release year"_ and _"Manufacturer, hardware type, release year"_. If you don't want to use any of the bundled files then you can create your own custom sorting file and place it into the ~/.emulationstation/custom_systems/ directory. More details about this setup can be found in the _es_systems_sorting.xml_ section of the [Building and advanced configuration](INSTALL.md#es_systems_sortingxml) document. +Yes the systems sorting configuration file can be selected via the _Systems sorting_ option in the _UI Settings_ menu. There are four such files bundled with ES-DE to sort by _"Release year", "Manufacturer, release year", "Hardware type, release year"_ and _"Manufacturer, hardware type, release year"_. If you don't want to use any of the bundled files then you can create your own custom sorting file and place it into the ~/ES-DE/custom_systems/ directory. More details about this setup can be found in the _es_systems_sorting.xml_ section of the [Building and advanced configuration](INSTALL.md#es_systems_sortingxml) document. ## I'm missing some systems like SNES MSU-1 and WiiWare, could those get added to ES-DE? @@ -46,7 +42,7 @@ ES-DE comes preconfigured with support for many alternative emulators, see the [ ## I'm on Windows and ES-DE can't find my emulators, what is wrong? -On Windows ES-DE is shipped as a portable installation and as a regular installer. If you're using the portable installation you need to drop your emulators inside the Emulators directory. Make sure to read the README.txt file directly in the EmulationStation-DE folder for more details. For the regular installer many emulators do not provide a method to inform ES-DE where they are installed, so you will need to add their installation directories to the Path environment variable in Windows. It's strongly recommended to read the _Specific notes for Windows_ section of the [User guide](USERGUIDE.md#specific-notes-for-windows) before attempting to setup and use ES-DE on Windows. +On Windows ES-DE is shipped as a portable installation and as a regular installer. If you're using the portable installation you need to drop your emulators inside the Emulators directory. Make sure to read the README.txt file directly in the ES-DE folder for more details. For the regular installer many emulators do not provide a method to inform ES-DE where they are installed, so you will need to add their installation directories to the Path environment variable in Windows. It's strongly recommended to read the _Specific notes for Windows_ section of the [User guide](USERGUIDE.md#specific-notes-for-windows) before attempting to setup and use ES-DE on Windows. ## I'm on Windows and ES-DE refuses to start, is the application broken? @@ -54,7 +50,7 @@ You're probably missing the OpenGL drivers required to run ES-DE. Try to downloa ## I'm on Windows and there is only a black screen shown on startup or when launching a game, is there a way to fix this? -This behavior has been observed for some specific AMD GPUs in the past. In some instances there is only a black screen on startup and in some instances the application starts and runs correctly but launching a game only shows a black screen. The issue is seemingly caused by GPU driver bugs and it only affects Windows as Linux works fine with the same hardware. The workaround is to make ES-DE run in windowed mode. You accomplish this by using the --resolution flag and setting the width to one pixel wider than your screen resolution. So if for instance running at a 1280x800 display resolution, run ES-DE such as this: `EmulationStation.exe --resolution 1281 800` +This behavior has been observed for some specific AMD GPUs in the past. In some instances there is only a black screen on startup and in some instances the application starts and runs correctly but launching a game only shows a black screen. The issue is seemingly caused by GPU driver bugs and it only affects Windows as Linux works fine with the same hardware. The workaround is to make ES-DE run in windowed mode. You accomplish this by using the --resolution flag and setting the width to one pixel wider than your screen resolution. So if for instance running at a 1280x800 display resolution, run ES-DE such as this: `ES-DE.exe --resolution 1281 800` ## The emulators don't seem to be properly configured? @@ -84,13 +80,9 @@ See the question above for a possible solution. Another approach would be to hid No, by default games are not removed from the gamelists when they are hidden and are instead only marked with a much lower opacity. You need to disable the setting _Show hidden games_ from the _Other Settings_ menu to make them disappear entirely. The reason this option is not disabled by default is that new users could very easily make a mistake by hiding some files accidentally without realizing it, only to have the entries being immediately removed from the gamelist view. It's also good practice to hide all your games with this option enabled and verify that it's all correct before going ahead and disabling it. -## I'm using Linux or macOS and I can't find the .emulationstation directory, where is it located? - -The .emulationstation directory is normally located in your home directory, but on these Unix-based operating systems files and directories starting with a dot are hidden by default. So you need to enable hidden files and directories in your file manager. On macOS this is done in Finder using the Shift + Command + . (a dot) keyboard combination. On Linux it depends on which file manager you're using, but in KDE's Dolphin it's accomplished by using the Alt + . (a dot) keyboard combination or via the corresponding entry in the hamburger menu. - ## I can't find a ROM directory setting in the user interface, so how do I relocate my games? -There is no need for such a setting as ES-DE will not start unless it finds at least one game. So you simply need to move your ROM directory to its new location using your operating system's file manager or terminal and then the next time you start ES-DE you will be shown a dialog where you can enter the new directory. Optionally you can manually change the ROMDirectory setting in ~/.emulationstation/es_settings.xml +There is no need for such a setting as ES-DE will not start unless it finds at least one game. So you simply need to move your ROM directory to its new location using your operating system's file manager or terminal and then the next time you start ES-DE you will be shown a dialog where you can enter the new directory. Optionally you can manually change the ROMDirectory setting in ~/ES-DE/es_settings.xml ## What are miximages precisely and why don't they get updated when I change my miximage settings? @@ -98,7 +90,7 @@ As the name implies these are images, and more specifically they are generated b ## Is there a way to customize existing systems, and/or to add more systems than those shipped by default? -Yes it's possible to both customize existing systems that are part of the bundled configuration as well as to add more systems than those shipped with ES-DE. Almost nothing is hardcoded in the application so there is a huge flexibility when it comes to such configuration. How this is done is covered in the _Game system customizations_ section of the [User guide](USERGUIDE.md#game-system-customizations). Just make sure to never modify the es_systems.xml and es_find_rules.xml files included in the application installation directory as these will be overwritten when upgrading ES-DE in the future. Always place your customizations in ~/.emulationstation/custom_systems/ as is also described in the user guide. +Yes it's possible to both customize existing systems that are part of the bundled configuration as well as to add more systems than those shipped with ES-DE. Almost nothing is hardcoded in the application so there is a huge flexibility when it comes to such configuration. How this is done is covered in the _Game system customizations_ section of the [User guide](USERGUIDE.md#game-system-customizations). Just make sure to never modify the es_systems.xml and es_find_rules.xml files included in the application installation directory as these will be overwritten when upgrading ES-DE in the future. Always place your customizations in ~/ES-DE/custom_systems/ as is also described in the user guide. ## Can I use the Steam release of RetroArch? @@ -110,7 +102,7 @@ You would normally use the built-in theme downloader to install additional theme ## I added some EmulationStation themes manually but they don't seem to show up inside ES-DE? -Only themes made specifically for ES-DE can be used. If you want to use a theme from Batocera, Recalbox, RetroBat, RetroPie etc. then it first needs to be ported to the ES-DE theme engine. If you place a non-supported theme in the ~/.emulationtation/themes/ directory then this will be ignored on startup, meaning it will not be selectable from the _UI Settings_ menu. +EmulationStation themes are not supported by ES-DE. If you want to use a theme from Batocera, Recalbox, RetroBat, RetroPie etc. then it first needs to be ported to the ES-DE theme engine. If you place a non-supported theme in the ES-DE/themes/ directory then this will be ignored on startup, meaning it will not be selectable from the _UI Settings_ menu. ## I used to be a Batocera/Recalbox user and ES-DE can't seem to find some of my games? @@ -122,15 +114,11 @@ There is a built-in application updater that works with the Linux AppImage relea ## I can't find any game media links in the gamelist.xml files, where is this data stored? -ES-DE works differently compared to all other EmulationStation forks when it comes to handling of game media. There are no links in the gamelist.xml files, instead media files are matched against the ROM/game file names which makes for a much simpler, faster and completely portable setup. Migrating game media from other EmulationStation forks (and potentially from other frontends as well) can be accomplished quite easily. See the next question below for more information. Make sure to also read the _Migrating from other EmulationStation forks_ section of the [User guide](USERGUIDE.md#migrating-from-other-emulationstation-forks) to avoid data loss if running ES-DE with existing data from another EmulationStation fork. +ES-DE works differently compared to EmulationStation when it comes to handling of game media. There are no links in the gamelist.xml files, instead media files are matched against the ROM/game file names which makes for a much simpler, faster and completely portable setup. Migrating game media from EmulationStation (and potentially from other frontends as well) can be accomplished quite easily. Make sure to also read the _Migrating from EmulationStation_ section of the [User guide](USERGUIDE.md#migrating-from-emulationstation) to avoid data loss if running ES-DE with existing data from EmulationStation. ## It seems like gamelist.xml files in the ROM directory tree are not getting loaded? -These files are not loaded by default as of ES-DE 2.0.0, only files placed in .emulationstation/gamelists/ are processed. If you insist on retaining the old logic of also looking for gamelist.xml files in the ROM directory tree then you can enable the LegacyGamelistFileLocation setting in es_settings.xml as explained in the _Settings not configurable via the GUI_ section of the [Building and advanced configuration](INSTALL.md#settings-not-configurable-via-the-gui) document. - -## Why do I sometimes get error messages when scraping stating that files are less than 350 bytes in size? - -This issue can occur occassionally as the ScreenScraper servers sometimes return invalid responses, in this case simply pressing the _RETRY_ button often works. But there is also a ScreenScraper bug where their cache could include entries that no longer exist. When a media file is removed from the ScreenScraper database, the cached link to that file is retained for some time and will be returned as a valid media file URL to ES-DE. However, when attempting to scrape such a file, it will only contain the text string _NOMEDIA_ which will trigger this error in ES-DE. The cache bug only affects the multi-scraper API call, so a workaround is to manually scrape such games using the single-game scraper (reachable via the metadata editor). The invalid cache entries seem to disappear within 24 hours so waiting for a while and rescraping should also resolve the problem. The issue has been reported to the ScreenScraper team but it's unclear if and when it will be resolved. +These files are not loaded by default, only files placed in ES-DE/gamelists/ are processed. If you insist on also looking for gamelist.xml files in the ROM directory tree then you can enable the LegacyGamelistFileLocation setting in es_settings.xml as explained in the _Settings not configurable via the GUI_ section of the [Building and advanced configuration](INSTALL.md#settings-not-configurable-via-the-gui) document. ## Can I use an external scraper application instead of the built-in scraper? diff --git a/INSTALL-DEV.md b/INSTALL-DEV.md index 3c33c97af..614b80ff3 100644 --- a/INSTALL-DEV.md +++ b/INSTALL-DEV.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 (development version) - Building and advanced configuration +# ES-DE (EmulationStation Desktop Edition) v3.0 (development version) - Building and advanced configuration This document is only relevant for the current ES-DE development version, if you would like to see the documentation for the latest stable release, refer to [INSTALL.md](INSTALL.md) instead. @@ -162,7 +162,7 @@ make -j8 ``` Due to buggy AMD GPU drivers it could be a good idea to use the `LSAN_suppressions` file included in the repository to avoid reports of a lot of irrelevant issue, for example: ``` -LSAN_OPTIONS="suppressions=tools/LSAN_suppressions" ./emulationstation --debug --resolution 2560 1440 +LSAN_OPTIONS="suppressions=tools/LSAN_suppressions" ./es-de --debug --resolution 2560 1440 ``` This applies to LeakSanitizer specifically, which is integrated into AddressSanitizer. @@ -175,7 +175,7 @@ make -j8 It could also be a good idea to use the `TSAN_suppressions` file included in the repository to suppress issues reported by some third party libraries, for example: ``` -TSAN_OPTIONS="suppressions=tools/TSAN_suppressions" ./emulationstation --debug --resolution 2560 1440 +TSAN_OPTIONS="suppressions=tools/TSAN_suppressions" ./es-de --debug --resolution 2560 1440 ``` To enable UndefinedBehaviorSanitizer which helps with identifying bugs that may otherwise be hard to find, build with the UBSAN option: @@ -196,17 +196,17 @@ As for advanced debugging, Valgrind is a very powerful and useful tool which can The most common tool is Memcheck to check for memory leaks, which you run like this: ``` -valgrind --tool=memcheck --leak-check=full --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=memcheck --leak-check=full --log-file=../valgrind_run_01 ./es-de ``` There are numerous flags that can be used, for example this will also track reachable memory which could indicate further leaks: ``` -valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes --log-file=../valgrind_run_01 ./es-de ``` Another helpful tool is the Callgrind call-graph analyzer: ``` -valgrind --tool=callgrind --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=callgrind --log-file=../valgrind_run_01 ./es-de ``` The output file can be loaded into an application such as KCachegrind for data analysis. @@ -215,7 +215,7 @@ The output file can be loaded into an application such as KCachegrind for data a Yet another very useful Valgrind tool is the Massif heap profiler, which can be run like this: ``` -valgrind --tool=massif --massif-out-file=../massif.out.01 ./emulationstation +valgrind --tool=massif --massif-out-file=../massif.out.01 ./es-de ``` The output file can be loaded into an application such as Massif-Visualizer for analysis. @@ -303,35 +303,35 @@ sudo make install Assuming the default installation prefix /usr has been used, this is the directory structure for the installation: ``` -/usr/bin/emulationstation +/usr/bin/es-de /usr/bin/es-pdf-convert -/usr/share/applications/org.es_de.emulationstation-de.desktop -/usr/share/emulationstation/licenses/* -/usr/share/emulationstation/resources/* -/usr/share/emulationstation/themes/* -/usr/share/emulationstation/LICENSE -/usr/share/icons/hicolor/scalable/apps/org.es_de.emulationstation-de.svg -/usr/share/man/man6/emulationstation.6.gz -/usr/share/metainfo/org.es_de.emulationstation-de.appdata.xml -/usr/share/pixmaps/org.es_de.emulationstation-de.svg +/usr/share/applications/org.es_de.frontend.desktop +/usr/share/es-de/licenses/* +/usr/share/es-de/resources/* +/usr/share/es-de/themes/* +/usr/share/es-de/LICENSE +/usr/share/icons/hicolor/scalable/apps/org.es_de.frontend.svg +/usr/share/man/man6/es-de.6.gz +/usr/share/metainfo/org.es_de.frontend.appdata.xml +/usr/share/pixmaps/org.es_de.frontend.svg ``` However, when installing manually instead of building a package, it's recommended to change the install prefix to /usr/local instead of /usr. -Be aware that if using the GNOME desktop environment, /usr/share/pixmaps/emulationstation.svg must exist in order for the ES-DE icon to be shown in the Dash and task switcher. +Be aware that if using the GNOME desktop environment, /usr/share/pixmaps/org.es_de.frontend.svg must exist in order for the ES-DE icon to be shown in the Dash and task switcher. ES-DE will look in the following locations for application resources, in the listed order: -* \/.emulationstation/resources/ -* \/share/emulationstation/resources/ +* \/ES-DE/resources/ +* \/share/es-de/resources/ * \/resources/ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \/.emulationstation/themes/ -* \/share/emulationstation/themes/ +* \/ES-DE/themes/ +* \/share/es-de/themes/ * \/themes/ A theme is not mandatory to start the application, but ES-DE will be basically useless without it. @@ -346,23 +346,23 @@ Creation of Debian .deb packages is enabled by default, simply run `cpack` to ge myusername@computer:~/emulationstation-de$ cpack CPack: Create package using DEB CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package CPackDeb: - Generating dependency list -CPack: - package: /home/myusername/emulationstation-de/emulationstation-de-2.2.0-x64.deb generated. +CPack: - package: /home/myusername/emulationstation-de/es-de_3.0.0-x64.deb generated. ``` You may want to check that the dependencies look fine, as they're (mostly) automatically generated by CMake: ``` -dpkg -I ./emulationstation-de-2.2.0-x64.deb +dpkg -I ./es-de_3.0.0-x64.deb ``` The package can now be installed using a package manager, for example apt: ``` -sudo apt install ./emulationstation-de-2.2.0-x64.deb +sudo apt install ./es-de_3.0.0-x64.deb ``` To build an RPM package instead, set the flag LINUX_CPACK_GENERATOR to RPM when running cmake, for example: @@ -377,11 +377,11 @@ Then simply run `cpack`: myusername@computer:~/emulationstation-de$ cpack CPack: Create package using RPM CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPackRPM: Will use GENERATED spec file: /home/myusername/emulationstation-de/_CPack_Packages/Linux/RPM/SPECS/emulationstation-de.spec -CPack: - package: /home/myusername/emulationstation-de/emulationstation-de-2.2.0-x64.rpm generated. +CPackRPM: Will use GENERATED spec file: /home/myusername/emulationstation-de/_CPack_Packages/Linux/RPM/SPECS/es-de.spec +CPack: - package: /home/myusername/emulationstation-de/es-de_3.0.0-x64.rpm generated ``` On Fedora, you need to install rpmbuild before this command can be run: @@ -391,17 +391,17 @@ sudo dnf install rpm-build After the package generation you can check that the metadata looks fine using the `rpm` command: ``` -rpm -qi ./emulationstation-de-2.2.0-x64.rpm +rpm -qi ./es-de_3.0.0-x64.rpm ``` To see the automatically generated dependencies, run this: ``` -rpm -q --requires ./emulationstation-de-2.2.0-x64.rpm +rpm -q --requires ./es-de_3.0.0-x64.rpm ``` And of course, you can also install the package: ``` -sudo dnf install ./emulationstation-de-2.2.0-x64.rpm +sudo dnf install ./es-de_3.0.0-x64.rpm ``` **Creating an AppImage** @@ -576,37 +576,37 @@ make install This will be the directory structure for the installation: ``` -/Applications/EmulationStation Desktop Edition.app/Contents/Info.plist -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/EmulationStation -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/es-pdf-convert -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libSDL2-2.0.0.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavcodec.60.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavfilter.9.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavformat.60.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavutil.58.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libfontconfig.1.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libfreetype.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libgit2.1.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libjpeg.62.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libopenjp2.7.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpoppler-cpp.0.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpoppler.129.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpostproc.57.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libswresample.4.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libswscale.7.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libtiff.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libvorbis.0.4.9.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libvorbisenc.2.0.12.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/EmulationStation-DE.icns -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/LICENSE -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/licenses/* -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/resources/* -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/themes/* +/Applications/ES-DE.app/Contents/Info.plist +/Applications/ES-DE.app/Contents/MacOS/ES-DE +/Applications/ES-DE.app/Contents/MacOS/es-pdf-convert +/Applications/ES-DE.app/Contents/MacOS/libSDL2-2.0.0.dylib +/Applications/ES-DE.app/Contents/MacOS/libavcodec.60.dylib +/Applications/ES-DE.app/Contents/MacOS/libavfilter.9.dylib +/Applications/ES-DE.app/Contents/MacOS/libavformat.60.dylib +/Applications/ES-DE.app/Contents/MacOS/libavutil.58.dylib +/Applications/ES-DE.app/Contents/MacOS/libfontconfig.1.dylib +/Applications/ES-DE.app/Contents/MacOS/libfreetype.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libgit2.1.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libjpeg.62.dylib +/Applications/ES-DE.app/Contents/MacOS/libopenjp2.7.dylib +/Applications/ES-DE.app/Contents/MacOS/libpoppler-cpp.0.dylib +/Applications/ES-DE.app/Contents/MacOS/libpoppler.129.dylib +/Applications/ES-DE.app/Contents/MacOS/libpostproc.57.dylib +/Applications/ES-DE.app/Contents/MacOS/libswresample.4.dylib +/Applications/ES-DE.app/Contents/MacOS/libswscale.7.dylib +/Applications/ES-DE.app/Contents/MacOS/libtiff.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libvorbis.0.4.9.dylib +/Applications/ES-DE.app/Contents/MacOS/libvorbisenc.2.0.12.dylib +/Applications/ES-DE.app/Contents/Resources/ES-DE.icns +/Applications/ES-DE.app/Contents/Resources/LICENSE +/Applications/ES-DE.app/Contents/Resources/licenses/* +/Applications/ES-DE.app/Contents/Resources/resources/* +/Applications/ES-DE.app/Contents/Resources/themes/* ``` ES-DE will look in the following locations for application resources, in the listed order: -* \/.emulationstation/resources/ +* \/ES-DE/resources/ * \/../Resources/resources/ * \/resources/ @@ -614,7 +614,7 @@ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \/.emulationstation/themes/ +* \/ES-DE/themes/ * \/../Resources/themes/ * \/themes/ @@ -630,19 +630,15 @@ Simply run `cpack` to build a .dmg disk image/installer: myusername@computer:~/emulationstation-de$ cpack CPack: Create package using Bundle CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPack: - package: /Users/myusername/emulationstation-de/EmulationStation-DE-2.2.0-x64.dmg generated. +CPack: - package: /Users/myusername/emulationstation-de/ES-DE_3.0.0-arm64.dmg generated. ``` ## Building on Windows -Although both Microsoft Visual C++ (MSVC) and GCC (MinGW) have historically been supported for building ES-DE on Windows, as of the 2.2.0 release MinGW is no longer recommended and support for it will likely be dropped in future releases. - -Although MinGW produces much higher quality code than MSVC with ES-DE running around 10% to 25% faster it's unfortunately not sustainable to keep using it. There are multiple technical issues with third party libraries like severe threading issues with FFmpeg and some libraries like Poppler not being readily available. Debugging with MinGW is also a very slow and tedious process compared to MSVC. MinGW up to 9.2.0 works more or less fine but anything more modern than this introduces issues like FFmpeg's avfilter_graph_free() call taking up to 7000 times longer to complete which makes video playback unusable. Setting filter graphs to use single threads solves some but not all issues. As well libgit2 has (probably) a race condition that causes random repository corruption that is likely only present when using MinGW. - -Clang/LLVM has also been evaluated but it suffers from at least the same threading issues as MinGW, likely because it uses libraries from the latter. It also fails to build some of the third party libraries needed by ES-DE. +Only the Microsoft Visual C++ (MSVC) compiler is supported on Windows. Although MinGW/GCC produces higher quality code with ES-DE running around 10% to 25% faster it's unfortunately not sustainable to use it. There are multiple technical issues with third party libraries like severe threading issues with FFmpeg and some libraries like Poppler not being readily available. **MSVC setup** @@ -679,21 +675,6 @@ The way the MSVC environment works is that a specific developer shell is provide It's important to choose the x64-specific shell and not the x86 variant, as ES-DE will only compile as a 64-bit application. -**MinGW (GCC) setup** - -Download the following packages and install them: - -[https://gitforwindows.org](https://gitforwindows.org) - -[https://cmake.org/download](https://cmake.org/download) - -Download the _MinGW-w64 based_ version of GCC: \ -[https://jmeubank.github.io/tdm-gcc](https://jmeubank.github.io/tdm-gcc) - -After installation, make a copy of `TDM-GCC-64\bin\mingw32-make` to `make` for your convenience. - -Only version 9.2.0 of MinGW has been confirmed to work correctly, anything newer introduces severe problems and MSVC should instead be used if a more modern compiler is required. - **Other preparations** In order to get clang-format onto the system you need to download and install Clang/LLVM: \ @@ -709,7 +690,7 @@ Configure Git. Details about its setup is beyond the scope of this document, but It's strongly recommended to set line breaks to Unix-style (line feed only) directly in the code editor. But if not done, lines breaks will anyway be converted when running clang-format on the code, as explained [here](INSTALL-DEV.md#using-clang-format-for-automatic-code-formatting). -The instructions below assume all build steps for MSVC are done in the MSVC developer console (x64 Native Tools Command Prompt for VS) and all MinGW build steps are done using the Git Bash shell. +The instructions below assume all build steps for MSVC are done in the MSVC developer console (x64 Native Tools Command Prompt for VS). **Cloning and setting up dependencies** @@ -726,29 +707,21 @@ cd emulationstation-de git checkout stable-2.2 ``` -On Windows all dependencies are kept in-tree in the `external` directory tree. Most of the libraries can be downloaded in binary form, but a few need to be built from source code. There are four scripts in the tools directory that automate this entirely. Two of them are used for the MSVC compiler and the other two for MinGW. +On Windows all dependencies are kept in-tree in the `external` directory tree. Most of the libraries can be downloaded in binary form, but a few need to be built from source code. There are two scripts in the tools directory that automate this entirely. You run them like this: -For MSVC, you run them like this: ``` cd emulationstation-de -tools\Windows_dependencies_setup_MSVC.bat -tools\Windows_dependencies_build_MSVC.bat -``` - -And for MinGW like the following: -``` -cd emulationstation-de -tools/Windows_dependencies_setup_MinGW.sh -tools/Windows_dependencies_build_MinGW.sh +tools\Windows_dependencies_setup.bat +tools\Windows_dependencies_build.bat ``` Re-running the setup script will delete and download all dependencies again, and re-running the build script will clean and rebuild from scratch. -The setup scripts for both MSVC and MinGW will download and launch an installer for OpenSSL for Windows if this has not already been installed on the build machine. Just run through the installer using the default settings and everything should work fine. +The setup scripts will download and launch an installer for OpenSSL for Windows if this has not already been installed on the build machine. Just run through the installer using the default settings and everything should work fine. Following these preparations, ES-DE should be ready to be compiled. -**Building ES-DE using MSVC** +**Building ES-DE** It's assumed that [Jom](https://wiki.qt.io/Jom) is used, but if instead using nmake then just remove _JOM_ from the -G flag argument and remove the -j flag as nmake does not support building in parallel. @@ -777,31 +750,7 @@ nmake ThreadSanitizer and UndefinedBehaviorSanitizer aren't available for the MSVC compiler. -There are a number of compiler warnings for the bundled rlottie library when building with MSVC. Unfortunately these need to be resolved upstream, but everything should still work fine so the warnings can be ignored for now. - -**Building ES-DE using MinGW** - -For a release build: - -``` -cmake -G "MinGW Makefiles" . -make -j8 -``` - -Or for a debug build: - -``` -cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug . -make -j8 -``` - -Change the -j flag to whatever amount of parallel threads you want to use for the compilation. - -Unfortunately AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer do not seem to be supported with MinGW. - -You run a parallel build using multiple CPU cores with the `-j` flag, for example, `make -j6`. - -Note that compilation time is much longer than on Unix/Linux or macOS, and linking is incredibly slow for a debug build (around 10 times longer compared to Linux). The debug binary is also much larger than on Unix. +There are a number of compiler warnings for the bundled rlottie library. Unfortunately these need to be resolved upstream, but everything should still work fine so the warnings can be ignored for now. **TLS/SSL certificates** @@ -829,24 +778,24 @@ After the installation has been completed, go to the emulationstation-de directo $ cpack CPack: Create package using NSIS CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPack: - package: C:/Programming/emulationstation-de/EmulationStation-DE-2.2.0-x64.exe generated. +CPack: - package: C:/Programming/emulationstation-de/ES-DE_3.0.0-x64.exe generated. ``` -The default installation directory suggested by the installer is `C:\Program Files\EmulationStation-DE` but this can of course be changed by the user. +The default installation directory suggested by the installer is `C:\Program Files\ES-DE` but this can of course be changed by the user. ES-DE will look in the following locations for application resources, in the listed order: -* \\\.emulationstation\resources\ +* \\\ES-DE\resources\ * \\resources\ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \\\.emulationstation\themes\ +* \\\ES-DE\themes\ * \\themes\ A theme is not mandatory to start the application, but ES-DE will be basically useless without it. @@ -1017,9 +966,9 @@ The reason to not simply replace the BIOS and devices files with the new version ## Configuration -**~/.emulationstation/es_settings.xml** +**~/ES-DE/settings/es_settings.xml** -When ES-DE is first started, a configuration file will be created as `~/.emulationstation/es_settings.xml` +When ES-DE is first started, a configuration file will be created as `~/ES-DE/settings/es_settings.xml` This file will contain all supported settings at their default values. Normally you shouldn't need to modify this file manually, instead you should be able to use the menu inside ES-DE to update all the necessary settings. @@ -1051,16 +1000,18 @@ There is also support to add the variable %ESPATH% to the ROM directory setting, ``` -**~/.emulationstation/es_input.xml** +**~/ES-DE/settings/es_input.xml** As ES-DE auto-configures the keyboard and controllers, neither the input configuration step or manual adjustments to the es_input.xml file should normally be needed. Actually, unless the button layout has been customized using the input configurator, the es_input.xml file will not even exist. -But if you have customized your button layout and your controller or keyboard stop working, you can delete the `~/.emulationstation/es_input.xml` file to remove the customizations, or you can start ES-DE with the `--force-input-config` command line option to make the input configurator appear. +But if you have customized your button layout and your controller or keyboard stop working, you can delete the `~/ES-DE/settings/es_input.xml` file to remove the customizations, or you can start ES-DE with the `--force-input-config` command line option to make the input configurator appear. The input configuration is described in the [User guide](USERGUIDE-DEV.md#input-device-configuration). ## Command line options +_There are no command line options available on Android as this operating system works completely differently than all other supported platforms._ + You can use **--help** or **-h** to view the list of command line options, as shown here. ``` @@ -1091,13 +1042,13 @@ You can use **--help** or **-h** to view the list of command line options, as sh _The --anti-aliasing option is not available if ES-DE is built using the OpenGL ES renderer and the --no-update-check option is not available for builds where the application updater is disabled._ -As you can see above, you can override the home directory path using the `--home` flag. So by running for instance the command `emulationstation --home ~/games/emulation`, ES-DE will use `~/games/emulation/.emulationstation` as its application home directory. Be aware that this option completely replaces what is considered the home directory, meaning the default ROM directory ~/ROMs would be resolved to ~/games/emulation/ROMs. The same is true for the emulator core locations if es_find_rules.xml is configured to look for them relative to the home directory. So of course RetroArch and other emulators would also need to be configured to use ~/games/emulation as its base directory in this instance. +As you can see above, you can override the home directory path using the `--home` flag. So by running for instance the command `es-de --home ~/games/emulation`, ES-DE will use `~/games/emulation/ES-DE` as its application data directory. Be aware that this option completely replaces what is considered the home directory, meaning the default ROM directory ~/ROMs would be resolved to ~/games/emulation/ROMs. The same is true for the emulator core locations if es_find_rules.xml is configured to look for them relative to the home directory. So of course RetroArch and other emulators would also need to be configured to use ~/games/emulation as its base directory in this instance. Setting --resolution to a lower or higher value than the display resolution will add a border to the application window. The exception is if defining a lower resolution than the display resolution in combination with the --fullscreen-padding flag as this will pad the screen contents on a black background. This can be combined with the --screenoffset option for exact positioning on displays where bezels or similar may obstruct part of the viewable area. The --no-update-check option only disabled the application updater for the current startup. To permanently disable this functionality use the _Check for application updates_ option in the _Other settings_ menu. The command line option is primarily intended for the unlikely event that the application updater breaks the application and makes it impossible to start. -Running with the --create-system-dirs option will generate all the game system directories in the ROMs folder. This is equivalent to starting ES-DE with no game ROMs present and pressing the _Create directories_ button. Detailed output for the directory creation will be available in es_log.txt and the application will quit immediately after the directories have been created. +Running with the --create-system-dirs option will generate all the game system directories in the ROMs folder. This is equivalent to starting ES-DE with no game ROMs present and pressing the _Create directories_ button. Detailed output for the directory creation will be available in es_log.txt and the application will quit immediately after the directories have been created. By default placeholder entries will be skipped, if you want to still create these directories then set the CreatePlaceholderSystemDirectories option to true in es_settings.xml. For the following options, the es_settings.xml file is immediately updated/saved when passing the parameter: ``` @@ -1118,6 +1069,10 @@ The --ignore-gamelist option is only active during the program session and is no There are some settings which are not configurable via the GUI as modifying these should normally not be required. To still change these, edit the es_settings.xml file directly. +**CreatePlaceholderSystemDirectories** + +If a system in es_systems.xml has a single command tag with the text _PLACEHOLDER_ anywhere in the tag (regardless of letter case) then its directory and _systeminfo.txt_ file will not get created when running with the --create-system-dirs command line option, or when using the _Create/update system directories_ entry in the _Utilities_ menu or when pressing the _Create directories_ button in the no-games startup dialog. However setting this option to true will override the behavior so the placeholder directories will still be created. + **DebugSkipInputLogging** Enabling this will skip all input event logging (button and key presses). Default value is false. @@ -1132,7 +1087,7 @@ Enabling this will skip all debug messages about missing files specifically for **LegacyGamelistFileLocation** -As of ES-DE 2.0.0 any gamelist.xml files stored in the game system directories (e.g. under `~/ROMs/`) will not get loaded, they are instead required to be placed in the `~/.emulationstation/gamelists/` directory tree. By setting this option to `true` it's however possible to retain the old behavior of first looking for gamelist.xml files in the system directories on startup. Note that even if this setting is enabled ES-DE will still always create new gamelist.xml files under `~/.emulationstation/gamelists/` which was the case also for the 1.x.x releases. +As of ES-DE 2.0.0 any gamelist.xml files stored in the game system directories (e.g. under `~/ROMs/`) will not get loaded, they are instead required to be placed in the `~/ES-DE/gamelists/` directory tree. By setting this option to `true` it's however possible to retain the old behavior of first looking for gamelist.xml files in the system directories on startup. Note that even if this setting is enabled ES-DE will still always create new gamelist.xml files under `~/ES-DE/gamelists/` which was the case also for the 1.x.x releases. **LottieMaxFileCache** @@ -1154,369 +1109,28 @@ Sets the server connection timeout for the scraper. Minimum value is 0 seconds ( Sets the transfer timeout per HTTPS request. Minimum value is 0 seconds (infinity) and maximum value is 300 seconds. Default value is 120 seconds. +**ScraperIgnoreHTTP404Errors** + +Normally the scraper will stop whenever an HTTP error code with value 400 or above is returned from the scraper service, but by default there is an exception for 404 errors (resource not found). Changing this setting to _false_ will make the scraper handle 404 errors as all other error codes, meaning it will run through the configured retry attempts and then display an error notification dialog if the resource could not be retrieved. + **UIMode_passkey** The passkey to use to change from the _Kiosk_ or _Kid_ UI modes to the _Full_ UI mode. -**UserThemeDirectory** +**UserThemeDirectory** _(All operating systems except Android)_ -Sets the user theme directory. If left blank it will default to `~/.emulationstation/themes/` - -## es_systems.xml - -The es_systems.xml file contains the game systems configuration data for ES-DE, written in XML format. This defines the system name, the full system name, the ROM path, the allowed file extensions, the launch command, the platform (for scraping) and the theme to use. - -ES-DE ships with a comprehensive `es_systems.xml` file and most users will probably never need to make any customizations. But there may be special circumstances such as wanting to use different emulators for some game systems or perhaps to add additional systems altogether. - -To accomplish this, ES-DE supports customizations via a separate es_systems.xml file that is to be placed in the `custom_systems` folder in the application home directory, i.e. `~/.emulationstation/custom_systems/es_systems.xml`. (The tilde symbol `~` translates to `$HOME` on Unix and macOS, and to `%HOMEPATH%` on Windows unless overridden via the --home command line option.) - -This custom file functionality is designed to be complementary to the bundled es_systems.xml file, meaning you should only add entries to the custom configuration file for game systems that you actually want to add or override. So to for example customize a single system, this file should only contain a single `` tag. The structure of the custom file is identical to the bundled file with the exception of an additional optional tag named ``. If this is placed in the custom es_systems.xml file, ES-DE will not load the bundled file. This is normally not recommended and should only be used for special situations. At the end of this section you can find an example of a custom es_systems.xml file. - -The bundled es_systems.xml file is located in the resources directory that is part of the application installation. For example this could be `/usr/share/emulationstation/resources/systems/unix/es_systems.xml` on Unix, `/Applications/EmulationStation Desktop Edition.app/Contents/Resources/resources/systems/macos/es_systems.xml` on macOS or `C:\Program Files\EmulationStation-DE\resources\systems\windows\es_systems.xml` on Windows. The actual location may differ from these examples of course, depending on where ES-DE has been installed. - -If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. - -It doesn't matter in which order you define the systems as they will be sorted by the `` tag or by the optional `` tag when displayed inside the application. But it's still a good idea to add the systems in alphabetical order to make the configuration file easier to maintain. - -Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. - -But instead of changing the sorting directly in the es_systems.xml file it could be a better idea to use the dedicated es_systems_sorting.xml file instead. How to do that is described later in this document. - -Wildcards are supported for emulator binaries, but not for directories: -```xml - -~/Applications/yuzu*.AppImage %ROM% - -~/Applications/yuzu*.App* %ROM% - -~/App*/yuzu*.AppImage %ROM% -``` - -There is a special case when it comes to file extensions where it's possible to use extensionless files if required. To accomplish this simply add a dot (.) to the list of extensions in the `` tag. Obviously this makes it impossible to use the _directories interpreted as files_ functionality as there is no file extension, but apart from that everything should work the same as for regular files. - -Keep in mind that you have to set up your emulators separately from ES-DE as the es_systems.xml file assumes that your emulator environment is properly configured. - -Below is an overview of the file layout with various examples. For the command tag, the newer es_find_rules.xml logic described later in this document removes the need for most of the legacy options, but they are still supported for special configurations and for backward compatibility with old configuration files. - -```xml - - - - - - - snes - - - Nintendo SNES (Super Nintendo) - - - Super Nintendo - - - %ROMPATH%/snes - - - .smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP - - - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - - - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% - - - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% - - - retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM% - - - retroarch -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - - - ~/Applications/rpcs3*.AppImage --no-gui %ROM% - - - /Applications/RetroArch.app/Contents/MacOS/RetroArch -L %CORE_RETROARCH%/snes9x_libretro.dylib %ROM% - - - retroarch.exe -L %EMUPATH%\cores\snes9x_libretro.dll %ROM% - - - "C:\My Games\RetroArch\retroarch.exe" -L "%EMUPATH%\cores\snes9x_libretro.dll" %ROM% - - - "%ESPATH%\RetroArch\retroarch.exe" -L "%ESPATH%\RetroArch\cores\snes9x_libretro.dll" %ROM% - - - %HIDEWINDOW% %EMULATOR_MAME% %STARTDIR%=%EMUDIR% -rompath %ROMPATH%\arcade %BASENAME% - - - %EMULATOR_MAME% %STARTDIR%=~/.mame -rompath %ROMPATH%/arcade %BASENAME% - - - %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - - - %HIDEWINDOW% %ESCAPESPECIALS% %RUNINBACKGROUND% cmd.exe /C %ROM% - - - snes - - - snes - - -``` - -The following variable is expanded for the `path` tag: - -`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. - -The following variables are expanded for the `command` tag: - -`%ROM%` - Replaced with the absolute path to the selected ROM, with most special characters escaped with a backslash. - -`%ROMRAW%` - Replaced with the unescaped, absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes. - -`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. If combined with a path that contains blankspaces, then it must be surrounded by quotation marks, for example `%ROMPATH%"\Arcade Games"`. Note that the quotation mark must be located before the directory separator in this case. - -`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar` - -`%FILENAME%` - Replaced with the filename of the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar.rom` - -`%STARTDIR%` - The directory to start in when launching the emulator. Must be defined as a pair separated by an equal sign. This is normally not required, but some emulators and game engines like standalone MAME and OpenBOR will not work properly unless you're in the correct directory when launching a game. Either an absolute path can be used, such as `%STARTDIR%=C:\Games\mame` or some variables are available that provide various functions. The `%EMUDIR%` variable can be used to start in the directory where the emulator binary is located, i.e. `%STARTDIR%=%EMUDIR%`, the `%GAMEDIR%` variable can be used to start in the directory where the game file is located, i.e. `%STARTDIR%=%GAMEDIR%` and the `%GAMEENTRYDIR%` variable can be used which works identically to `%GAMEDIR%` with the exception that it will interpret the actual game entry as the start directory. This is useful in very rare situations like for the EasyRPG Player where the game directories are interpreted as files but where the game engine must still be started from inside the game directory. If an absolute path is set that contains blankspaces, then it must be surrounded by quotation marks, for example `%STARTDIR%="C:\Retro games\mame"`. If the directory defined by this variable does not exist, it will be created on game launch. The variable can be placed anywhere in the launch command if the %EMULATOR_ variable is used, otherwise it has to be placed after the emulator binary. - -`%INJECT%` - This allows the injection of launch arguments or environment variables stored in a text file on the filesystem. The %INJECT% variable must be defined as a pair separated by an equal sign, for example `%INJECT%=game.commands`. The `%BASENAME%` variable can also be used in conjunction with this variable, such as `%INJECT%=%BASENAME%.commands`. By default a path relative to the game file will be assumed but it's also possible to use an absolute path or the ~ (tilde) symbol which will expand to the home directory. If a path contains spaces it needs to be surrounded by quotation marks, such as `%INJECT%="C:\My games\ROMs\daphne\%BASENAME%.daphne\%BASENAME%.commands"`. The variable can be placed anywhere in the launch command and the file contents will be injected at that position. It's also possible to have multiple injections by defining the variable more than once at different locations in the launch command string. The specified file is optional, if it does not exist, is empty, or if there are insufficient permissions to read the file, then it will simply be skipped. For safety reasons the injection file can only have a maximum size of 4096 bytes and if it's larger than this it will be skipped and a warning will be written to es_log.txt. - -`%EMUPATH%` - Replaced with the path to the emulator binary. This variable is used for manually specifying emulator core locations, and a check for the existence of the core file will be done on game launch and an error displayed if it can't be found. Normally %EMUPATH% should not be used as the %CORE_ variable is the recommended method for defining core locations. - -`%EMUDIR%` - Replaced with the path to the emulator binary. This is a general purpose variable as opposed to %EMUPATH% which is intended specifically for core locations. - -`%GAMEDIR%` - Replaced with the path to the game. - -`%GAMEDIRRAW%` - Replaced with the unescaped path to the game. - -`%ESPATH%` - Replaced with the path to the ES-DE binary. Mostly useful for portable emulator installations, for example on a USB memory stick. - -`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. The find rules are explained in more detail below. - -`%PRECOMMAND_` - This utilizes the emulator find rules as defined in `es_find_rules.xml` to locate a pre-command binary. It's for instance useful for running Windows emulators on Linux using Wine or Proton. The %PRECOMMAND_ entry can be located anywhere in the launch command but it should be placed before the %EMULATOR_ variable in order to work as intended. - -`%CORE_` - This utilizes the core find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. - -`%RUNINBACKGROUND%` - When this variable is present, ES-DE will continue to run in the background while a game is launched. This will also prevent the gamelist video from playing, the screensaver from starting, and the game name and game description from scrolling. This functionality is required for some systems such as Valve Steam. The variable can be placed anywhere in the launch command. - -`%HIDEWINDOW%` - This variable is only available on Windows and is used primarily for hiding console windows when launching scripts (used for example by Steam games and source ports). If not defining this, the console window will be visible when launching games. The variable can be placed anywhere in the launch command. - -`%ESCAPESPECIALS%` - This variable is only available on Windows and is used to escape the characters &()^=;, for the %ROM% variable, which would otherwise make binaries like cmd.exe fail when launching scripts or links. The variable can be placed anywhere in the launch command. - -`%ENABLESHORTCUTS%` - This variable is only available on Unix and macOS and is used to enable shortcuts to games and applications. On Unix these come in the form of .desktop files and ES-DE has a simple parser which essentially extracts the command defined in the Exec key and then executes it. Although some basic file structure checks are performed, the actual command listed with the Exec key is blindly executed. In addition to this the variables %F, %f, %U and %u are removed from the Exec key entry. On macOS shortcuts in the form of .app directories and alias files are executed using the `open -W -a` command. This makes it possible to launch shortcuts to emulators and applications like Steam as well as aliases for any application. However the latter need to be renamed to the .app file extension or it won't work. When a file is matching the .desktop or .app extension respectively, the emulator command defined using the %EMULATOR% variable will be stripped. An %EMULATOR% entry is however still required for the %ENABLESHORTCUTS% variable to work as the intention is to combine shortcuts with the ability to launch shell scripts without having to setup alternative emulators. The %ROM% variable is expanded to the command to execute when using %ENABLESHORTCUTS%, which also means that this variable has to be used, and for example %ROMRAW% will not work. - -Here are some additional real world examples of system entries, the first one for Unix: - -```xml - - dos - DOS (PC) - %ROMPATH%/dos - .bat .BAT .com .COM .conf .CONF .cue .CUE .exe .EXE .iso .ISO .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% - dos - dos - -``` - -Then one for macOS: - -```xml - - n64 - Nintendo 64 - %ROMPATH%/n64 - .n64 .N64 .v64 .V64 .z64 .Z64 .bin .BIN .u1 .U1 .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.dylib %ROM% - n64 - n64 - -``` - -And finally one for Windows: - -```xml - - pcengine - NEC PC Engine - %ROMPATH%\pcengine - .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_libretro.dll %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_fast_libretro.dll %ROM% - pcengine - pcengine - -``` - -As well, here's an example for Unix of a custom es_systems.xml file placed in ~/.emulationstation/custom_systems/ that overrides a single game system from the bundled configuration file: -```xml - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - -``` - -If adding the `` tag to the file, the bundled es_systems.xml file will not be processed. For this example it wouldn't be a very good idea as NES would then be the only platform that could be used in ES-DE. - -```xml - - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - -``` - -Here is yet another example with the addition of the `snes` system where some file extensions and alternative emulator entries have been removed, and the full name and sorting have been modified. - -```xml - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - - snes - Super Nintendo - Nintendo SNES (Super Nintendo) - %ROMPATH%/snes - .smc .SMC .sfc .SFC .swc .SWC .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% - snes - snes - - -``` - -## es_systems_sorting.xml - -This file makes it possible to apply a custom systems sorting without having to modify the es_systems.xml file directly. It should be placed in the custom_systems directory, e.g. `~/.emulationstation/custom_systems/es_systems_sorting.xml` - -Note that in order for ES-DE to load this file you'll need to set the _Systems sorting_ option in the _Other settings_ menu to _Full names or custom_. - -The structure of this file is essentially a simplified version of the es_systems.xml file, but with only the `` and `` tags present per system. - -Here's an example where three systems have been sorted by release year instead of the default full system name: - -```xml - - - - amiga - 1985 - - - c64 - 1982 - - - vic20 - 1980 - - -``` - -You only need to include systems that you want to customize sorting for, and if there's also a systemsortname tag present in the es_systems.xml file for any system, then the es_systems_sorting.xml entry will take precedence. - -Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. Secondary sorting will always be done by the fullname tag in es_systems.xml. - -There are also four complete sorting files bundled with ES-DE, you can find them in the resources/sorting/ directory, or you can access them [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/sorting). - -These files include all systems supported by ES-DE and provide the following sorting options: - -* Release year -* Manufacturer, release year -* Hardware type, release year -* Manufacturer, hardware type, release year - -You can apply any of these sorting files via the _Systems sorting_ option in the _Other settings_ menu. Note that in order to load a es_systems_sorting.xml file placed in the custom_systems directory you'll need to set this option to _Full names or custom_. +Sets the user theme directory. If left blank it will default to `~/ES-DE/themes/` ## es_find_rules.xml This file makes it possible to define rules for where to search for the emulator binaries and emulator cores. -The file is located in the resources directory in the same location as the es_systems.xml file, but a customized copy can be placed in ~/.emulationstation/custom_systems, which will complement the bundled file. +The file is located in the resources directory in the same location as the es_systems.xml file, but a customized copy can be placed in ~/ES-DE/custom_systems, which will complement the bundled file. -Here's an example es_find_rules.xml file for Unix (this is not the complete file shipped with ES-DE as that would be too large to include here): +Here's an example es_find_rules.xml file for Linux (this is not the complete file shipped with ES-DE as that would be too large to include here): ```xml - + @@ -1552,10 +1166,6 @@ Here's an example es_find_rules.xml file for Unix (this is not the complete file /usr/lib64/libretro /usr/lib/libretro - - /usr/local/lib/libretro - - /usr/pkg/lib/libretro @@ -1765,14 +1375,497 @@ For reference, here are also example es_find_rules.xml files for macOS and Windo ``` +## es_systems.xml + +The es_systems.xml file contains the game systems configuration data for ES-DE, written in XML format. This defines the system name, the full system name, the ROM path, the allowed file extensions, the launch command, the platform (for scraping) and the theme to use. + +ES-DE ships with a comprehensive `es_systems.xml` file and most users will probably never need to make any customizations. But there may be special circumstances such as wanting to use different emulators for some game systems or perhaps to add additional systems altogether. + +To accomplish this, ES-DE supports customizations via a separate es_systems.xml file that is to be placed in the `custom_systems` folder in the application home directory, i.e. `~/ES-DE/custom_systems/es_systems.xml`. (The tilde symbol `~` translates to `$HOME` on Unix and macOS, and to `%HOMEPATH%` on Windows unless overridden via the --home command line option.) + +This custom file functionality is designed to be complementary to the bundled es_systems.xml file, meaning you should only add entries to the custom configuration file for game systems that you actually want to add or override. So to for example customize a single system, this file should only contain a single `` tag. The structure of the custom file is identical to the bundled file with the exception of an additional optional tag named ``. If this is placed in the custom es_systems.xml file, ES-DE will not load the bundled file. This is normally not recommended and should only be used for special situations. At the end of this section you can find an example of a custom es_systems.xml file. + +The bundled es_systems.xml file is located in the resources directory that is part of the application installation. For example this could be `/usr/share/es-de/resources/systems/linux/es_systems.xml` on Linux, `/Applications/ES-DE.app/Contents/Resources/resources/systems/macos/es_systems.xml` on macOS or `C:\Program Files\ES-DE\resources\systems\windows\es_systems.xml` on Windows. The actual location may differ from these examples of course, depending on where ES-DE has been installed. + +If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. + +It doesn't matter in which order you define the systems as they will be sorted by the `` tag or by the optional `` tag when displayed inside the application. But it's still a good idea to add the systems in alphabetical order to make the configuration file easier to maintain. + +Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. + +But instead of changing the sorting directly in the es_systems.xml file it could be a better idea to use the dedicated es_systems_sorting.xml file instead. How to do that is described later in this document. + +Wildcards are supported for emulator binaries, but not for directories: +```xml + +~/Applications/yuzu*.AppImage %ROM% + +~/Applications/yuzu*.App* %ROM% + +~/App*/yuzu*.AppImage %ROM% +``` + +There is a special case when it comes to file extensions where it's possible to use extensionless files if required. To accomplish this simply add a dot (.) to the list of extensions in the `` tag. Obviously this makes it impossible to use the _directories interpreted as files_ functionality as there is no file extension, but apart from that everything should work the same as for regular files. + +Keep in mind that you have to set up your emulators separately from ES-DE as the es_systems.xml file assumes that your emulator environment is properly configured. + +Below is an overview of the file layout with various examples. For the command tag, the newer es_find_rules.xml logic described later in this document removes the need for most of the legacy options, but they are still supported for special configurations and for backward compatibility with old configuration files. + +```xml + + + + + + + snes + + + Nintendo SNES (Super Nintendo) + + + Super Nintendo + + + %ROMPATH%/snes + + + .smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP + + + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + + + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + + + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% + + + retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM% + + + retroarch -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + + + ~/Applications/rpcs3*.AppImage --no-gui %ROM% + + + /Applications/RetroArch.app/Contents/MacOS/RetroArch -L %CORE_RETROARCH%/snes9x_libretro.dylib %ROM% + + + retroarch.exe -L %EMUPATH%\cores\snes9x_libretro.dll %ROM% + + + "C:\My Games\RetroArch\retroarch.exe" -L "%EMUPATH%\cores\snes9x_libretro.dll" %ROM% + + + "%ESPATH%\RetroArch\retroarch.exe" -L "%ESPATH%\RetroArch\cores\snes9x_libretro.dll" %ROM% + + + %HIDEWINDOW% %EMULATOR_MAME% %STARTDIR%=%EMUDIR% -rompath %ROMPATH%\arcade %BASENAME% + + + %EMULATOR_MAME% %STARTDIR%=~/.mame -rompath %ROMPATH%/arcade %BASENAME% + + + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + + + %HIDEWINDOW% %ESCAPESPECIALS% %RUNINBACKGROUND% cmd.exe /C %ROM% + + + PLACEHOLDER %ROM% + + + snes + + + snes + + +``` + +The following variable is expanded for the `path` tag: + +`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. + +The following variables are expanded for the `command` tag: + +`%ROM%` - Replaced with the absolute path to the selected ROM, with most special characters escaped with a backslash. + +`%ROMRAW%` - Replaced with the unescaped, absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes. + +`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. If combined with a path that contains blankspaces, then it must be surrounded by quotation marks, for example `%ROMPATH%"\Arcade Games"`. Note that the quotation mark must be located before the directory separator in this case. + +`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar` + +`%FILENAME%` - Replaced with the filename of the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar.rom` + +`%STARTDIR%` - The directory to start in when launching the emulator. Must be defined as a pair separated by an equal sign. This is normally not required, but some emulators and game engines like standalone MAME and OpenBOR will not work properly unless you're in the correct directory when launching a game. Either an absolute path can be used, such as `%STARTDIR%=C:\Games\mame` or some variables are available that provide various functions. The `%EMUDIR%` variable can be used to start in the directory where the emulator binary is located, i.e. `%STARTDIR%=%EMUDIR%`, the `%GAMEDIR%` variable can be used to start in the directory where the game file is located, i.e. `%STARTDIR%=%GAMEDIR%` and the `%GAMEENTRYDIR%` variable can be used which works identically to `%GAMEDIR%` with the exception that it will interpret the actual game entry as the start directory. This is useful in very rare situations like for the EasyRPG Player where the game directories are interpreted as files but where the game engine must still be started from inside the game directory. If an absolute path is set that contains blankspaces, then it must be surrounded by quotation marks, for example `%STARTDIR%="C:\Retro games\mame"`. If the directory defined by this variable does not exist, it will be created on game launch. The variable can be placed anywhere in the launch command if the %EMULATOR_ variable is used, otherwise it has to be placed after the emulator binary. + +`%INJECT%` - This allows the injection of launch arguments or environment variables stored in a text file on the filesystem. The %INJECT% variable must be defined as a pair separated by an equal sign, for example `%INJECT%=game.commands`. The `%BASENAME%` variable can also be used in conjunction with this variable, such as `%INJECT%=%BASENAME%.commands`. By default a path relative to the game file will be assumed but it's also possible to use an absolute path or the ~ (tilde) symbol which will expand to the home directory. If a path contains spaces it needs to be surrounded by quotation marks, such as `%INJECT%="C:\My games\ROMs\daphne\%BASENAME%.daphne\%BASENAME%.commands"`. The variable can be placed anywhere in the launch command and the file contents will be injected at that position. It's also possible to have multiple injections by defining the variable more than once at different locations in the launch command string. The specified file is optional, if it does not exist, is empty, or if there are insufficient permissions to read the file, then it will simply be skipped. For safety reasons the injection file can only have a maximum size of 4096 bytes and if it's larger than this it will be skipped and a warning will be written to es_log.txt. + +`%EMUPATH%` - Replaced with the path to the emulator binary. This variable is used for manually specifying emulator core locations, and a check for the existence of the core file will be done on game launch and an error displayed if it can't be found. Normally %EMUPATH% should not be used as the %CORE_ variable is the recommended method for defining core locations. + +`%EMUDIR%` - Replaced with the path to the emulator binary. This is a general purpose variable as opposed to %EMUPATH% which is intended specifically for core locations. + +`%GAMEDIR%` - Replaced with the path to the game. + +`%GAMEDIRRAW%` - Replaced with the unescaped path to the game. + +`%ESPATH%` - Replaced with the path to the ES-DE binary. Mostly useful for portable emulator installations, for example on a USB memory stick. + +`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. The find rules are explained in more detail below. + +`%PRECOMMAND_` - This utilizes the emulator find rules as defined in `es_find_rules.xml` to locate a pre-command binary. It's for instance useful for running Windows emulators on Linux using Wine or Proton. The %PRECOMMAND_ entry can be located anywhere in the launch command but it should be placed before the %EMULATOR_ variable in order to work as intended. + +`%CORE_` - This utilizes the core find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. + +`%RUNINBACKGROUND%` - When this variable is present, ES-DE will continue to run in the background while a game is launched. This will also prevent the gamelist video from playing, the screensaver from starting, and the game name and game description from scrolling. This functionality is required for some systems such as Valve Steam. The variable can be placed anywhere in the launch command. + +`%HIDEWINDOW%` - This variable is only available on Windows and is used primarily for hiding console windows when launching scripts (used for example by Steam games and source ports). If not defining this, the console window will be visible when launching games. The variable can be placed anywhere in the launch command. + +`%ESCAPESPECIALS%` - This variable is only available on Windows and is used to escape the characters &()^=;, for the %ROM% variable, which would otherwise make binaries like cmd.exe fail when launching scripts or links. The variable can be placed anywhere in the launch command. + +`%ENABLESHORTCUTS%` - This variable is only available on Unix and macOS and is used to enable shortcuts to games and applications. On Unix these come in the form of .desktop files and ES-DE has a simple parser which essentially extracts the command defined in the Exec key and then executes it. Although some basic file structure checks are performed, the actual command listed with the Exec key is blindly executed. In addition to this the variables %F, %f, %U and %u are removed from the Exec key entry. On macOS shortcuts in the form of .app directories and alias files are executed using the `open -W -a` command. This makes it possible to launch shortcuts to emulators and applications like Steam as well as aliases for any application. However the latter need to be renamed to the .app file extension or it won't work. When a file is matching the .desktop or .app extension respectively, the emulator command defined using the %EMULATOR% variable will be stripped. An %EMULATOR% entry is however still required for the %ENABLESHORTCUTS% variable to work as the intention is to combine shortcuts with the ability to launch shell scripts without having to setup alternative emulators. The %ROM% variable is expanded to the command to execute when using %ENABLESHORTCUTS%, which also means that this variable has to be used, and for example %ROMRAW% will not work. + +Here are some additional real world examples of system entries, the first one for Unix: + +```xml + + dos + DOS (PC) + %ROMPATH%/dos + .bat .BAT .com .COM .conf .CONF .cue .CUE .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% + dos + dos + +``` + +Then one for macOS: + +```xml + + n64 + Nintendo 64 + %ROMPATH%/n64 + .n64 .N64 .v64 .V64 .z64 .Z64 .bin .BIN .u1 .U1 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.dylib %ROM% + n64 + n64 + +``` + +And finally one for Windows: + +```xml + + pcengine + NEC PC Engine + %ROMPATH%\pcengine + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_fast_libretro.dll %ROM% + pcengine + pcengine + +``` + +As well, here's an example for Linux of a custom es_systems.xml file placed in ~/ES-DE/custom_systems/ that overrides a single game system from the bundled configuration file: +```xml + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + +``` + +If adding the `` tag to the file, the bundled es_systems.xml file will not be processed. For this example it wouldn't be a very good idea as NES would then be the only platform that could be used in ES-DE. + +```xml + + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + +``` + +Here is yet another example with the addition of the `snes` system where some file extensions and alternative emulator entries have been removed, and the full name and sorting have been modified. + +```xml + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + + snes + Super Nintendo + Nintendo SNES (Super Nintendo) + %ROMPATH%/snes + .smc .SMC .sfc .SFC .swc .SWC .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + snes + snes + + +``` + +## es_find_rules.xml and es_systems.xml on Android + +ES-DE works a bit differently on Android which is also reflected in the es_find_rules.xml and es_systems.xml configuration. Emulators on Android are launched via so-called _Intents_ which is an API rather than the typical command line approach used on Unix systems. Although ES-DE on Windows also uses an API call to launch emulators it's still closely connected to the regular operating system paradigms on how to start binaries and pass application options so the systems configuration still looks quite traditional. On Android this is not the case and there is therefore a heavy use of variables to reflect the Intent API functionality. + +To better understand the configuration in this section it could be a good idea to refer the official Android documentation:\ +https://developer.android.com/reference/android/content/Intent + +There is a command line tool in Android named _am_ which implements the _Intent_ API and can be used to test emulator launching, but this is not intended to be used by other applications and therefore ES-DE implements direct (albeit partial) support for the Intent API. Testing the modern FileProvider interface using the _am_ utility may also be difficult, or maybe impossible. + +**es_find_rules.xml** + +The es_find_rules.xml file is structured the same as for the other operating systems but there'a special _androidpackage_ find rule where you define the name of the emulator package as well as optionally which _activity_ to launch. If the activity is not defined then the default one for the package will be used. Although this may work in some instances it's usually a good idea to explicity set it. Apart from that the find rules work as on the other platforms, i.e. they will be traversed in the order they are defined. So by adding multiple _androidpackage_ entries for an emulator it's possible to look for multiple releases or forks without having to create separate emulator entries in es_systems.xml. It's also possible to override find rules by adding an ES-DE/custom_systems/es_find_rules.xml file, again the same logic applies as for all other platforms. + +The _androidpackage_ find rule entries are structured as `packagename/activity` and if only a package is defined then the forward slash can be omitted, i.e. only `packagename` is needed. + +Here's an example es_find_rules.xml file defining two emulators: + +```xml + + + + + + com.retroarch.aarch64/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch.ra32/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch/com.retroarch.browser.retroactivity.RetroActivityFuture + + + + + + org.yuzu.yuzu_emu.ea/org.yuzu.yuzu_emu.activities.EmulationActivity + org.yuzu.yuzu_emu/org.yuzu.yuzu_emu.activities.EmulationActivity + + + +``` + +**es_systems.xml** + +The es_systems.xml file on Android utilizes variables heavily to implement the _Intent_ API and these variables are covered in detail below. It's possible to override the systems configuration by adding an ES-DE/custom_systems/es_systems.xml file, the same logic applies as for all other platforms. + +`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the only way to configure the launch command on Android and it works identically to the other platforms. + +`%ACTION%` - The general Intent action to be performed, you need to assign its value using an equal sign. + +`%MIMETYPE%` - Sets an explicit MIME type, which you need to assign using an equal sign such as %MIMETYPE%=text/plain. You will rarely, if ever, need to set an explicit MIME type so this variable is of limited use. By default Android will set the MIME type to application/octet-stream which is normally what you want. + +There are two main ways to pass options to emulators, using _extras_ or using the _data_ URI. There can only be a single data URI but there can be an arbitrary amount of extras. To understand more about the way this works, you can read about the _putExtra()_ and and _setData()_ functions here:\ +https://developer.android.com/reference/android/content/Intent + +`%EXTRA_` - This passes an _extra_ which contains any additional information that the emulator may support. This is provided as a key/value pair where you define the key name following the literal %EXTRA_ string and terminate it with a % sign and then assign the value using an equal sign. For example %EXTRA_LIBRETRO%=puae_libretro_android.so will pass the extra named _LIBRETRO_ with its value set to _puae_libretro_android.so_. You can pass an unlimited number of extras and you can also use various ROM variables in combination with this as described below. + +`%EXTRAARRAY_` - Defines an array of comma-separated string values following the key name. Only literal strings are supported, so this can't be used in combination with any ROM variables. As commas are used as separator characters, you'll need to escape any comma signs that you want to include in the actual value. For example %EXTRAARRAY_Parameters%=pone,p\\,two,pthree will pass the extra named _Parameters_ with the three separate array entries _pone_, _p,two_ and _pthree_. + +`%EXTRABOOL_` - Sets an extra with a boolean value, i.e. true/1 or false/0. + +`%DATA%` - Sets the data URI value for the intent using an equal sign. This is normally combined with one of the ROM variables. + +There are three approaches to passing game ROMs to emulators by using the following variables: + +`%ROM%` - Replaced with the absolute path to the selected ROM. This is a traditional method to provide the game ROM and its use will likely decrease or go away completely long term as emulators move to more modern methods. + +`%ROMSAF%` - Replaced with an Android Storage Access Framework (SAF) document URI which always starts with the _content://com.android.externalstorage.documents/_ string. You can read more about the SAF here:\ +https://developer.android.com/guide/topics/providers/document-provider + +`%ROMPROVIDER%` - This is the most modern approach to passing game ROMs to emulators. It uses the _FileProvider_ API to provide permissions to the file. This means that you don't need to setup the emulator upfront to have access to the directory where the game file is stored, access is instead temporarily granted by ES-DE. You can read more about the FileProvider API here:\ +https://developer.android.com/reference/androidx/core/content/FileProvider + +The `%ROM%` and `%ROMSAF%` variables can be used with both the `%DATA%` and `%EXTRA_` variables, but `%ROMPROVIDER%` can only be used with the `%DATA%` variable. For the `%DATA%` variable you'll just assign the ROM variable with an equal sign as there can only be a single _setData()_ API call per Intent. For the `%EXTRA_` variable you need to specify a name of the extra and then define it using an equal sign as an arbitrary amount of _putExtra()_ API calls can be used for an Intent. + +Here are some examples to clarify how this works: +``` +%DATA%=%ROM% +%DATA%=%ROMSAF% +%DATA%=%ROMPROVIDER% +%EXTRA_ROM%=%ROM% +%EXTRA_bootPath%=%ROMSAF% +%EXTRABOOL_resumeState%=false +``` + +There is also support for a couple of activity flags that affect the emulator/game launch behavior, you can read more about these flags here:\ +https://developer.android.com/reference/android/content/Intent + +The descriptions below are taken from the official documentation just linked above: + +`%ACTIVITY_CLEAR_TASK%` - If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. + +`%ACTIVITY_CLEAR_TOP%` - If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent. + +`%ACTIVITY_NO_HISTORY%` - If set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished. This may also be set with the noHistory attribute. If set, onActivityResult() is never invoked when the current activity starts a new activity which sets a result and finishes. + +Here's an example es_systems.xml file for Android: +```xml + + + + + gc + Nintendo GameCube + %ROMPATH%/gc + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/dolphin_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DOLPHIN% %ACTION%=android.intent.action.MAIN %DATA%=%ROMPROVIDER% + gc + gc + + + n3ds + Nintendo 3DS + %ROMPATH%/n3ds + .3ds .3DS .3dsx .3DSX .app .APP .axf .AXF .cci .CCI .cxi .CXI .elf .ELF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/citra_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_CITRA% %ACTIVITY_NO_HISTORY% %EXTRA_SelectedGame%=%ROMSAF% + %EMULATOR_CITRA-MMJ% %EXTRA_GamePath%=%ROM% + n3ds + n3ds + + + psx + Sony PlayStation + %ROMPATH%/psx + .bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DUCKSTATION% %EXTRABOOL_resumeState%=false %EXTRA_bootPath%=%ROMSAF% + psx + psx + + +``` + +## es_systems_sorting.xml + +This file makes it possible to apply custom systems sorting without having to modify the es_systems.xml file directly. It should be placed in the custom_systems directory, e.g. `~/ES-DE/custom_systems/es_systems_sorting.xml` + +Note that in order for ES-DE to load this file you'll need to set the _Systems sorting_ option in the _UI settings_ menu to _Full names or custom_. + +The structure of this file is essentially a simplified version of the es_systems.xml file, but with only the `` and `` tags present per system. + +Here's an example where three systems have been sorted by release year instead of the default full system name: + +```xml + + + + amiga + 1985 + + + c64 + 1982 + + + vic20 + 1980 + + +``` + +You only need to include systems that you want to customize sorting for, and if there's also a systemsortname tag present in the es_systems.xml file for any system, then the es_systems_sorting.xml entry will take precedence. + +Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. Secondary sorting will always be done by the fullname tag in es_systems.xml. + +There are also four complete sorting files bundled with ES-DE, you can find them in the resources/sorting/ directory, or you can access them [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/sorting). + +These files include all systems supported by ES-DE and provide the following sorting options: + +* Release year +* Manufacturer, release year +* Hardware type, release year +* Manufacturer, hardware type, release year + +You can apply any of these sorting files via the _Systems sorting_ option in the _Other settings_ menu. Note that in order to load a es_systems_sorting.xml file placed in the custom_systems directory you'll need to set this option to _Full names or custom_. + ## gamelist.xml The gamelist.xml file for a system defines the metadata for its entries, such as the game names, descriptions, release dates and ratings. -As of the fork to EmulationStation Desktop Edition, game media information no longer needs to be defined in the gamelist.xml files. Instead the application will look for any media matching the ROM filename. The media path where to look for game media is configurable either manually in `es_settings.xml` or via the GUI. If configured manually in es_settings.xml, it looks something like this: +As of the fork to ES-DE, game media information no longer needs to be defined in the gamelist.xml files. Instead the application will look for any media matching the ROM filename. The media path where to look for game media is configurable either manually in `es_settings.xml` or via the GUI. If configured manually in es_settings.xml, it looks something like this: ```xml - + ``` There is also support to add the variable %ESPATH% to the media directory setting, this will expand to the path where the ES-DE executable is started from. You should normally not need this, but the option is there for special cases. For example: @@ -1781,17 +1874,17 @@ There is also support to add the variable %ESPATH% to the media directory settin ``` -The default media directory is `~/.emulationstation/downloaded_media` +The default media directory is `~/ES-DE/downloaded_media` You can use ES-DE's scrapers to populate the gamelist.xml files, or manually update individual entries using the metadata editor. All of this is explained in the [User guide](USERGUIDE-DEV.md). -The gamelist.xml files are searched for in the ES-DE home directory, i.e. `~/.emulationstation/gamelists//gamelist.xml` +The gamelist.xml files are searched for in the ES-DE home directory, i.e. `~/ES-DE/gamelists//gamelist.xml` For example: ``` -~/.emulationstation/gamelists/c64/gamelist.xml -~/.emulationstation/gamelists/megadrive/gamelist.xml +~/ES-DE/gamelists/c64/gamelist.xml +~/ES-DE/gamelists/megadrive/gamelist.xml ``` **gamelist.xml file structure** @@ -1922,7 +2015,7 @@ Before attempting to add a custom profile for your controller you need to check ES-DE uses the [SDL](https://www.libsdl.org) (Simple DirectMedia Layer) library to handle controller input, so in order for a controller to work in ES-DE, it has to be supported by SDL. There is however a possibility to add custom controller profiles to SDL which in some cases could enable devices in ES-DE that would otherwise not be supported. This is generally a temporary solution though, as controller support is constantly getting improved natively in SDL. As a first step it's therefore recommended to open a request at the SDL [issue tracker](https://github.com/libsdl-org/SDL/issues) to have your specific controller added to a future SDL release. -Assuming the controller works in other applications than ES-DE, you can attempt to add a custom profile by creating the file `~/.emulationstation/es_controller_mappings.cfg` and enter the appropriate configuration inside this file. +Assuming the controller works in other applications than ES-DE, you can attempt to add a custom profile by creating the file `~/ES-DE/controllers/es_controller_mappings.cfg` and enter the appropriate configuration inside this file. The required format is described here:\ https://github.com/gabomdq/SDL_GameControllerDB @@ -1932,7 +2025,7 @@ https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontro But just do this as a first step to see whether you controller gets enabled. If it does, then you should remove all entries that are not relevant. That is important as this file will take precedence over the built-in controller profiles in the SDL library, so any future controller bug fixes and similar would not apply. In the past the gamecontrollerdb.txt file has also included some invalid configuration entries, so even though it may make your controller work, it could actually break some other controllers that you may want to use now or in the future. -Therefore only keep the entries in the es_controller_mappings.cfg file that are relevant for your devices. You can find each relevant controller GUID by starting ES-DE and then looking in the ~/.emulationstation/es_log.txt file. You should see entries such as the following: +Therefore only keep the entries in the es_controller_mappings.cfg file that are relevant for your devices. You can find each relevant controller GUID by starting ES-DE and then looking in the `~/ES-DE/logs/es_log.txt` file. You should see entries such as the following: ``` May 16 18:26:17 Info: Added controller with custom configuration: "X360 Controller" (GUID: 030000005e0400008e02000010010000, instance ID: 0, device index: 0) ``` @@ -1954,26 +2047,26 @@ For this example, let's assume that the removable media has the device name `F:\ These are the steps to perform: * Install ES-DE -* Copy the EmulationStation-DE installation directory to F:\ -* Create a directory named F:\EmulationStation-DE\Emulators -* Copy your emulator directories to F:\EmulationStation-DE\Emulators\ -* Copy your ROMs directory to F:\EmulationStation-DE\ -* Create an empty file named portable.txt in F:\EmulationStation-DE\ +* Copy the ES-DE installation directory to F:\ +* Create a directory named F:\ES-DE\Emulators +* Copy your emulator directories to F:\ES-DE\Emulators\ +* Copy your ROMs directory to F:\ES-DE\ +* Create an empty file named portable.txt in F:\ES-DE\ You should end up with something like this: ``` -F:\EmulationStation-DE\ -F:\EmulationStation-DE\Emulators\dosbox-staging\ -F:\EmulationStation-DE\Emulators\RetroArch-Win64\ -F:\EmulationStation-DE\Emulators\RPCS3\ -F:\EmulationStation-DE\Emulators\xemu\ -F:\EmulationStation-DE\ROMs\ -F:\EmulationStation-DE\portable.txt +F:\ES-DE\ +F:\ES-DE\Emulators\dosbox-staging\ +F:\ES-DE\Emulators\RetroArch-Win64\ +F:\ES-DE\Emulators\RPCS3\ +F:\ES-DE\Emulators\xemu\ +F:\ES-DE\ROMs\ +F:\ES-DE\portable.txt ``` -This is just an example as you may of course not use these specific emulators. There are also many more emulators supported as detailed in the `es_find_rules.xml` configuration file. As well there will be many more files and directories than those listed above inside the F:\EmulationStation-DE folder. +This is just an example as you may of course not use these specific emulators. There are also many more emulators supported as detailed in the `es_find_rules.xml` configuration file. As well there will be many more files and directories than those listed above inside the F:\ES-DE folder. -How the portable setup works is that when ES-DE finds a file named portable.txt in its executable directory, it will by default locate the .emulationstation directory directly inside this folder. It's also possible to modify portable.txt with a path relative to the ES-DE executable directory. For instance if two dots `..` are placed inside the portable.txt file, then the .emulationstation directory will be located in the parent folder, which would be directly under F:\ for this example. +How the portable setup works is that when ES-DE finds a file named portable.txt in its executable directory, it will by default locate the ES-DE application data directory directly inside this folder. It's also possible to modify portable.txt with a path relative to the ES-DE executable directory. For instance if two dots `..` are placed inside the portable.txt file, then the ES-DE application data directory will be located in the parent folder, which would be directly under F:\ for this example. If the --home command line parameter is passed when starting ES-DE, that will override the portable.txt file. @@ -1982,12 +2075,12 @@ Start ES-DE from the F:\ device and check that everything works as expected. Jus Following this, optionally copy any existing gamelist.xml files, game media files etc. to the removable media. For example: ``` -F:\EmulationStation-DE\.emulationstation\collections\ -F:\EmulationStation-DE\.emulationstation\downloaded_media\ -F:\EmulationStation-DE\.emulationstation\gamelists\ +F:\ES-DE\ES-DE\collections\ +F:\ES-DE\ES-DE\downloaded_media\ +F:\ES-DE\ES-DE\gamelists\ ``` -You could alternatively copy over your entire .emulationstation directory, but in this case make sure that you have no settings in es_settings.xml that point to a specific location on your local filesystem, such as the game ROMs or game media directories. +You could alternatively copy over your entire ES-DE application data directory, but in this case make sure that you have no settings in es_settings.xml that point to a specific location on your local filesystem, such as the game ROMs or game media directories. You now have a fully functional portable retrogaming installation! @@ -2030,7 +2123,7 @@ The following examples are for Unix systems, but it works the same way on macOS As can be seen in the table above, the events executed when a game starts and ends are named _game-start_ and _game-end_ -So let's create the folders for these events in the scripts directory. The location is `~/.emulationstation/scripts` +So let's create the folders for these events in the scripts directory. The location is `~/ES-DE/scripts` **Game log** @@ -2041,7 +2134,7 @@ Let's name the start script `game_start_logging.sh` with the following contents: ``` #!/bin/bash TIMESTAMP=$(date +%Y-%m-%d' '%H:%M:%S) -echo Starting game "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/.emulationstation/game_playlog.txt +echo Starting game "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/ES-DE/logs/game_playlog.txt ``` And let's name the end script `game_end_logging.sh` with the following contents: @@ -2049,14 +2142,14 @@ And let's name the end script `game_end_logging.sh` with the following contents: ``` #!/bin/bash TIMESTAMP=$(date +%Y-%m-%d' '%H:%M:%S) -echo "Ending game " "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/.emulationstation/game_playlog.txt +echo "Ending game " "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/ES-DE/logs/game_playlog.txt ``` After creating the two scripts, you should have something like this on the filesystem: ``` -~/.emulationstation/scripts/game-start/game_start_logging.sh -~/.emulationstation/scripts/game-end/game_end_logging.sh +~/ES-DE/scripts/game-start/game_start_logging.sh +~/ES-DE/scripts/game-end/game_end_logging.sh ``` Don't forget to make the scripts executable (e.g. "chmod 755 ./game_start_logging.sh"). @@ -2065,15 +2158,14 @@ If we now start ES-DE with the debug flag and launch a game, something like the ``` Aug 05 14:19:24 Debug: Scripting::fireEvent(): game-start "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" -Aug 05 14:19:24 Debug: Executing: /home/myusername/.emulationstation/scripts/game-start/game_start_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" +Aug 05 14:19:24 Debug: Executing: /home/myusername/ES-DE/scripts/game-start/game_start_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" . . Aug 05 14:27:15 Debug: Scripting::fireEvent(): game-end "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" "" -Aug 05 14:27:15 Debug: Executing: /home/myusername/.emulationstation/scripts/game-end/game_end_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" - +Aug 05 14:27:15 Debug: Executing: /home/myusername/ES-DE/scripts/game-end/game_end_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" ``` -Finally after running some games, ~/.emulationstation/game_playlog.txt should contain something like the following: +Finally after running some games, ~/ES-DE/logs/game_playlog.txt should contain something like the following: ``` Starting game "The Legend Of Zelda" "Nintendo Entertainment System" ("/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip") at 2020-08-05 14:19:24 @@ -2101,7 +2193,7 @@ Then create the end script, which we'll name `set_resolution_4K.sh`: #!/bin/sh xrandr -s 3840x2160 sleep 0.3 -xdotool search --class emulationstation windowactivate +xdotool search --class es-de windowactivate ``` The last two lines are optional, they're used to set the focus back to ES-DE in case you're running attention-seeking applications such as Kodi which may steal focus after resolution changes. You may need to adjust the sleep time to get this to work reliably though, as the timing may differ between different computers and graphics drivers. @@ -2109,8 +2201,8 @@ The last two lines are optional, they're used to set the focus back to ES-DE in After creating the two scripts, you should have something like this on the filesystem: ``` -~/.emulationstation/scripts/game-start/set_resolution_1080p.sh -~/.emulationstation/scripts/game-end/set_resolution_4K.sh +~/ES-DE/scripts/game-start/set_resolution_1080p.sh +~/ES-DE/scripts/game-end/set_resolution_4K.sh ``` Don't forget to make the scripts executable (e.g. "chmod 755 ./set_resolution_1080p.sh"). diff --git a/INSTALL.md b/INSTALL.md index ab1ec48a2..95c18a21f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 - Building and advanced configuration +# ES-DE (EmulationStation Desktop Edition) v3.0 - Building and advanced configuration Table of contents: @@ -160,7 +160,7 @@ make -j8 ``` Due to buggy AMD GPU drivers it could be a good idea to use the `LSAN_suppressions` file included in the repository to avoid reports of a lot of irrelevant issue, for example: ``` -LSAN_OPTIONS="suppressions=tools/LSAN_suppressions" ./emulationstation --debug --resolution 2560 1440 +LSAN_OPTIONS="suppressions=tools/LSAN_suppressions" ./es-de --debug --resolution 2560 1440 ``` This applies to LeakSanitizer specifically, which is integrated into AddressSanitizer. @@ -173,7 +173,7 @@ make -j8 It could also be a good idea to use the `TSAN_suppressions` file included in the repository to suppress issues reported by some third party libraries, for example: ``` -TSAN_OPTIONS="suppressions=tools/TSAN_suppressions" ./emulationstation --debug --resolution 2560 1440 +TSAN_OPTIONS="suppressions=tools/TSAN_suppressions" ./es-de --debug --resolution 2560 1440 ``` To enable UndefinedBehaviorSanitizer which helps with identifying bugs that may otherwise be hard to find, build with the UBSAN option: @@ -194,17 +194,17 @@ As for advanced debugging, Valgrind is a very powerful and useful tool which can The most common tool is Memcheck to check for memory leaks, which you run like this: ``` -valgrind --tool=memcheck --leak-check=full --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=memcheck --leak-check=full --log-file=../valgrind_run_01 ./es-de ``` There are numerous flags that can be used, for example this will also track reachable memory which could indicate further leaks: ``` -valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=memcheck --leak-check=full --track-origins=yes --show-reachable=yes --log-file=../valgrind_run_01 ./es-de ``` Another helpful tool is the Callgrind call-graph analyzer: ``` -valgrind --tool=callgrind --log-file=../valgrind_run_01 ./emulationstation +valgrind --tool=callgrind --log-file=../valgrind_run_01 ./es-de ``` The output file can be loaded into an application such as KCachegrind for data analysis. @@ -213,7 +213,7 @@ The output file can be loaded into an application such as KCachegrind for data a Yet another very useful Valgrind tool is the Massif heap profiler, which can be run like this: ``` -valgrind --tool=massif --massif-out-file=../massif.out.01 ./emulationstation +valgrind --tool=massif --massif-out-file=../massif.out.01 ./es-de ``` The output file can be loaded into an application such as Massif-Visualizer for analysis. @@ -301,35 +301,35 @@ sudo make install Assuming the default installation prefix /usr has been used, this is the directory structure for the installation: ``` -/usr/bin/emulationstation +/usr/bin/es-de /usr/bin/es-pdf-convert -/usr/share/applications/org.es_de.emulationstation-de.desktop -/usr/share/emulationstation/licenses/* -/usr/share/emulationstation/resources/* -/usr/share/emulationstation/themes/* -/usr/share/emulationstation/LICENSE -/usr/share/icons/hicolor/scalable/apps/org.es_de.emulationstation-de.svg -/usr/share/man/man6/emulationstation.6.gz -/usr/share/metainfo/org.es_de.emulationstation-de.appdata.xml -/usr/share/pixmaps/org.es_de.emulationstation-de.svg +/usr/share/applications/org.es_de.frontend.desktop +/usr/share/es-de/licenses/* +/usr/share/es-de/resources/* +/usr/share/es-de/themes/* +/usr/share/es-de/LICENSE +/usr/share/icons/hicolor/scalable/apps/org.es_de.frontend.svg +/usr/share/man/man6/es-de.6.gz +/usr/share/metainfo/org.es_de.frontend.appdata.xml +/usr/share/pixmaps/org.es_de.frontend.svg ``` However, when installing manually instead of building a package, it's recommended to change the install prefix to /usr/local instead of /usr. -Be aware that if using the GNOME desktop environment, /usr/share/pixmaps/emulationstation.svg must exist in order for the ES-DE icon to be shown in the Dash and task switcher. +Be aware that if using the GNOME desktop environment, /usr/share/pixmaps/org.es_de.frontend.svg must exist in order for the ES-DE icon to be shown in the Dash and task switcher. ES-DE will look in the following locations for application resources, in the listed order: -* \/.emulationstation/resources/ -* \/share/emulationstation/resources/ +* \/ES-DE/resources/ +* \/share/es-de/resources/ * \/resources/ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \/.emulationstation/themes/ -* \/share/emulationstation/themes/ +* \/ES-DE/themes/ +* \/share/es-de/themes/ * \/themes/ A theme is not mandatory to start the application, but ES-DE will be basically useless without it. @@ -344,23 +344,23 @@ Creation of Debian .deb packages is enabled by default, simply run `cpack` to ge myusername@computer:~/emulationstation-de$ cpack CPack: Create package using DEB CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package CPackDeb: - Generating dependency list -CPack: - package: /home/myusername/emulationstation-de/emulationstation-de-2.2.0-x64.deb generated. +CPack: - package: /home/myusername/emulationstation-de/es-de_3.0.0-x64.deb generated. ``` You may want to check that the dependencies look fine, as they're (mostly) automatically generated by CMake: ``` -dpkg -I ./emulationstation-de-2.2.0-x64.deb +dpkg -I ./es-de_3.0.0-x64.deb ``` The package can now be installed using a package manager, for example apt: ``` -sudo apt install ./emulationstation-de-2.2.0-x64.deb +sudo apt install ./es-de_3.0.0-x64.deb ``` To build an RPM package instead, set the flag LINUX_CPACK_GENERATOR to RPM when running cmake, for example: @@ -375,11 +375,11 @@ Then simply run `cpack`: myusername@computer:~/emulationstation-de$ cpack CPack: Create package using RPM CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPackRPM: Will use GENERATED spec file: /home/myusername/emulationstation-de/_CPack_Packages/Linux/RPM/SPECS/emulationstation-de.spec -CPack: - package: /home/myusername/emulationstation-de/emulationstation-de-2.2.0-x64.rpm generated. +CPackRPM: Will use GENERATED spec file: /home/myusername/emulationstation-de/_CPack_Packages/Linux/RPM/SPECS/es-de.spec +CPack: - package: /home/myusername/emulationstation-de/es-de_3.0.0-x64.rpm generated ``` On Fedora, you need to install rpmbuild before this command can be run: @@ -389,17 +389,17 @@ sudo dnf install rpm-build After the package generation you can check that the metadata looks fine using the `rpm` command: ``` -rpm -qi ./emulationstation-de-2.2.0-x64.rpm +rpm -qi ./es-de_3.0.0-x64.rpm ``` To see the automatically generated dependencies, run this: ``` -rpm -q --requires ./emulationstation-de-2.2.0-x64.rpm +rpm -q --requires ./es-de_3.0.0-x64.rpm ``` And of course, you can also install the package: ``` -sudo dnf install ./emulationstation-de-2.2.0-x64.rpm +sudo dnf install ./es-de_3.0.0-x64.rpm ``` **Creating an AppImage** @@ -574,37 +574,37 @@ make install This will be the directory structure for the installation: ``` -/Applications/EmulationStation Desktop Edition.app/Contents/Info.plist -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/EmulationStation -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/es-pdf-convert -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libSDL2-2.0.0.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavcodec.60.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavfilter.9.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavformat.60.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libavutil.58.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libfontconfig.1.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libfreetype.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libgit2.1.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libjpeg.62.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libopenjp2.7.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpoppler-cpp.0.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpoppler.129.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libpostproc.57.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libswresample.4.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libswscale.7.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libtiff.6.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libvorbis.0.4.9.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/MacOS/libvorbisenc.2.0.12.dylib -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/EmulationStation-DE.icns -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/LICENSE -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/licenses/* -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/resources/* -/Applications/EmulationStation Desktop Edition.app/Contents/Resources/themes/* +/Applications/ES-DE.app/Contents/Info.plist +/Applications/ES-DE.app/Contents/MacOS/ES-DE +/Applications/ES-DE.app/Contents/MacOS/es-pdf-convert +/Applications/ES-DE.app/Contents/MacOS/libSDL2-2.0.0.dylib +/Applications/ES-DE.app/Contents/MacOS/libavcodec.60.dylib +/Applications/ES-DE.app/Contents/MacOS/libavfilter.9.dylib +/Applications/ES-DE.app/Contents/MacOS/libavformat.60.dylib +/Applications/ES-DE.app/Contents/MacOS/libavutil.58.dylib +/Applications/ES-DE.app/Contents/MacOS/libfontconfig.1.dylib +/Applications/ES-DE.app/Contents/MacOS/libfreetype.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libgit2.1.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libjpeg.62.dylib +/Applications/ES-DE.app/Contents/MacOS/libopenjp2.7.dylib +/Applications/ES-DE.app/Contents/MacOS/libpoppler-cpp.0.dylib +/Applications/ES-DE.app/Contents/MacOS/libpoppler.129.dylib +/Applications/ES-DE.app/Contents/MacOS/libpostproc.57.dylib +/Applications/ES-DE.app/Contents/MacOS/libswresample.4.dylib +/Applications/ES-DE.app/Contents/MacOS/libswscale.7.dylib +/Applications/ES-DE.app/Contents/MacOS/libtiff.6.dylib +/Applications/ES-DE.app/Contents/MacOS/libvorbis.0.4.9.dylib +/Applications/ES-DE.app/Contents/MacOS/libvorbisenc.2.0.12.dylib +/Applications/ES-DE.app/Contents/Resources/ES-DE.icns +/Applications/ES-DE.app/Contents/Resources/LICENSE +/Applications/ES-DE.app/Contents/Resources/licenses/* +/Applications/ES-DE.app/Contents/Resources/resources/* +/Applications/ES-DE.app/Contents/Resources/themes/* ``` ES-DE will look in the following locations for application resources, in the listed order: -* \/.emulationstation/resources/ +* \/ES-DE/resources/ * \/../Resources/resources/ * \/resources/ @@ -612,7 +612,7 @@ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \/.emulationstation/themes/ +* \/ES-DE/themes/ * \/../Resources/themes/ * \/themes/ @@ -628,19 +628,15 @@ Simply run `cpack` to build a .dmg disk image/installer: myusername@computer:~/emulationstation-de$ cpack CPack: Create package using Bundle CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPack: - package: /Users/myusername/emulationstation-de/EmulationStation-DE-2.2.0-x64.dmg generated. +CPack: - package: /Users/myusername/emulationstation-de/ES-DE_3.0.0-arm64.dmg generated. ``` ## Building on Windows -Although both Microsoft Visual C++ (MSVC) and GCC (MinGW) have historically been supported for building ES-DE on Windows, as of the 2.2.0 release MinGW is no longer recommended and support for it will likely be dropped in future releases. - -Although MinGW produces much higher quality code than MSVC with ES-DE running around 10% to 25% faster it's unfortunately not sustainable to keep using it. There are multiple technical issues with third party libraries like severe threading issues with FFmpeg and some libraries like Poppler not being readily available. Debugging with MinGW is also a very slow and tedious process compared to MSVC. MinGW up to 9.2.0 works more or less fine but anything more modern than this introduces issues like FFmpeg's avfilter_graph_free() call taking up to 7000 times longer to complete which makes video playback unusable. Setting filter graphs to use single threads solves some but not all issues. As well libgit2 has (probably) a race condition that causes random repository corruption that is likely only present when using MinGW. - -Clang/LLVM has also been evaluated but it suffers from at least the same threading issues as MinGW, likely because it uses libraries from the latter. It also fails to build some of the third party libraries needed by ES-DE. +Only the Microsoft Visual C++ (MSVC) compiler is supported on Windows. Although MinGW/GCC produces higher quality code with ES-DE running around 10% to 25% faster it's unfortunately not sustainable to use it. There are multiple technical issues with third party libraries like severe threading issues with FFmpeg and some libraries like Poppler not being readily available. **MSVC setup** @@ -677,21 +673,6 @@ The way the MSVC environment works is that a specific developer shell is provide It's important to choose the x64-specific shell and not the x86 variant, as ES-DE will only compile as a 64-bit application. -**MinGW (GCC) setup** - -Download the following packages and install them: - -[https://gitforwindows.org](https://gitforwindows.org) - -[https://cmake.org/download](https://cmake.org/download) - -Download the _MinGW-w64 based_ version of GCC: \ -[https://jmeubank.github.io/tdm-gcc](https://jmeubank.github.io/tdm-gcc) - -After installation, make a copy of `TDM-GCC-64\bin\mingw32-make` to `make` for your convenience. - -Only version 9.2.0 of MinGW has been confirmed to work correctly, anything newer introduces severe problems and MSVC should instead be used if a more modern compiler is required. - **Other preparations** In order to get clang-format onto the system you need to download and install Clang/LLVM: \ @@ -707,7 +688,7 @@ Configure Git. Details about its setup is beyond the scope of this document, but It's strongly recommended to set line breaks to Unix-style (line feed only) directly in the code editor. But if not done, lines breaks will anyway be converted when running clang-format on the code, as explained [here](INSTALL.md#using-clang-format-for-automatic-code-formatting). -The instructions below assume all build steps for MSVC are done in the MSVC developer console (x64 Native Tools Command Prompt for VS) and all MinGW build steps are done using the Git Bash shell. +The instructions below assume all build steps for MSVC are done in the MSVC developer console (x64 Native Tools Command Prompt for VS). **Cloning and setting up dependencies** @@ -724,29 +705,21 @@ cd emulationstation-de git checkout stable-2.2 ``` -On Windows all dependencies are kept in-tree in the `external` directory tree. Most of the libraries can be downloaded in binary form, but a few need to be built from source code. There are four scripts in the tools directory that automate this entirely. Two of them are used for the MSVC compiler and the other two for MinGW. +On Windows all dependencies are kept in-tree in the `external` directory tree. Most of the libraries can be downloaded in binary form, but a few need to be built from source code. There are two scripts in the tools directory that automate this entirely. You run them like this: -For MSVC, you run them like this: ``` cd emulationstation-de -tools\Windows_dependencies_setup_MSVC.bat -tools\Windows_dependencies_build_MSVC.bat -``` - -And for MinGW like the following: -``` -cd emulationstation-de -tools/Windows_dependencies_setup_MinGW.sh -tools/Windows_dependencies_build_MinGW.sh +tools\Windows_dependencies_setup.bat +tools\Windows_dependencies_build.bat ``` Re-running the setup script will delete and download all dependencies again, and re-running the build script will clean and rebuild from scratch. -The setup scripts for both MSVC and MinGW will download and launch an installer for OpenSSL for Windows if this has not already been installed on the build machine. Just run through the installer using the default settings and everything should work fine. +The setup scripts will download and launch an installer for OpenSSL for Windows if this has not already been installed on the build machine. Just run through the installer using the default settings and everything should work fine. Following these preparations, ES-DE should be ready to be compiled. -**Building ES-DE using MSVC** +**Building ES-DE** It's assumed that [Jom](https://wiki.qt.io/Jom) is used, but if instead using nmake then just remove _JOM_ from the -G flag argument and remove the -j flag as nmake does not support building in parallel. @@ -775,31 +748,7 @@ nmake ThreadSanitizer and UndefinedBehaviorSanitizer aren't available for the MSVC compiler. -There are a number of compiler warnings for the bundled rlottie library when building with MSVC. Unfortunately these need to be resolved upstream, but everything should still work fine so the warnings can be ignored for now. - -**Building ES-DE using MinGW** - -For a release build: - -``` -cmake -G "MinGW Makefiles" . -make -j8 -``` - -Or for a debug build: - -``` -cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug . -make -j8 -``` - -Change the -j flag to whatever amount of parallel threads you want to use for the compilation. - -Unfortunately AddressSanitizer, ThreadSanitizer and UndefinedBehaviorSanitizer do not seem to be supported with MinGW. - -You run a parallel build using multiple CPU cores with the `-j` flag, for example, `make -j6`. - -Note that compilation time is much longer than on Unix/Linux or macOS, and linking is incredibly slow for a debug build (around 10 times longer compared to Linux). The debug binary is also much larger than on Unix. +There are a number of compiler warnings for the bundled rlottie library. Unfortunately these need to be resolved upstream, but everything should still work fine so the warnings can be ignored for now. **TLS/SSL certificates** @@ -827,24 +776,24 @@ After the installation has been completed, go to the emulationstation-de directo $ cpack CPack: Create package using NSIS CPack: Install projects -CPack: - Run preinstall target for: emulationstation-de -CPack: - Install project: emulationstation-de [] +CPack: - Run preinstall target for: es-de +CPack: - Install project: es-de [] CPack: Create package -CPack: - package: C:/Programming/emulationstation-de/EmulationStation-DE-2.2.0-x64.exe generated. +CPack: - package: C:/Programming/emulationstation-de/ES-DE_3.0.0-x64.exe generated. ``` -The default installation directory suggested by the installer is `C:\Program Files\EmulationStation-DE` but this can of course be changed by the user. +The default installation directory suggested by the installer is `C:\Program Files\ES-DE` but this can of course be changed by the user. ES-DE will look in the following locations for application resources, in the listed order: -* \\\.emulationstation\resources\ +* \\\ES-DE\resources\ * \\resources\ The resources directory is critical, without it the application won't start. As well the following locations will be searched for themes, also in the listed order: -* \\\.emulationstation\themes\ +* \\\ES-DE\themes\ * \\themes\ A theme is not mandatory to start the application, but ES-DE will be basically useless without it. @@ -1015,9 +964,9 @@ The reason to not simply replace the BIOS and devices files with the new version ## Configuration -**~/.emulationstation/es_settings.xml** +**~/ES-DE/settings/es_settings.xml** -When ES-DE is first started, a configuration file will be created as `~/.emulationstation/es_settings.xml` +When ES-DE is first started, a configuration file will be created as `~/ES-DE/settings/es_settings.xml` This file will contain all supported settings at their default values. Normally you shouldn't need to modify this file manually, instead you should be able to use the menu inside ES-DE to update all the necessary settings. @@ -1049,16 +998,18 @@ There is also support to add the variable %ESPATH% to the ROM directory setting, ``` -**~/.emulationstation/es_input.xml** +**~/ES-DE/settings/es_input.xml** As ES-DE auto-configures the keyboard and controllers, neither the input configuration step or manual adjustments to the es_input.xml file should normally be needed. Actually, unless the button layout has been customized using the input configurator, the es_input.xml file will not even exist. -But if you have customized your button layout and your controller or keyboard stop working, you can delete the `~/.emulationstation/es_input.xml` file to remove the customizations, or you can start ES-DE with the `--force-input-config` command line option to make the input configurator appear. +But if you have customized your button layout and your controller or keyboard stop working, you can delete the `~/ES-DE/settings/es_input.xml` file to remove the customizations, or you can start ES-DE with the `--force-input-config` command line option to make the input configurator appear. The input configuration is described in the [User guide](USERGUIDE.md#input-device-configuration). ## Command line options +_There are no command line options available on Android as this operating system works completely differently than all other supported platforms._ + You can use **--help** or **-h** to view the list of command line options, as shown here. ``` @@ -1089,13 +1040,13 @@ You can use **--help** or **-h** to view the list of command line options, as sh _The --anti-aliasing option is not available if ES-DE is built using the OpenGL ES renderer and the --no-update-check option is not available for builds where the application updater is disabled._ -As you can see above, you can override the home directory path using the `--home` flag. So by running for instance the command `emulationstation --home ~/games/emulation`, ES-DE will use `~/games/emulation/.emulationstation` as its application home directory. Be aware that this option completely replaces what is considered the home directory, meaning the default ROM directory ~/ROMs would be resolved to ~/games/emulation/ROMs. The same is true for the emulator core locations if es_find_rules.xml is configured to look for them relative to the home directory. So of course RetroArch and other emulators would also need to be configured to use ~/games/emulation as its base directory in this instance. +As you can see above, you can override the home directory path using the `--home` flag. So by running for instance the command `es-de --home ~/games/emulation`, ES-DE will use `~/games/emulation/ES-DE` as its application data directory. Be aware that this option completely replaces what is considered the home directory, meaning the default ROM directory ~/ROMs would be resolved to ~/games/emulation/ROMs. The same is true for the emulator core locations if es_find_rules.xml is configured to look for them relative to the home directory. So of course RetroArch and other emulators would also need to be configured to use ~/games/emulation as its base directory in this instance. Setting --resolution to a lower or higher value than the display resolution will add a border to the application window. The exception is if defining a lower resolution than the display resolution in combination with the --fullscreen-padding flag as this will pad the screen contents on a black background. This can be combined with the --screenoffset option for exact positioning on displays where bezels or similar may obstruct part of the viewable area. The --no-update-check option only disabled the application updater for the current startup. To permanently disable this functionality use the _Check for application updates_ option in the _Other settings_ menu. The command line option is primarily intended for the unlikely event that the application updater breaks the application and makes it impossible to start. -Running with the --create-system-dirs option will generate all the game system directories in the ROMs folder. This is equivalent to starting ES-DE with no game ROMs present and pressing the _Create directories_ button. Detailed output for the directory creation will be available in es_log.txt and the application will quit immediately after the directories have been created. +Running with the --create-system-dirs option will generate all the game system directories in the ROMs folder. This is equivalent to starting ES-DE with no game ROMs present and pressing the _Create directories_ button. Detailed output for the directory creation will be available in es_log.txt and the application will quit immediately after the directories have been created. By default placeholder entries will be skipped, if you want to still create these directories then set the CreatePlaceholderSystemDirectories option to true in es_settings.xml. For the following options, the es_settings.xml file is immediately updated/saved when passing the parameter: ``` @@ -1116,6 +1067,10 @@ The --ignore-gamelist option is only active during the program session and is no There are some settings which are not configurable via the GUI as modifying these should normally not be required. To still change these, edit the es_settings.xml file directly. +**CreatePlaceholderSystemDirectories** + +If a system in es_systems.xml has a single command tag with the text _PLACEHOLDER_ anywhere in the tag (regardless of letter case) then its directory and _systeminfo.txt_ file will not get created when running with the --create-system-dirs command line option, or when using the _Create/update system directories_ entry in the _Utilities_ menu or when pressing the _Create directories_ button in the no-games startup dialog. However setting this option to true will override the behavior so the placeholder directories will still be created. + **DebugSkipInputLogging** Enabling this will skip all input event logging (button and key presses). Default value is false. @@ -1130,7 +1085,7 @@ Enabling this will skip all debug messages about missing files specifically for **LegacyGamelistFileLocation** -As of ES-DE 2.0.0 any gamelist.xml files stored in the game system directories (e.g. under `~/ROMs/`) will not get loaded, they are instead required to be placed in the `~/.emulationstation/gamelists/` directory tree. By setting this option to `true` it's however possible to retain the old behavior of first looking for gamelist.xml files in the system directories on startup. Note that even if this setting is enabled ES-DE will still always create new gamelist.xml files under `~/.emulationstation/gamelists/` which was the case also for the 1.x.x releases. +As of ES-DE 2.0.0 any gamelist.xml files stored in the game system directories (e.g. under `~/ROMs/`) will not get loaded, they are instead required to be placed in the `~/ES-DE/gamelists/` directory tree. By setting this option to `true` it's however possible to retain the old behavior of first looking for gamelist.xml files in the system directories on startup. Note that even if this setting is enabled ES-DE will still always create new gamelist.xml files under `~/ES-DE/gamelists/` which was the case also for the 1.x.x releases. **LottieMaxFileCache** @@ -1152,369 +1107,28 @@ Sets the server connection timeout for the scraper. Minimum value is 0 seconds ( Sets the transfer timeout per HTTPS request. Minimum value is 0 seconds (infinity) and maximum value is 300 seconds. Default value is 120 seconds. +**ScraperIgnoreHTTP404Errors** + +Normally the scraper will stop whenever an HTTP error code with value 400 or above is returned from the scraper service, but by default there is an exception for 404 errors (resource not found). Changing this setting to _false_ will make the scraper handle 404 errors as all other error codes, meaning it will run through the configured retry attempts and then display an error notification dialog if the resource could not be retrieved. + **UIMode_passkey** The passkey to use to change from the _Kiosk_ or _Kid_ UI modes to the _Full_ UI mode. -**UserThemeDirectory** +**UserThemeDirectory** _(All operating systems except Android)_ -Sets the user theme directory. If left blank it will default to `~/.emulationstation/themes/` - -## es_systems.xml - -The es_systems.xml file contains the game systems configuration data for ES-DE, written in XML format. This defines the system name, the full system name, the ROM path, the allowed file extensions, the launch command, the platform (for scraping) and the theme to use. - -ES-DE ships with a comprehensive `es_systems.xml` file and most users will probably never need to make any customizations. But there may be special circumstances such as wanting to use different emulators for some game systems or perhaps to add additional systems altogether. - -To accomplish this, ES-DE supports customizations via a separate es_systems.xml file that is to be placed in the `custom_systems` folder in the application home directory, i.e. `~/.emulationstation/custom_systems/es_systems.xml`. (The tilde symbol `~` translates to `$HOME` on Unix and macOS, and to `%HOMEPATH%` on Windows unless overridden via the --home command line option.) - -This custom file functionality is designed to be complementary to the bundled es_systems.xml file, meaning you should only add entries to the custom configuration file for game systems that you actually want to add or override. So to for example customize a single system, this file should only contain a single `` tag. The structure of the custom file is identical to the bundled file with the exception of an additional optional tag named ``. If this is placed in the custom es_systems.xml file, ES-DE will not load the bundled file. This is normally not recommended and should only be used for special situations. At the end of this section you can find an example of a custom es_systems.xml file. - -The bundled es_systems.xml file is located in the resources directory that is part of the application installation. For example this could be `/usr/share/emulationstation/resources/systems/unix/es_systems.xml` on Unix, `/Applications/EmulationStation Desktop Edition.app/Contents/Resources/resources/systems/macos/es_systems.xml` on macOS or `C:\Program Files\EmulationStation-DE\resources\systems\windows\es_systems.xml` on Windows. The actual location may differ from these examples of course, depending on where ES-DE has been installed. - -If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. - -It doesn't matter in which order you define the systems as they will be sorted by the `` tag or by the optional `` tag when displayed inside the application. But it's still a good idea to add the systems in alphabetical order to make the configuration file easier to maintain. - -Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. Secondary sorting will always be done by the fullname tag in es_systems.xml. - -But instead of changing the sorting directly in the es_systems.xml file it could be a better idea to use the dedicated es_systems_sorting.xml file instead. How to do that is described later in this document. - -Wildcards are supported for emulator binaries, but not for directories: -```xml - -~/Applications/yuzu*.AppImage %ROM% - -~/Applications/yuzu*.App* %ROM% - -~/App*/yuzu*.AppImage %ROM% -``` - -There is a special case when it comes to file extensions where it's possible to use extensionless files if required. To accomplish this simply add a dot (.) to the list of extensions in the `` tag. Obviously this makes it impossible to use the _directories interpreted as files_ functionality as there is no file extension, but apart from that everything should work the same as for regular files. - -Keep in mind that you have to set up your emulators separately from ES-DE as the es_systems.xml file assumes that your emulator environment is properly configured. - -Below is an overview of the file layout with various examples. For the command tag, the newer es_find_rules.xml logic described later in this document removes the need for most of the legacy options, but they are still supported for special configurations and for backward compatibility with old configuration files. - -```xml - - - - - - - snes - - - Nintendo SNES (Super Nintendo) - - - Super Nintendo - - - %ROMPATH%/snes - - - .smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP - - - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - - - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% - - - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% - - - retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM% - - - retroarch -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - - - ~/Applications/rpcs3*.AppImage --no-gui %ROM% - - - /Applications/RetroArch.app/Contents/MacOS/RetroArch -L %CORE_RETROARCH%/snes9x_libretro.dylib %ROM% - - - retroarch.exe -L %EMUPATH%\cores\snes9x_libretro.dll %ROM% - - - "C:\My Games\RetroArch\retroarch.exe" -L "%EMUPATH%\cores\snes9x_libretro.dll" %ROM% - - - "%ESPATH%\RetroArch\retroarch.exe" -L "%ESPATH%\RetroArch\cores\snes9x_libretro.dll" %ROM% - - - %HIDEWINDOW% %EMULATOR_MAME% %STARTDIR%=%EMUDIR% -rompath %ROMPATH%\arcade %BASENAME% - - - %EMULATOR_MAME% %STARTDIR%=~/.mame -rompath %ROMPATH%/arcade %BASENAME% - - - %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - - - %HIDEWINDOW% %ESCAPESPECIALS% %RUNINBACKGROUND% cmd.exe /C %ROM% - - - snes - - - snes - - -``` - -The following variable is expanded for the `path` tag: - -`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. - -The following variables are expanded for the `command` tag: - -`%ROM%` - Replaced with the absolute path to the selected ROM, with most special characters escaped with a backslash. - -`%ROMRAW%` - Replaced with the unescaped, absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes. - -`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. If combined with a path that contains blankspaces, then it must be surrounded by quotation marks, for example `%ROMPATH%"\Arcade Games"`. Note that the quotation mark must be located before the directory separator in this case. - -`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar` - -`%FILENAME%` - Replaced with the filename of the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar.rom` - -`%STARTDIR%` - The directory to start in when launching the emulator. Must be defined as a pair separated by an equal sign. This is normally not required, but some emulators and game engines like standalone MAME and OpenBOR will not work properly unless you're in the correct directory when launching a game. Either an absolute path can be used, such as `%STARTDIR%=C:\Games\mame` or some variables are available that provide various functions. The `%EMUDIR%` variable can be used to start in the directory where the emulator binary is located, i.e. `%STARTDIR%=%EMUDIR%`, the `%GAMEDIR%` variable can be used to start in the directory where the game file is located, i.e. `%STARTDIR%=%GAMEDIR%` and the `%GAMEENTRYDIR%` variable can be used which works identically to `%GAMEDIR%` with the exception that it will interpret the actual game entry as the start directory. This is useful in very rare situations like for the EasyRPG Player where the game directories are interpreted as files but where the game engine must still be started from inside the game directory. If an absolute path is set that contains blankspaces, then it must be surrounded by quotation marks, for example `%STARTDIR%="C:\Retro games\mame"`. If the directory defined by this variable does not exist, it will be created on game launch. The variable can be placed anywhere in the launch command if the %EMULATOR_ variable is used, otherwise it has to be placed after the emulator binary. - -`%INJECT%` - This allows the injection of launch arguments or environment variables stored in a text file on the filesystem. The %INJECT% variable must be defined as a pair separated by an equal sign, for example `%INJECT%=game.commands`. The `%BASENAME%` variable can also be used in conjunction with this variable, such as `%INJECT%=%BASENAME%.commands`. By default a path relative to the game file will be assumed but it's also possible to use an absolute path or the ~ (tilde) symbol which will expand to the home directory. If a path contains spaces it needs to be surrounded by quotation marks, such as `%INJECT%="C:\My games\ROMs\daphne\%BASENAME%.daphne\%BASENAME%.commands"`. The variable can be placed anywhere in the launch command and the file contents will be injected at that position. It's also possible to have multiple injections by defining the variable more than once at different locations in the launch command string. The specified file is optional, if it does not exist, is empty, or if there are insufficient permissions to read the file, then it will simply be skipped. For safety reasons the injection file can only have a maximum size of 4096 bytes and if it's larger than this it will be skipped and a warning will be written to es_log.txt. - -`%EMUPATH%` - Replaced with the path to the emulator binary. This variable is used for manually specifying emulator core locations, and a check for the existence of the core file will be done on game launch and an error displayed if it can't be found. Normally %EMUPATH% should not be used as the %CORE_ variable is the recommended method for defining core locations. - -`%EMUDIR%` - Replaced with the path to the emulator binary. This is a general purpose variable as opposed to %EMUPATH% which is intended specifically for core locations. - -`%GAMEDIR%` - Replaced with the path to the game. - -`%GAMEDIRRAW%` - Replaced with the unescaped path to the game. - -`%ESPATH%` - Replaced with the path to the ES-DE binary. Mostly useful for portable emulator installations, for example on a USB memory stick. - -`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. The find rules are explained in more detail below. - -`%PRECOMMAND_` - This utilizes the emulator find rules as defined in `es_find_rules.xml` to locate a pre-command binary. It's for instance useful for running Windows emulators on Linux using Wine or Proton. The %PRECOMMAND_ entry can be located anywhere in the launch command but it should be placed before the %EMULATOR_ variable in order to work as intended. - -`%CORE_` - This utilizes the core find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. - -`%RUNINBACKGROUND%` - When this variable is present, ES-DE will continue to run in the background while a game is launched. This will also prevent the gamelist video from playing, the screensaver from starting, and the game name and game description from scrolling. This functionality is required for some systems such as Valve Steam. The variable can be placed anywhere in the launch command. - -`%HIDEWINDOW%` - This variable is only available on Windows and is used primarily for hiding console windows when launching scripts (used for example by Steam games and source ports). If not defining this, the console window will be visible when launching games. The variable can be placed anywhere in the launch command. - -`%ESCAPESPECIALS%` - This variable is only available on Windows and is used to escape the characters &()^=;, for the %ROM% variable, which would otherwise make binaries like cmd.exe fail when launching scripts or links. The variable can be placed anywhere in the launch command. - -`%ENABLESHORTCUTS%` - This variable is only available on Unix and macOS and is used to enable shortcuts to games and applications. On Unix these come in the form of .desktop files and ES-DE has a simple parser which essentially extracts the command defined in the Exec key and then executes it. Although some basic file structure checks are performed, the actual command listed with the Exec key is blindly executed. In addition to this the variables %F, %f, %U and %u are removed from the Exec key entry. On macOS shortcuts in the form of .app directories and alias files are executed using the `open -W -a` command. This makes it possible to launch shortcuts to emulators and applications like Steam as well as aliases for any application. However the latter need to be renamed to the .app file extension or it won't work. When a file is matching the .desktop or .app extension respectively, the emulator command defined using the %EMULATOR% variable will be stripped. An %EMULATOR% entry is however still required for the %ENABLESHORTCUTS% variable to work as the intention is to combine shortcuts with the ability to launch shell scripts without having to setup alternative emulators. The %ROM% variable is expanded to the command to execute when using %ENABLESHORTCUTS%, which also means that this variable has to be used, and for example %ROMRAW% will not work. - -Here are some additional real world examples of system entries, the first one for Unix: - -```xml - - dos - DOS (PC) - %ROMPATH%/dos - .bat .BAT .com .COM .conf .CONF .cue .CUE .exe .EXE .iso .ISO .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% - dos - dos - -``` - -Then one for macOS: - -```xml - - n64 - Nintendo 64 - %ROMPATH%/n64 - .n64 .N64 .v64 .V64 .z64 .Z64 .bin .BIN .u1 .U1 .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.dylib %ROM% - n64 - n64 - -``` - -And finally one for Windows: - -```xml - - pcengine - NEC PC Engine - %ROMPATH%\pcengine - .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_libretro.dll %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_fast_libretro.dll %ROM% - pcengine - pcengine - -``` - -As well, here's an example for Unix of a custom es_systems.xml file placed in ~/.emulationstation/custom_systems/ that overrides a single game system from the bundled configuration file: -```xml - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - -``` - -If adding the `` tag to the file, the bundled es_systems.xml file will not be processed. For this example it wouldn't be a very good idea as NES would then be the only platform that could be used in ES-DE. - -```xml - - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - -``` - -Here is yet another example with the addition of the `snes` system where some file extensions and alternative emulator entries have been removed, and the full name and sorting have been modified. - -```xml - - - - - nes - Nintendo Entertainment System - %ROMPATH%/nes - .nes .NES .zip .ZIP - /usr/games/fceux %ROM% - nes - nes - - - snes - Super Nintendo - Nintendo SNES (Super Nintendo) - %ROMPATH%/snes - .smc .SMC .sfc .SFC .swc .SWC .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% - snes - snes - - -``` - -## es_systems_sorting.xml - -This file makes it possible to apply a custom systems sorting without having to modify the es_systems.xml file directly. It should be placed in the custom_systems directory, e.g. `~/.emulationstation/custom_systems/es_systems_sorting.xml` - -Note that in order for ES-DE to load this file you'll need to set the _Systems sorting_ option in the _Other settings_ menu to _Full names or custom_. - -The structure of this file is essentially a simplified version of the es_systems.xml file, but with only the `` and `` tags present per system. - -Here's an example where three systems have been sorted by release year instead of the default full system name: - -```xml - - - - amiga - 1985 - - - c64 - 1982 - - - vic20 - 1980 - - -``` - -You only need to include systems that you want to customize sorting for, and if there's also a systemsortname tag present in the es_systems.xml file for any system, then the es_systems_sorting.xml entry will take precedence. - -Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. - -There are also four complete sorting files bundled with ES-DE, you can find them in the resources/sorting/ directory, or you can access them [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/sorting). - -These files include all systems supported by ES-DE and provide the following sorting options: - -* Release year -* Manufacturer, release year -* Hardware type, release year -* Manufacturer, hardware type, release year - -You can apply any of these sorting files via the _Systems sorting_ option in the _Other settings_ menu. Note that in order to load a es_systems_sorting.xml file placed in the custom_systems directory you'll need to set this option to _Full names or custom_. +Sets the user theme directory. If left blank it will default to `~/ES-DE/themes/` ## es_find_rules.xml This file makes it possible to define rules for where to search for the emulator binaries and emulator cores. -The file is located in the resources directory in the same location as the es_systems.xml file, but a customized copy can be placed in ~/.emulationstation/custom_systems, which will complement the bundled file. +The file is located in the resources directory in the same location as the es_systems.xml file, but a customized copy can be placed in ~/ES-DE/custom_systems, which will complement the bundled file. -Here's an example es_find_rules.xml file for Unix (this is not the complete file shipped with ES-DE as that would be too large to include here): +Here's an example es_find_rules.xml file for Linux (this is not the complete file shipped with ES-DE as that would be too large to include here): ```xml - + @@ -1550,10 +1164,6 @@ Here's an example es_find_rules.xml file for Unix (this is not the complete file /usr/lib64/libretro /usr/lib/libretro - - /usr/local/lib/libretro - - /usr/pkg/lib/libretro @@ -1763,14 +1373,497 @@ For reference, here are also example es_find_rules.xml files for macOS and Windo ``` +## es_systems.xml + +The es_systems.xml file contains the game systems configuration data for ES-DE, written in XML format. This defines the system name, the full system name, the ROM path, the allowed file extensions, the launch command, the platform (for scraping) and the theme to use. + +ES-DE ships with a comprehensive `es_systems.xml` file and most users will probably never need to make any customizations. But there may be special circumstances such as wanting to use different emulators for some game systems or perhaps to add additional systems altogether. + +To accomplish this, ES-DE supports customizations via a separate es_systems.xml file that is to be placed in the `custom_systems` folder in the application home directory, i.e. `~/ES-DE/custom_systems/es_systems.xml`. (The tilde symbol `~` translates to `$HOME` on Unix and macOS, and to `%HOMEPATH%` on Windows unless overridden via the --home command line option.) + +This custom file functionality is designed to be complementary to the bundled es_systems.xml file, meaning you should only add entries to the custom configuration file for game systems that you actually want to add or override. So to for example customize a single system, this file should only contain a single `` tag. The structure of the custom file is identical to the bundled file with the exception of an additional optional tag named ``. If this is placed in the custom es_systems.xml file, ES-DE will not load the bundled file. This is normally not recommended and should only be used for special situations. At the end of this section you can find an example of a custom es_systems.xml file. + +The bundled es_systems.xml file is located in the resources directory that is part of the application installation. For example this could be `/usr/share/es-de/resources/systems/linux/es_systems.xml` on Linux, `/Applications/ES-DE.app/Contents/Resources/resources/systems/macos/es_systems.xml` on macOS or `C:\Program Files\ES-DE\resources\systems\windows\es_systems.xml` on Windows. The actual location may differ from these examples of course, depending on where ES-DE has been installed. + +If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. + +It doesn't matter in which order you define the systems as they will be sorted by the `` tag or by the optional `` tag when displayed inside the application. But it's still a good idea to add the systems in alphabetical order to make the configuration file easier to maintain. + +Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. + +But instead of changing the sorting directly in the es_systems.xml file it could be a better idea to use the dedicated es_systems_sorting.xml file instead. How to do that is described later in this document. + +Wildcards are supported for emulator binaries, but not for directories: +```xml + +~/Applications/yuzu*.AppImage %ROM% + +~/Applications/yuzu*.App* %ROM% + +~/App*/yuzu*.AppImage %ROM% +``` + +There is a special case when it comes to file extensions where it's possible to use extensionless files if required. To accomplish this simply add a dot (.) to the list of extensions in the `` tag. Obviously this makes it impossible to use the _directories interpreted as files_ functionality as there is no file extension, but apart from that everything should work the same as for regular files. + +Keep in mind that you have to set up your emulators separately from ES-DE as the es_systems.xml file assumes that your emulator environment is properly configured. + +Below is an overview of the file layout with various examples. For the command tag, the newer es_find_rules.xml logic described later in this document removes the need for most of the legacy options, but they are still supported for special configurations and for backward compatibility with old configuration files. + +```xml + + + + + + + snes + + + Nintendo SNES (Super Nintendo) + + + Super Nintendo + + + %ROMPATH%/snes + + + .smc .SMC .sfc .SFC .swc .SWC .fig .FIG .bs .BS .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP + + + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + + + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + + + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% + + + retroarch -L ~/.config/retroarch/cores/snes9x_libretro.so %ROM% + + + retroarch -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + + + ~/Applications/rpcs3*.AppImage --no-gui %ROM% + + + /Applications/RetroArch.app/Contents/MacOS/RetroArch -L %CORE_RETROARCH%/snes9x_libretro.dylib %ROM% + + + retroarch.exe -L %EMUPATH%\cores\snes9x_libretro.dll %ROM% + + + "C:\My Games\RetroArch\retroarch.exe" -L "%EMUPATH%\cores\snes9x_libretro.dll" %ROM% + + + "%ESPATH%\RetroArch\retroarch.exe" -L "%ESPATH%\RetroArch\cores\snes9x_libretro.dll" %ROM% + + + %HIDEWINDOW% %EMULATOR_MAME% %STARTDIR%=%EMUDIR% -rompath %ROMPATH%\arcade %BASENAME% + + + %EMULATOR_MAME% %STARTDIR%=~/.mame -rompath %ROMPATH%/arcade %BASENAME% + + + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + + + %HIDEWINDOW% %ESCAPESPECIALS% %RUNINBACKGROUND% cmd.exe /C %ROM% + + + PLACEHOLDER %ROM% + + + snes + + + snes + + +``` + +The following variable is expanded for the `path` tag: + +`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. + +The following variables are expanded for the `command` tag: + +`%ROM%` - Replaced with the absolute path to the selected ROM, with most special characters escaped with a backslash. + +`%ROMRAW%` - Replaced with the unescaped, absolute path to the selected ROM. If your emulator is picky about paths, you might want to use this instead of %ROM%, but enclosed in quotes. + +`%ROMPATH%` - Replaced with the path defined in the setting ROMDirectory in es_settings.xml. If combined with a path that contains blankspaces, then it must be surrounded by quotation marks, for example `%ROMPATH%"\Arcade Games"`. Note that the quotation mark must be located before the directory separator in this case. + +`%BASENAME%` - Replaced with the "base" name of the path to the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar` + +`%FILENAME%` - Replaced with the filename of the selected ROM. For example the path `/foo/bar.rom` would end up as the value `bar.rom` + +`%STARTDIR%` - The directory to start in when launching the emulator. Must be defined as a pair separated by an equal sign. This is normally not required, but some emulators and game engines like standalone MAME and OpenBOR will not work properly unless you're in the correct directory when launching a game. Either an absolute path can be used, such as `%STARTDIR%=C:\Games\mame` or some variables are available that provide various functions. The `%EMUDIR%` variable can be used to start in the directory where the emulator binary is located, i.e. `%STARTDIR%=%EMUDIR%`, the `%GAMEDIR%` variable can be used to start in the directory where the game file is located, i.e. `%STARTDIR%=%GAMEDIR%` and the `%GAMEENTRYDIR%` variable can be used which works identically to `%GAMEDIR%` with the exception that it will interpret the actual game entry as the start directory. This is useful in very rare situations like for the EasyRPG Player where the game directories are interpreted as files but where the game engine must still be started from inside the game directory. If an absolute path is set that contains blankspaces, then it must be surrounded by quotation marks, for example `%STARTDIR%="C:\Retro games\mame"`. If the directory defined by this variable does not exist, it will be created on game launch. The variable can be placed anywhere in the launch command if the %EMULATOR_ variable is used, otherwise it has to be placed after the emulator binary. + +`%INJECT%` - This allows the injection of launch arguments or environment variables stored in a text file on the filesystem. The %INJECT% variable must be defined as a pair separated by an equal sign, for example `%INJECT%=game.commands`. The `%BASENAME%` variable can also be used in conjunction with this variable, such as `%INJECT%=%BASENAME%.commands`. By default a path relative to the game file will be assumed but it's also possible to use an absolute path or the ~ (tilde) symbol which will expand to the home directory. If a path contains spaces it needs to be surrounded by quotation marks, such as `%INJECT%="C:\My games\ROMs\daphne\%BASENAME%.daphne\%BASENAME%.commands"`. The variable can be placed anywhere in the launch command and the file contents will be injected at that position. It's also possible to have multiple injections by defining the variable more than once at different locations in the launch command string. The specified file is optional, if it does not exist, is empty, or if there are insufficient permissions to read the file, then it will simply be skipped. For safety reasons the injection file can only have a maximum size of 4096 bytes and if it's larger than this it will be skipped and a warning will be written to es_log.txt. + +`%EMUPATH%` - Replaced with the path to the emulator binary. This variable is used for manually specifying emulator core locations, and a check for the existence of the core file will be done on game launch and an error displayed if it can't be found. Normally %EMUPATH% should not be used as the %CORE_ variable is the recommended method for defining core locations. + +`%EMUDIR%` - Replaced with the path to the emulator binary. This is a general purpose variable as opposed to %EMUPATH% which is intended specifically for core locations. + +`%GAMEDIR%` - Replaced with the path to the game. + +`%GAMEDIRRAW%` - Replaced with the unescaped path to the game. + +`%ESPATH%` - Replaced with the path to the ES-DE binary. Mostly useful for portable emulator installations, for example on a USB memory stick. + +`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. The find rules are explained in more detail below. + +`%PRECOMMAND_` - This utilizes the emulator find rules as defined in `es_find_rules.xml` to locate a pre-command binary. It's for instance useful for running Windows emulators on Linux using Wine or Proton. The %PRECOMMAND_ entry can be located anywhere in the launch command but it should be placed before the %EMULATOR_ variable in order to work as intended. + +`%CORE_` - This utilizes the core find rules as defined in `es_find_rules.xml`. This is the recommended way to configure the launch command. + +`%RUNINBACKGROUND%` - When this variable is present, ES-DE will continue to run in the background while a game is launched. This will also prevent the gamelist video from playing, the screensaver from starting, and the game name and game description from scrolling. This functionality is required for some systems such as Valve Steam. The variable can be placed anywhere in the launch command. + +`%HIDEWINDOW%` - This variable is only available on Windows and is used primarily for hiding console windows when launching scripts (used for example by Steam games and source ports). If not defining this, the console window will be visible when launching games. The variable can be placed anywhere in the launch command. + +`%ESCAPESPECIALS%` - This variable is only available on Windows and is used to escape the characters &()^=;, for the %ROM% variable, which would otherwise make binaries like cmd.exe fail when launching scripts or links. The variable can be placed anywhere in the launch command. + +`%ENABLESHORTCUTS%` - This variable is only available on Unix and macOS and is used to enable shortcuts to games and applications. On Unix these come in the form of .desktop files and ES-DE has a simple parser which essentially extracts the command defined in the Exec key and then executes it. Although some basic file structure checks are performed, the actual command listed with the Exec key is blindly executed. In addition to this the variables %F, %f, %U and %u are removed from the Exec key entry. On macOS shortcuts in the form of .app directories and alias files are executed using the `open -W -a` command. This makes it possible to launch shortcuts to emulators and applications like Steam as well as aliases for any application. However the latter need to be renamed to the .app file extension or it won't work. When a file is matching the .desktop or .app extension respectively, the emulator command defined using the %EMULATOR% variable will be stripped. An %EMULATOR% entry is however still required for the %ENABLESHORTCUTS% variable to work as the intention is to combine shortcuts with the ability to launch shell scripts without having to setup alternative emulators. The %ROM% variable is expanded to the command to execute when using %ENABLESHORTCUTS%, which also means that this variable has to be used, and for example %ROMRAW% will not work. + +Here are some additional real world examples of system entries, the first one for Unix: + +```xml + + dos + DOS (PC) + %ROMPATH%/dos + .bat .BAT .com .COM .conf .CONF .cue .CUE .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% + dos + dos + +``` + +Then one for macOS: + +```xml + + n64 + Nintendo 64 + %ROMPATH%/n64 + .n64 .N64 .v64 .V64 .z64 .Z64 .bin .BIN .u1 .U1 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.dylib %ROM% + n64 + n64 + +``` + +And finally one for Windows: + +```xml + + pcengine + NEC PC Engine + %ROMPATH%\pcengine + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_fast_libretro.dll %ROM% + pcengine + pcengine + +``` + +As well, here's an example for Linux of a custom es_systems.xml file placed in ~/ES-DE/custom_systems/ that overrides a single game system from the bundled configuration file: +```xml + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + +``` + +If adding the `` tag to the file, the bundled es_systems.xml file will not be processed. For this example it wouldn't be a very good idea as NES would then be the only platform that could be used in ES-DE. + +```xml + + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + +``` + +Here is yet another example with the addition of the `snes` system where some file extensions and alternative emulator entries have been removed, and the full name and sorting have been modified. + +```xml + + + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .nes .NES .zip .ZIP + /usr/games/fceux %ROM% + nes + nes + + + snes + Super Nintendo + Nintendo SNES (Super Nintendo) + %ROMPATH%/snes + .smc .SMC .sfc .SFC .swc .SWC .bin .BIN .mgd .MGD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + snes + snes + + +``` + +## es_find_rules.xml and es_systems.xml on Android + +ES-DE works a bit differently on Android which is also reflected in the es_find_rules.xml and es_systems.xml configuration. Emulators on Android are launched via so-called _Intents_ which is an API rather than the typical command line approach used on Unix systems. Although ES-DE on Windows also uses an API call to launch emulators it's still closely connected to the regular operating system paradigms on how to start binaries and pass application options so the systems configuration still looks quite traditional. On Android this is not the case and there is therefore a heavy use of variables to reflect the Intent API functionality. + +To better understand the configuration in this section it could be a good idea to refer the official Android documentation:\ +https://developer.android.com/reference/android/content/Intent + +There is a command line tool in Android named _am_ which implements the _Intent_ API and can be used to test emulator launching, but this is not intended to be used by other applications and therefore ES-DE implements direct (albeit partial) support for the Intent API. Testing the modern FileProvider interface using the _am_ utility may also be difficult, or maybe impossible. + +**es_find_rules.xml** + +The es_find_rules.xml file is structured the same as for the other operating systems but there'a special _androidpackage_ find rule where you define the name of the emulator package as well as optionally which _activity_ to launch. If the activity is not defined then the default one for the package will be used. Although this may work in some instances it's usually a good idea to explicity set it. Apart from that the find rules work as on the other platforms, i.e. they will be traversed in the order they are defined. So by adding multiple _androidpackage_ entries for an emulator it's possible to look for multiple releases or forks without having to create separate emulator entries in es_systems.xml. It's also possible to override find rules by adding an ES-DE/custom_systems/es_find_rules.xml file, again the same logic applies as for all other platforms. + +The _androidpackage_ find rule entries are structured as `packagename/activity` and if only a package is defined then the forward slash can be omitted, i.e. only `packagename` is needed. + +Here's an example es_find_rules.xml file defining two emulators: + +```xml + + + + + + com.retroarch.aarch64/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch.ra32/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch/com.retroarch.browser.retroactivity.RetroActivityFuture + + + + + + org.yuzu.yuzu_emu.ea/org.yuzu.yuzu_emu.activities.EmulationActivity + org.yuzu.yuzu_emu/org.yuzu.yuzu_emu.activities.EmulationActivity + + + +``` + +**es_systems.xml** + +The es_systems.xml file on Android utilizes variables heavily to implement the _Intent_ API and these variables are covered in detail below. It's possible to override the systems configuration by adding an ES-DE/custom_systems/es_systems.xml file, the same logic applies as for all other platforms. + +`%EMULATOR_` - This utilizes the emulator find rules as defined in `es_find_rules.xml`. This is the only way to configure the launch command on Android and it works identically to the other platforms. + +`%ACTION%` - The general Intent action to be performed, you need to assign its value using an equal sign. + +`%MIMETYPE%` - Sets an explicit MIME type, which you need to assign using an equal sign such as %MIMETYPE%=text/plain. You will rarely, if ever, need to set an explicit MIME type so this variable is of limited use. By default Android will set the MIME type to application/octet-stream which is normally what you want. + +There are two main ways to pass options to emulators, using _extras_ or using the _data_ URI. There can only be a single data URI but there can be an arbitrary amount of extras. To understand more about the way this works, you can read about the _putExtra()_ and and _setData()_ functions here:\ +https://developer.android.com/reference/android/content/Intent + +`%EXTRA_` - This passes an _extra_ which contains any additional information that the emulator may support. This is provided as a key/value pair where you define the key name following the literal %EXTRA_ string and terminate it with a % sign and then assign the value using an equal sign. For example %EXTRA_LIBRETRO%=puae_libretro_android.so will pass the extra named _LIBRETRO_ with its value set to _puae_libretro_android.so_. You can pass an unlimited number of extras and you can also use various ROM variables in combination with this as described below. + +`%EXTRAARRAY_` - Defines an array of comma-separated string values following the key name. Only literal strings are supported, so this can't be used in combination with any ROM variables. As commas are used as separator characters, you'll need to escape any comma signs that you want to include in the actual value. For example %EXTRAARRAY_Parameters%=pone,p\\,two,pthree will pass the extra named _Parameters_ with the three separate array entries _pone_, _p,two_ and _pthree_. + +`%EXTRABOOL_` - Sets an extra with a boolean value, i.e. true/1 or false/0. + +`%DATA%` - Sets the data URI value for the intent using an equal sign. This is normally combined with one of the ROM variables. + +There are three approaches to passing game ROMs to emulators by using the following variables: + +`%ROM%` - Replaced with the absolute path to the selected ROM. This is a traditional method to provide the game ROM and its use will likely decrease or go away completely long term as emulators move to more modern methods. + +`%ROMSAF%` - Replaced with an Android Storage Access Framework (SAF) document URI which always starts with the _content://com.android.externalstorage.documents/_ string. You can read more about the SAF here:\ +https://developer.android.com/guide/topics/providers/document-provider + +`%ROMPROVIDER%` - This is the most modern approach to passing game ROMs to emulators. It uses the _FileProvider_ API to provide permissions to the file. This means that you don't need to setup the emulator upfront to have access to the directory where the game file is stored, access is instead temporarily granted by ES-DE. You can read more about the FileProvider API here:\ +https://developer.android.com/reference/androidx/core/content/FileProvider + +The `%ROM%` and `%ROMSAF%` variables can be used with both the `%DATA%` and `%EXTRA_` variables, but `%ROMPROVIDER%` can only be used with the `%DATA%` variable. For the `%DATA%` variable you'll just assign the ROM variable with an equal sign as there can only be a single _setData()_ API call per Intent. For the `%EXTRA_` variable you need to specify a name of the extra and then define it using an equal sign as an arbitrary amount of _putExtra()_ API calls can be used for an Intent. + +Here are some examples to clarify how this works: +``` +%DATA%=%ROM% +%DATA%=%ROMSAF% +%DATA%=%ROMPROVIDER% +%EXTRA_ROM%=%ROM% +%EXTRA_bootPath%=%ROMSAF% +%EXTRABOOL_resumeState%=false +``` + +There is also support for a couple of activity flags that affect the emulator/game launch behavior, you can read more about these flags here:\ +https://developer.android.com/reference/android/content/Intent + +The descriptions below are taken from the official documentation just linked above: + +`%ACTIVITY_CLEAR_TASK%` - If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. + +`%ACTIVITY_CLEAR_TOP%` - If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent. + +`%ACTIVITY_NO_HISTORY%` - If set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished. This may also be set with the noHistory attribute. If set, onActivityResult() is never invoked when the current activity starts a new activity which sets a result and finishes. + +Here's an example es_systems.xml file for Android: +```xml + + + + + gc + Nintendo GameCube + %ROMPATH%/gc + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/dolphin_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DOLPHIN% %ACTION%=android.intent.action.MAIN %DATA%=%ROMPROVIDER% + gc + gc + + + n3ds + Nintendo 3DS + %ROMPATH%/n3ds + .3ds .3DS .3dsx .3DSX .app .APP .axf .AXF .cci .CCI .cxi .CXI .elf .ELF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/citra_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_CITRA% %ACTIVITY_NO_HISTORY% %EXTRA_SelectedGame%=%ROMSAF% + %EMULATOR_CITRA-MMJ% %EXTRA_GamePath%=%ROM% + n3ds + n3ds + + + psx + Sony PlayStation + %ROMPATH%/psx + .bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DUCKSTATION% %EXTRABOOL_resumeState%=false %EXTRA_bootPath%=%ROMSAF% + psx + psx + + +``` + +## es_systems_sorting.xml + +This file makes it possible to apply custom systems sorting without having to modify the es_systems.xml file directly. It should be placed in the custom_systems directory, e.g. `~/ES-DE/custom_systems/es_systems_sorting.xml` + +Note that in order for ES-DE to load this file you'll need to set the _Systems sorting_ option in the _UI settings_ menu to _Full names or custom_. + +The structure of this file is essentially a simplified version of the es_systems.xml file, but with only the `` and `` tags present per system. + +Here's an example where three systems have been sorted by release year instead of the default full system name: + +```xml + + + + amiga + 1985 + + + c64 + 1982 + + + vic20 + 1980 + + +``` + +You only need to include systems that you want to customize sorting for, and if there's also a systemsortname tag present in the es_systems.xml file for any system, then the es_systems_sorting.xml entry will take precedence. + +Note that the `` tags are sorted in [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order) so 11 will be sorted above 2 but 002 will be sorted above 011. Secondary sorting will always be done by the fullname tag in es_systems.xml. + +There are also four complete sorting files bundled with ES-DE, you can find them in the resources/sorting/ directory, or you can access them [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/sorting). + +These files include all systems supported by ES-DE and provide the following sorting options: + +* Release year +* Manufacturer, release year +* Hardware type, release year +* Manufacturer, hardware type, release year + +You can apply any of these sorting files via the _Systems sorting_ option in the _Other settings_ menu. Note that in order to load a es_systems_sorting.xml file placed in the custom_systems directory you'll need to set this option to _Full names or custom_. + ## gamelist.xml The gamelist.xml file for a system defines the metadata for its entries, such as the game names, descriptions, release dates and ratings. -As of the fork to EmulationStation Desktop Edition, game media information no longer needs to be defined in the gamelist.xml files. Instead the application will look for any media matching the ROM filename. The media path where to look for game media is configurable either manually in `es_settings.xml` or via the GUI. If configured manually in es_settings.xml, it looks something like this: +As of the fork to ES-DE, game media information no longer needs to be defined in the gamelist.xml files. Instead the application will look for any media matching the ROM filename. The media path where to look for game media is configurable either manually in `es_settings.xml` or via the GUI. If configured manually in es_settings.xml, it looks something like this: ```xml - + ``` There is also support to add the variable %ESPATH% to the media directory setting, this will expand to the path where the ES-DE executable is started from. You should normally not need this, but the option is there for special cases. For example: @@ -1779,17 +1872,17 @@ There is also support to add the variable %ESPATH% to the media directory settin ``` -The default media directory is `~/.emulationstation/downloaded_media` +The default media directory is `~/ES-DE/downloaded_media` You can use ES-DE's scrapers to populate the gamelist.xml files, or manually update individual entries using the metadata editor. All of this is explained in the [User guide](USERGUIDE.md). -The gamelist.xml files are searched for in the ES-DE home directory, i.e. `~/.emulationstation/gamelists//gamelist.xml` +The gamelist.xml files are searched for in the ES-DE home directory, i.e. `~/ES-DE/gamelists//gamelist.xml` For example: ``` -~/.emulationstation/gamelists/c64/gamelist.xml -~/.emulationstation/gamelists/megadrive/gamelist.xml +~/ES-DE/gamelists/c64/gamelist.xml +~/ES-DE/gamelists/megadrive/gamelist.xml ``` **gamelist.xml file structure** @@ -1920,7 +2013,7 @@ Before attempting to add a custom profile for your controller you need to check ES-DE uses the [SDL](https://www.libsdl.org) (Simple DirectMedia Layer) library to handle controller input, so in order for a controller to work in ES-DE, it has to be supported by SDL. There is however a possibility to add custom controller profiles to SDL which in some cases could enable devices in ES-DE that would otherwise not be supported. This is generally a temporary solution though, as controller support is constantly getting improved natively in SDL. As a first step it's therefore recommended to open a request at the SDL [issue tracker](https://github.com/libsdl-org/SDL/issues) to have your specific controller added to a future SDL release. -Assuming the controller works in other applications than ES-DE, you can attempt to add a custom profile by creating the file `~/.emulationstation/es_controller_mappings.cfg` and enter the appropriate configuration inside this file. +Assuming the controller works in other applications than ES-DE, you can attempt to add a custom profile by creating the file `~/ES-DE/controllers/es_controller_mappings.cfg` and enter the appropriate configuration inside this file. The required format is described here:\ https://github.com/gabomdq/SDL_GameControllerDB @@ -1930,7 +2023,7 @@ https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontro But just do this as a first step to see whether you controller gets enabled. If it does, then you should remove all entries that are not relevant. That is important as this file will take precedence over the built-in controller profiles in the SDL library, so any future controller bug fixes and similar would not apply. In the past the gamecontrollerdb.txt file has also included some invalid configuration entries, so even though it may make your controller work, it could actually break some other controllers that you may want to use now or in the future. -Therefore only keep the entries in the es_controller_mappings.cfg file that are relevant for your devices. You can find each relevant controller GUID by starting ES-DE and then looking in the ~/.emulationstation/es_log.txt file. You should see entries such as the following: +Therefore only keep the entries in the es_controller_mappings.cfg file that are relevant for your devices. You can find each relevant controller GUID by starting ES-DE and then looking in the `~/ES-DE/logs/es_log.txt` file. You should see entries such as the following: ``` May 16 18:26:17 Info: Added controller with custom configuration: "X360 Controller" (GUID: 030000005e0400008e02000010010000, instance ID: 0, device index: 0) ``` @@ -1952,26 +2045,26 @@ For this example, let's assume that the removable media has the device name `F:\ These are the steps to perform: * Install ES-DE -* Copy the EmulationStation-DE installation directory to F:\ -* Create a directory named F:\EmulationStation-DE\Emulators -* Copy your emulator directories to F:\EmulationStation-DE\Emulators\ -* Copy your ROMs directory to F:\EmulationStation-DE\ -* Create an empty file named portable.txt in F:\EmulationStation-DE\ +* Copy the ES-DE installation directory to F:\ +* Create a directory named F:\ES-DE\Emulators +* Copy your emulator directories to F:\ES-DE\Emulators\ +* Copy your ROMs directory to F:\ES-DE\ +* Create an empty file named portable.txt in F:\ES-DE\ You should end up with something like this: ``` -F:\EmulationStation-DE\ -F:\EmulationStation-DE\Emulators\dosbox-staging\ -F:\EmulationStation-DE\Emulators\RetroArch-Win64\ -F:\EmulationStation-DE\Emulators\RPCS3\ -F:\EmulationStation-DE\Emulators\xemu\ -F:\EmulationStation-DE\ROMs\ -F:\EmulationStation-DE\portable.txt +F:\ES-DE\ +F:\ES-DE\Emulators\dosbox-staging\ +F:\ES-DE\Emulators\RetroArch-Win64\ +F:\ES-DE\Emulators\RPCS3\ +F:\ES-DE\Emulators\xemu\ +F:\ES-DE\ROMs\ +F:\ES-DE\portable.txt ``` -This is just an example as you may of course not use these specific emulators. There are also many more emulators supported as detailed in the `es_find_rules.xml` configuration file. As well there will be many more files and directories than those listed above inside the F:\EmulationStation-DE folder. +This is just an example as you may of course not use these specific emulators. There are also many more emulators supported as detailed in the `es_find_rules.xml` configuration file. As well there will be many more files and directories than those listed above inside the F:\ES-DE folder. -How the portable setup works is that when ES-DE finds a file named portable.txt in its executable directory, it will by default locate the .emulationstation directory directly inside this folder. It's also possible to modify portable.txt with a path relative to the ES-DE executable directory. For instance if two dots `..` are placed inside the portable.txt file, then the .emulationstation directory will be located in the parent folder, which would be directly under F:\ for this example. +How the portable setup works is that when ES-DE finds a file named portable.txt in its executable directory, it will by default locate the ES-DE application data directory directly inside this folder. It's also possible to modify portable.txt with a path relative to the ES-DE executable directory. For instance if two dots `..` are placed inside the portable.txt file, then the ES-DE application data directory will be located in the parent folder, which would be directly under F:\ for this example. If the --home command line parameter is passed when starting ES-DE, that will override the portable.txt file. @@ -1980,12 +2073,12 @@ Start ES-DE from the F:\ device and check that everything works as expected. Jus Following this, optionally copy any existing gamelist.xml files, game media files etc. to the removable media. For example: ``` -F:\EmulationStation-DE\.emulationstation\collections\ -F:\EmulationStation-DE\.emulationstation\downloaded_media\ -F:\EmulationStation-DE\.emulationstation\gamelists\ +F:\ES-DE\ES-DE\collections\ +F:\ES-DE\ES-DE\downloaded_media\ +F:\ES-DE\ES-DE\gamelists\ ``` -You could alternatively copy over your entire .emulationstation directory, but in this case make sure that you have no settings in es_settings.xml that point to a specific location on your local filesystem, such as the game ROMs or game media directories. +You could alternatively copy over your entire ES-DE application data directory, but in this case make sure that you have no settings in es_settings.xml that point to a specific location on your local filesystem, such as the game ROMs or game media directories. You now have a fully functional portable retrogaming installation! @@ -2028,7 +2121,7 @@ The following examples are for Unix systems, but it works the same way on macOS As can be seen in the table above, the events executed when a game starts and ends are named _game-start_ and _game-end_ -So let's create the folders for these events in the scripts directory. The location is `~/.emulationstation/scripts` +So let's create the folders for these events in the scripts directory. The location is `~/ES-DE/scripts` **Game log** @@ -2039,7 +2132,7 @@ Let's name the start script `game_start_logging.sh` with the following contents: ``` #!/bin/bash TIMESTAMP=$(date +%Y-%m-%d' '%H:%M:%S) -echo Starting game "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/.emulationstation/game_playlog.txt +echo Starting game "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/ES-DE/logs/game_playlog.txt ``` And let's name the end script `game_end_logging.sh` with the following contents: @@ -2047,14 +2140,14 @@ And let's name the end script `game_end_logging.sh` with the following contents: ``` #!/bin/bash TIMESTAMP=$(date +%Y-%m-%d' '%H:%M:%S) -echo "Ending game " "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/.emulationstation/game_playlog.txt +echo "Ending game " "\""${2}"\"" "\""${4}"\"" "(\""${1}"\")" at $TIMESTAMP >> ~/ES-DE/logs/game_playlog.txt ``` After creating the two scripts, you should have something like this on the filesystem: ``` -~/.emulationstation/scripts/game-start/game_start_logging.sh -~/.emulationstation/scripts/game-end/game_end_logging.sh +~/ES-DE/scripts/game-start/game_start_logging.sh +~/ES-DE/scripts/game-end/game_end_logging.sh ``` Don't forget to make the scripts executable (e.g. "chmod 755 ./game_start_logging.sh"). @@ -2063,15 +2156,14 @@ If we now start ES-DE with the debug flag and launch a game, something like the ``` Aug 05 14:19:24 Debug: Scripting::fireEvent(): game-start "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" -Aug 05 14:19:24 Debug: Executing: /home/myusername/.emulationstation/scripts/game-start/game_start_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" +Aug 05 14:19:24 Debug: Executing: /home/myusername/ES-DE/scripts/game-start/game_start_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" . . Aug 05 14:27:15 Debug: Scripting::fireEvent(): game-end "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" "" -Aug 05 14:27:15 Debug: Executing: /home/myusername/.emulationstation/scripts/game-end/game_end_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" - +Aug 05 14:27:15 Debug: Executing: /home/myusername/ES-DE/scripts/game-end/game_end_logging.sh "/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip" "The Legend Of Zelda" "nes" "Nintendo Entertainment System" ``` -Finally after running some games, ~/.emulationstation/game_playlog.txt should contain something like the following: +Finally after running some games, ~/ES-DE/logs/game_playlog.txt should contain something like the following: ``` Starting game "The Legend Of Zelda" "Nintendo Entertainment System" ("/home/myusername/ROMs/nes/Legend\ of\ Zelda,\ The.zip") at 2020-08-05 14:19:24 @@ -2099,7 +2191,7 @@ Then create the end script, which we'll name `set_resolution_4K.sh`: #!/bin/sh xrandr -s 3840x2160 sleep 0.3 -xdotool search --class emulationstation windowactivate +xdotool search --class es-de windowactivate ``` The last two lines are optional, they're used to set the focus back to ES-DE in case you're running attention-seeking applications such as Kodi which may steal focus after resolution changes. You may need to adjust the sleep time to get this to work reliably though, as the timing may differ between different computers and graphics drivers. @@ -2107,8 +2199,8 @@ The last two lines are optional, they're used to set the focus back to ES-DE in After creating the two scripts, you should have something like this on the filesystem: ``` -~/.emulationstation/scripts/game-start/set_resolution_1080p.sh -~/.emulationstation/scripts/game-end/set_resolution_4K.sh +~/ES-DE/scripts/game-start/set_resolution_1080p.sh +~/ES-DE/scripts/game-end/set_resolution_4K.sh ``` Don't forget to make the scripts executable (e.g. "chmod 755 ./set_resolution_1080p.sh"). diff --git a/LICENSE b/LICENSE index 5f27c157e..84a609b0d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 Leon Styhre +Copyright (c) 2020-2024 Leon Styhre Copyright (c) 2014 Alec Lofquist Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/README.md b/README.md index f5dbb1713..6f207fde1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) +# ES-DE (EmulationStation Desktop Edition) EmulationStation Desktop Edition is a frontend for browsing and launching games from your multi-platform game collection. diff --git a/ROADMAP.md b/ROADMAP.md index 6e6584f42..6f2898e06 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) - Feature roadmap +# ES-DE (EmulationStation Desktop Edition) - Feature roadmap ES-DE is developed using an agile methodology so which features to include per release is reviewed and adjusted continuously. As such this document is basically a list of the main features that are planned to be added eventually. diff --git a/THEMES-DEV.md b/THEMES-DEV.md index cf3e2b108..cf78e75de 100644 --- a/THEMES-DEV.md +++ b/THEMES-DEV.md @@ -1,8 +1,8 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 (development version) - Themes +# ES-DE (EmulationStation Desktop Edition) v3.0 (development version) - Themes **Note:** This document is only relevant for the current ES-DE development version, if you would like to see the documentation for the latest stable release, refer to [THEMES.md](THEMES.md) instead. -If creating themes specifically for ES-DE, please add `-es-de` to the repository/directory name, as in `slate-es-de`. Themes made for ES-DE are not compatible with any other EmulationStation forks (and vice versa) and the -es-de extension makes it clear that it's an ES-DE theme. The actual theme name as defined using the `themeName` tag in capabilities.xml does of course not need to include the `-es-de` extension as that's the actual theme name that will be displayed when selecting themes from the _UI Settings_ menu. For example slate-es-de will be listed simply as _Slate_ in this menu. +If creating themes for ES-DE, please add `-es-de` to the repository/directory name to clearly indicate that it's a theme for this frontend. Two examples would be `linear-es-de` and `modern-es-de`. The actual theme name as defined using the `themeName` tag in capabilities.xml does of course not need to include the `-es-de` extension as that's the actual theme name that will be displayed when selecting themes from the _UI Settings_ menu. For example linear-es-de will be listed simply as _Linear_ in this menu. Before your start, make sure to download the _Theme engine examples_ theme that contains a number of example variants for things like vertical and horizontal carousels, wheel carousels, system view text lists, grids etc: @@ -18,7 +18,7 @@ https://github.com/lilbud/es-de-theme-stuff To test whether your theme includes support for all ES-DE systems, download one of the following archives which contain ROM directory trees fully populated with dummy files: -[ROMs_ALL_Unix.zip](tools/system-dirs-dummy-files/ROMs_ALL_Unix.zip)\ +[ROMs_ALL_Linux.zip](tools/system-dirs-dummy-files/ROMs_ALL_Linux.zip)\ [ROMs_ALL_macOS.zip](tools/system-dirs-dummy-files/ROMs_ALL_macOS.zip)\ [ROMs_ALL_Windows.zip](tools/system-dirs-dummy-files/ROMs_ALL_Windows.zip) @@ -158,17 +158,19 @@ Note that the legacy theme engine had quite inaccurate text sizing and font rend * The defined line spacing was not always applied for automatically sized text elements * Font sizes were rounded to integers, leading to imprecise text sizing across different resolutions (the rounding was also done incorrectly) -## System metadata and logo repositories +## Theme assets repositories -There are two useful repositories hosted by the ES-DE project that provide system metadata and system logotypes. This greatly simplifies the work of adding support for all systems that ES-DE supports. +There are several useful repositories hosted by the ES-DE project that provide system metadata and system graphics files. Using these greatly simplifies the work of adding support for all ES-DE systems to your theme. -**Metadata** +Make sure to regularly check for updates in these repositories as corrections, improvements and additions of new systems are made continuously. + +### Metadata The metadata repository provides descriptions, release dates, per-system color palettes etc. and it can be found here: https://gitlab.com/es-de/themes/system-metadata -By adding this to your theme, either via manually downloading and including it, or by adding it as a Git subtree, you'll be able to access its defined variables. Make sure to regularly check for updates as corrections and additions of new systems are done continuously. Also check the README.md file in the repository for more details on how to actually use the variables. +By adding this to your theme, either via manually downloading and including it, or by adding it as a Git subtree, you'll be able to access its defined variables. Check the README.md file in the repository for details on how to actually use the variables. Here's how to add this repository as a subtree inside your theme's Git repository: ``` @@ -183,9 +185,47 @@ git subtree pull --prefix=system-metadata --squash system-metadata master The directory name can be changed to whatever you like using the --prefix flag. -**Logos** +### Controller outline graphics -Likewise there's a repository of system logotypes that can also be added and used in the same fashion as the metadata. It can be found here: +This repository provides controller graphics files for each system in an outline style and it can be found here: + +https://gitlab.com/es-de/themes/system-controllers-outline + +Here's how to add this repository as a subtree inside your theme's Git repository: +``` +git remote add system-controllers-outline https://gitlab.com/es-de/themes/system-controllers-outline.git +git subtree add --prefix=system-controllers-outline --squash system-controllers-outline master +``` + +To later pull in repository updates you'll run the following: +``` +git subtree pull --prefix=system-controllers-outline --squash system-controllers-outline master +``` + +The directory name can be changed to whatever you like using the --prefix flag. + +### Mini system graphics + +This repository provides graphics files for each system in a "mini" style and it can be found here: + +https://gitlab.com/es-de/themes/system-graphics-mini + +Here's how to add this repository as a subtree inside your theme's Git repository: +``` +git remote add system-graphics-mini https://gitlab.com/es-de/themes/system-graphics-mini.git +git subtree add --prefix=system-graphics-mini --squash system-graphics-mini master +``` + +To later pull in repository updates you'll run the following: +``` +git subtree pull --prefix=system-graphics-mini --squash system-graphics-mini master +``` + +The directory name can be changed to whatever you like using the --prefix flag. + +### Logos + +This repository provides logos for each system in color and white (the latter for use with color shifting) and it can be found here: https://gitlab.com/es-de/themes/system-logos @@ -202,11 +242,13 @@ git subtree pull --prefix=system-logos --squash system-logos master The directory name can be changed to whatever you like using the --prefix flag. -**Adding remotes** +### Adding remotes -Note that the remotes are only setup for your local repository, so if you clone a theme you'll need to manually add the system-metadata and/or system-logos remotes to be able to pull to these subtrees. That means you'll need to run the following commands on a freshly cloned theme repository: +Note that the remotes are only setup for your local repository, so if you clone a theme you'll need to manually add the repository remotes to be able to pull from these subtrees. That means you'll need to run one or more of the following commands on a freshly cloned theme repository: ``` git remote add system-metadata https://gitlab.com/es-de/themes/system-metadata.git +git remote add system-controllers-outline https://gitlab.com/es-de/themes/system-controllers-outline.git +git remote add system-graphics-mini https://gitlab.com/es-de/themes/system-graphics-mini.git git remote add system-logos https://gitlab.com/es-de/themes/system-logos.git ``` After doing this you'll be able to pull repository updates as described above. @@ -611,6 +653,95 @@ Here's an example configuration: ``` +## Font sizes + +The optional font sizes functionality makes it possible to use a set of predefined size options and connect these to theme variables that can be used to apply different text sizes and related design changes. The font sizes declared for the theme can be selected via the _Theme font size_ setting in the _UI Settings_ menu. + +To understand the basics on how to use variables, make sure to read the _Theme variables_ section elsewhere in this document. + +To use the font size entries you first need to declare them using `` tag pairs in the `capabilities.xml` file. The following sizes are available: + +| capabilities.xml name | UI Settings label | +| :-------------------- | :--------------- | +| medium | medium | +| large | large | +| small | small | +| x-large | extra large | +| x-small | extra small | + +The options will always be listed in the above order in the _UI Settings_ menu. + +Here's an example of a theme that implements three of these sizes: + +```xml + + + My theme + + medium + small + x-small + +``` + +In the theme configuration you'll also use a `` tag pair combined with a `` tag pair to define the variables you want to apply per font size. + +These `` tag pairs can be placed directly inside the `` tags, inside the `` tags or inside the `` tags. + +The mandatory name attribute is used to specificy which font size to use, and multiple values can be specified at the same time by separating them by commas or by whitespace characters (tabs, spaces or line breaks). + +Here's an example configuration: + +```xml + + + + 0.025 + 0.5 0.6437 + 0.022 + 0.016 + + + + + 0.015 + 0.45 0.6437 + 0.013 + + + + + 0.008 + 0.4 0.6437 + 0.006 + + + + 0.011 + + + + + + ${gameCounterPos} + 1 0.056 + ${gameCounterFontSize} + + + + 0.2 0.3412 + 0.2 0.040 + ${gameNameFontSize} + + + 0.33 0.3412 + 0.18 0.040 + ${publisherFontSize} + + + +``` + ## Aspect ratios The aspect ratio support works almost identically to the variants and color schemes with the main difference that the available aspect ratios are hardcoded into ES-DE. The theme can still decide which of the aspect ratios to support (or none at all in which case the theme aspect ratio is left undefined) but it can't create entirely new aspect ratio entries. @@ -836,15 +967,18 @@ The variant, color scheme and transitions names as well as their labels can be s Unlike the types just mentioned, aspectRatio entries can not be set to arbitrary values, instead they have to use a value from the _horizontal name_ or _vertical name_ columns in the following table: -| Horizontal name | Vertical name | Common resolutions | -| :--------------- | :------------- | :--------------------------------------------- | -| 16:9 | 16:9_vertical | 1280x720, 1920x1080, 2560x1440, 3840x2160 | -| 16:10 | 16:10_vertical | 1280x800, 1440x900, 1920x1200 | -| 3:2 | 3:2_vertical | 2160x1440 | -| 4:3 | 4:3_vertical | 320x240, 640x480, 800x600, 1024x768, 1600x1200 | -| 5:4 | 5:4_vertical | 1280x1024 | -| 21:9 | 21:9_vertical | 2560x1080, 3840x1600, 5120x2160 | -| 32:9 | 32:9_vertical | 3840x1080, 5120x1440 | +| Horizontal name | Vertical name | Common resolutions | +| :--------------- | :-------------- | :--------------------------------------------- | +| 16:9 | 16:9_vertical | 1280x720, 1920x1080, 2560x1440, 3840x2160 | +| 16:10 | 16:10_vertical | 1280x800, 1440x900, 1920x1200 | +| 3:2 | 3:2_vertical | 2160x1440 | +| 4:3 | 4:3_vertical | 320x240, 640x480, 800x600, 1024x768, 1600x1200 | +| 5:4 | 5:4_vertical | 1280x1024 | +| 19.5:9 | 19.5:9_vertical | 2340x1080, 2532x1170 | +| 20:9 | 20:9_vertical | 2400x1080, 1600x720 | +| 21:9 | 21:9_vertical | 2560x1080, 3840x1600, 5120x2160 | +| 32:9 | 32:9_vertical | 3840x1080, 5120x1440 | +| 1:1 | 1:1 | Any square resolution | The 21:9 and 32:9 aspect ratios are approximate as monitors of slightly different ratios are collectively marketed using these numbers. @@ -1287,10 +1421,11 @@ It's important to understand how the theme configuration files are parsed in ord 1) Transitions 2) Variables 3) Color schemes -4) Included files -5) "General" (non-variant) configuration -6) Variants -7) Aspect ratios +4) Font sizes +5) Included files +6) "General" (non-variant) configuration +7) Variants +8) Aspect ratios When including a file using the `` tag (i.e. step 4 above) then all steps listed above are executed for that included file prior to continuing to the next line after the `` tag. @@ -1299,7 +1434,7 @@ For any given step, the configuration is parsed in the exact order that it's def ## Property data types * NORMALIZED_PAIR - two decimal values delimited by a space, for example `0.25 0.5` -* PATH - path to a resource. If the first character is a tilde (`~`) then it will be expanded to the user's home directory (`$HOME` for Unix and macOS and `%HOMEPATH%` for Windows) unless overridden using the --home command line option. If the first character is a dot (`.`) then the resource will be searched for relative to the location of the theme file, for example `./myfont.ttf` or `./../core/fonts/myfont.ttf` +* PATH - path to a resource. If the first character is a tilde (`~`) then it will be expanded to the user's home directory (`$HOME` for Linux, BSD Unix and macOS and `%HOMEPATH%` for Windows) unless overridden using the --home command line option. If the first character is a dot (`.`) then the resource will be searched for relative to the location of the theme file, for example `./myfont.ttf` or `./../core/fonts/myfont.ttf` * BOOLEAN - `true`/`1` or `false`/`0` * COLOR - a hexadecimal RGB or RGBA color value consisting of 6 or 8 digits. If a 6 digit value is used then the alpha channel will be set to `FF` (completely opaque) * UNSIGNED_INTEGER - an unsigned integer value @@ -1872,6 +2007,10 @@ Properties: - Where on the element `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the textlist exactly in the middle of the screen. If the position and size attributes are themeable, origin is implied. - Minimum value per axis is `0` and maximum value per axis is `1` - Default is `0 0` +* `selectorWidth` - type: FLOAT + - Width of the selector bar. If an image has been defined using `selectorImagePath` then setting this property to zero will retain the aspect ratio for that image. + - Minimum value is `0` and maximum value is `1` + - Default is the equivalent value as the width of the overall element. * `selectorHeight` - type: FLOAT - Height of the selector bar. This is expanded downwards so you'll probably want to adjust its position using `selectorVerticalOffset` if making use of this property. - Minimum value is `0` and maximum value is `1` @@ -2033,6 +2172,10 @@ Properties: - `always` - Set element as stationary during all transitions. - `never` - Don't set element as stationary during any transitions. - Default is `never` +* `renderDuringTransitions` - type: BOOLEAN + - This special property which is only usable for slide transitions between the system and gamelist views makes it possible to for example have a background image stay seamlessly in place when transitioning, or being able to use semi-transparent stationary elements without having them render on top of each other during transitions. For this to work correctly only define `stationary` for one view and set `renderDuringTransitions` to false for the corresponding element in the other view. This way the element from the former view will keep rendering until the slide animation has been completed, after which the latter view will "take over" by rendering the element normally. + - This property can only be used if slide transitions are used, and only when moving from the system view to the gamelist view, or vice versa. + - Default is `true` * `flipHorizontal` - type: BOOLEAN - Flips the image texture horizontally. - Default is `false` @@ -2603,7 +2746,7 @@ Properties: - `sourceSystemName` - The source short system name of the game. For regular systems this value will be identical to `systemName` but for collections it will show the actual system that the game is located in instead of the collection system name. - `sourceSystemFullname` - The source full system name of the game. For regular systems this value will be identical to `systemFullname` but for collections it will show the actual system that the game is located in instead of the collection system name. * `defaultValue` - type: STRING - - This property makes it possible to override the default "unknown" text that is displayed if `metadata` has been set to `developer`, `publisher`, `genre` or `players` and there is no metadata available for the defined type. Any string can be used but you can't set it to a blank value. If you don't want to display anything when there is no metadata available, then set this property to `:space:` in which case a blankspace will be used. This property has no effect on the metadata editor where "unknown" will still be shown for blank values. + - This property makes it possible to override the default "unknown" text that is displayed if `metadata` has been set to `developer`, `publisher`, `genre` or `players` and there is no metadata available for the defined type. Any string can be used but you can't set it to a blank value. If you don't want to display anything when there is no metadata available, then set this property to `:space:` in which case a blankspace will be used. This property has no effect on the metadata editor where "unknown" will still be shown for blank values. A secondary use for this property is to set a default value if `metadata` has been set to `systemName`, `systemFullname`, `sourceSystemName` or `sourceSystemFullname` in which case the value will be used if the metadata value is blank. This is useful for defining a specific string at the root of the custom collections system. * `systemNameSuffix` - type: BOOLEAN - Whether to add the system name in square brackets after the game name when inside a collection system (automatic as well as custom collections). If `metadata` has been set to `description` then this property will only apply when inside the root of the grouped custom collections system where a summary of available games for the currently selected collection is displayed. - Default is `true` @@ -2884,6 +3027,9 @@ Properties: - `always` - Set element as stationary during all transitions. - `never` - Don't set element as stationary during any transitions. - Default is `never` +* `hideIfZero` - type: BOOLEAN + - If set to true then the element will not get rendered if the rating value is zero. + - Default is `false` * `gameselector` - type: STRING - If more than one gameselector element has been defined, this property makes it possible to state which one to use. If multiple gameselector elements have been defined and this property is missing then the first entry will be chosen and a warning message will be logged. If only a single gameselector has been defined, this property is ignored. The value of this property must match the `name` attribute value of the gameselector element. This property is only needed for the `system` view. * `gameselectorEntry` - type: UNSIGNED_INTEGER @@ -2946,7 +3092,7 @@ Properties: #### helpsystem -The helpsystem is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Note that this element does not have a zIndex value, instead it's always rendered on top of all other elements. +The helpsystem is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Note that this element does not have a zIndex value, instead it's always rendered on top of all other elements. It also has to have its name attribute set to `help` or the configuration will not get loaded. It's possible to set this element as right-aligned or center-aligned using a combination of the `pos` and `origin` properties. For example `1 1` and `1 1` will place it in the lower right corner of the screen. diff --git a/THEMES.md b/THEMES.md index b503af69a..28dea259d 100644 --- a/THEMES.md +++ b/THEMES.md @@ -1,6 +1,6 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 - Themes +# ES-DE (EmulationStation Desktop Edition) v3.0 - Themes -If creating themes specifically for ES-DE, please add `-es-de` to the repository/directory name, as in `slate-es-de`. Themes made for ES-DE are not compatible with any other EmulationStation forks (and vice versa) and the -es-de extension makes it clear that it's an ES-DE theme. The actual theme name as defined using the `themeName` tag in capabilities.xml does of course not need to include the `-es-de` extension as that's the actual theme name that will be displayed when selecting themes from the _UI Settings_ menu. For example slate-es-de will be listed simply as _Slate_ in this menu. +If creating themes for ES-DE, please add `-es-de` to the repository/directory name to clearly indicate that it's a theme for this frontend. Two examples would be `linear-es-de` and `modern-es-de`. The actual theme name as defined using the `themeName` tag in capabilities.xml does of course not need to include the `-es-de` extension as that's the actual theme name that will be displayed when selecting themes from the _UI Settings_ menu. For example linear-es-de will be listed simply as _Linear_ in this menu. Before your start, make sure to download the _Theme engine examples_ theme that contains a number of example variants for things like vertical and horizontal carousels, wheel carousels, system view text lists, grids etc: @@ -16,7 +16,7 @@ https://github.com/lilbud/es-de-theme-stuff To test whether your theme includes support for all ES-DE systems, download one of the following archives which contain ROM directory trees fully populated with dummy files: -[ROMs_ALL_Unix.zip](tools/system-dirs-dummy-files/ROMs_ALL_Unix.zip)\ +[ROMs_ALL_Linux.zip](tools/system-dirs-dummy-files/ROMs_ALL_Linux.zip)\ [ROMs_ALL_macOS.zip](tools/system-dirs-dummy-files/ROMs_ALL_macOS.zip)\ [ROMs_ALL_Windows.zip](tools/system-dirs-dummy-files/ROMs_ALL_Windows.zip) @@ -156,17 +156,19 @@ Note that the legacy theme engine had quite inaccurate text sizing and font rend * The defined line spacing was not always applied for automatically sized text elements * Font sizes were rounded to integers, leading to imprecise text sizing across different resolutions (the rounding was also done incorrectly) -## System metadata and logo repositories +## Theme assets repositories -There are two useful repositories hosted by the ES-DE project that provide system metadata and system logotypes. This greatly simplifies the work of adding support for all systems that ES-DE supports. +There are several useful repositories hosted by the ES-DE project that provide system metadata and system graphics files. Using these greatly simplifies the work of adding support for all ES-DE systems to your theme. -**Metadata** +Make sure to regularly check for updates in these repositories as corrections, improvements and additions of new systems are made continuously. + +### Metadata The metadata repository provides descriptions, release dates, per-system color palettes etc. and it can be found here: https://gitlab.com/es-de/themes/system-metadata -By adding this to your theme, either via manually downloading and including it, or by adding it as a Git subtree, you'll be able to access its defined variables. Make sure to regularly check for updates as corrections and additions of new systems are done continuously. Also check the README.md file in the repository for more details on how to actually use the variables. +By adding this to your theme, either via manually downloading and including it, or by adding it as a Git subtree, you'll be able to access its defined variables. Check the README.md file in the repository for details on how to actually use the variables. Here's how to add this repository as a subtree inside your theme's Git repository: ``` @@ -181,9 +183,47 @@ git subtree pull --prefix=system-metadata --squash system-metadata master The directory name can be changed to whatever you like using the --prefix flag. -**Logos** +### Controller outline graphics -Likewise there's a repository of system logotypes that can also be added and used in the same fashion as the metadata. It can be found here: +This repository provides controller graphics files for each system in an outline style and it can be found here: + +https://gitlab.com/es-de/themes/system-controllers-outline + +Here's how to add this repository as a subtree inside your theme's Git repository: +``` +git remote add system-controllers-outline https://gitlab.com/es-de/themes/system-controllers-outline.git +git subtree add --prefix=system-controllers-outline --squash system-controllers-outline master +``` + +To later pull in repository updates you'll run the following: +``` +git subtree pull --prefix=system-controllers-outline --squash system-controllers-outline master +``` + +The directory name can be changed to whatever you like using the --prefix flag. + +### Mini system graphics + +This repository provides graphics files for each system in a "mini" style and it can be found here: + +https://gitlab.com/es-de/themes/system-graphics-mini + +Here's how to add this repository as a subtree inside your theme's Git repository: +``` +git remote add system-graphics-mini https://gitlab.com/es-de/themes/system-graphics-mini.git +git subtree add --prefix=system-graphics-mini --squash system-graphics-mini master +``` + +To later pull in repository updates you'll run the following: +``` +git subtree pull --prefix=system-graphics-mini --squash system-graphics-mini master +``` + +The directory name can be changed to whatever you like using the --prefix flag. + +### Logos + +This repository provides logos for each system in color and white (the latter for use with color shifting) and it can be found here: https://gitlab.com/es-de/themes/system-logos @@ -200,11 +240,13 @@ git subtree pull --prefix=system-logos --squash system-logos master The directory name can be changed to whatever you like using the --prefix flag. -**Adding remotes** +### Adding remotes -Note that the remotes are only setup for your local repository, so if you clone a theme you'll need to manually add the system-metadata and/or system-logos remotes to be able to pull to these subtrees. That means you'll need to run the following commands on a freshly cloned theme repository: +Note that the remotes are only setup for your local repository, so if you clone a theme you'll need to manually add the repository remotes to be able to pull from these subtrees. That means you'll need to run one or more of the following commands on a freshly cloned theme repository: ``` git remote add system-metadata https://gitlab.com/es-de/themes/system-metadata.git +git remote add system-controllers-outline https://gitlab.com/es-de/themes/system-controllers-outline.git +git remote add system-graphics-mini https://gitlab.com/es-de/themes/system-graphics-mini.git git remote add system-logos https://gitlab.com/es-de/themes/system-logos.git ``` After doing this you'll be able to pull repository updates as described above. @@ -609,6 +651,95 @@ Here's an example configuration: ``` +## Font sizes + +The optional font sizes functionality makes it possible to use a set of predefined size options and connect these to theme variables that can be used to apply different text sizes and related design changes. The font sizes declared for the theme can be selected via the _Theme font size_ setting in the _UI Settings_ menu. + +To understand the basics on how to use variables, make sure to read the _Theme variables_ section elsewhere in this document. + +To use the font size entries you first need to declare them using `` tag pairs in the `capabilities.xml` file. The following sizes are available: + +| capabilities.xml name | UI Settings label | +| :-------------------- | :--------------- | +| medium | medium | +| large | large | +| small | small | +| x-large | extra large | +| x-small | extra small | + +The options will always be listed in the above order in the _UI Settings_ menu. + +Here's an example of a theme that implements three of these sizes: + +```xml + + + My theme + + medium + small + x-small + +``` + +In the theme configuration you'll also use a `` tag pair combined with a `` tag pair to define the variables you want to apply per font size. + +These `` tag pairs can be placed directly inside the `` tags, inside the `` tags or inside the `` tags. + +The mandatory name attribute is used to specificy which font size to use, and multiple values can be specified at the same time by separating them by commas or by whitespace characters (tabs, spaces or line breaks). + +Here's an example configuration: + +```xml + + + + 0.025 + 0.5 0.6437 + 0.022 + 0.016 + + + + + 0.015 + 0.45 0.6437 + 0.013 + + + + + 0.008 + 0.4 0.6437 + 0.006 + + + + 0.011 + + + + + + ${gameCounterPos} + 1 0.056 + ${gameCounterFontSize} + + + + 0.2 0.3412 + 0.2 0.040 + ${gameNameFontSize} + + + 0.33 0.3412 + 0.18 0.040 + ${publisherFontSize} + + + +``` + ## Aspect ratios The aspect ratio support works almost identically to the variants and color schemes with the main difference that the available aspect ratios are hardcoded into ES-DE. The theme can still decide which of the aspect ratios to support (or none at all in which case the theme aspect ratio is left undefined) but it can't create entirely new aspect ratio entries. @@ -834,15 +965,18 @@ The variant, color scheme and transitions names as well as their labels can be s Unlike the types just mentioned, aspectRatio entries can not be set to arbitrary values, instead they have to use a value from the _horizontal name_ or _vertical name_ columns in the following table: -| Horizontal name | Vertical name | Common resolutions | -| :--------------- | :------------- | :--------------------------------------------- | -| 16:9 | 16:9_vertical | 1280x720, 1920x1080, 2560x1440, 3840x2160 | -| 16:10 | 16:10_vertical | 1280x800, 1440x900, 1920x1200 | -| 3:2 | 3:2_vertical | 2160x1440 | -| 4:3 | 4:3_vertical | 320x240, 640x480, 800x600, 1024x768, 1600x1200 | -| 5:4 | 5:4_vertical | 1280x1024 | -| 21:9 | 21:9_vertical | 2560x1080, 3840x1600, 5120x2160 | -| 32:9 | 32:9_vertical | 3840x1080, 5120x1440 | +| Horizontal name | Vertical name | Common resolutions | +| :--------------- | :-------------- | :--------------------------------------------- | +| 16:9 | 16:9_vertical | 1280x720, 1920x1080, 2560x1440, 3840x2160 | +| 16:10 | 16:10_vertical | 1280x800, 1440x900, 1920x1200 | +| 3:2 | 3:2_vertical | 2160x1440 | +| 4:3 | 4:3_vertical | 320x240, 640x480, 800x600, 1024x768, 1600x1200 | +| 5:4 | 5:4_vertical | 1280x1024 | +| 19.5:9 | 19.5:9_vertical | 2340x1080, 2532x1170 | +| 20:9 | 20:9_vertical | 2400x1080, 1600x720 | +| 21:9 | 21:9_vertical | 2560x1080, 3840x1600, 5120x2160 | +| 32:9 | 32:9_vertical | 3840x1080, 5120x1440 | +| 1:1 | 1:1 | Any square resolution | The 21:9 and 32:9 aspect ratios are approximate as monitors of slightly different ratios are collectively marketed using these numbers. @@ -1285,10 +1419,11 @@ It's important to understand how the theme configuration files are parsed in ord 1) Transitions 2) Variables 3) Color schemes -4) Included files -5) "General" (non-variant) configuration -6) Variants -7) Aspect ratios +4) Font sizes +5) Included files +6) "General" (non-variant) configuration +7) Variants +8) Aspect ratios When including a file using the `` tag (i.e. step 4 above) then all steps listed above are executed for that included file prior to continuing to the next line after the `` tag. @@ -1297,7 +1432,7 @@ For any given step, the configuration is parsed in the exact order that it's def ## Property data types * NORMALIZED_PAIR - two decimal values delimited by a space, for example `0.25 0.5` -* PATH - path to a resource. If the first character is a tilde (`~`) then it will be expanded to the user's home directory (`$HOME` for Unix and macOS and `%HOMEPATH%` for Windows) unless overridden using the --home command line option. If the first character is a dot (`.`) then the resource will be searched for relative to the location of the theme file, for example `./myfont.ttf` or `./../core/fonts/myfont.ttf` +* PATH - path to a resource. If the first character is a tilde (`~`) then it will be expanded to the user's home directory (`$HOME` for Linux, BSD Unix and macOS and `%HOMEPATH%` for Windows) unless overridden using the --home command line option. If the first character is a dot (`.`) then the resource will be searched for relative to the location of the theme file, for example `./myfont.ttf` or `./../core/fonts/myfont.ttf` * BOOLEAN - `true`/`1` or `false`/`0` * COLOR - a hexadecimal RGB or RGBA color value consisting of 6 or 8 digits. If a 6 digit value is used then the alpha channel will be set to `FF` (completely opaque) * UNSIGNED_INTEGER - an unsigned integer value @@ -1870,6 +2005,10 @@ Properties: - Where on the element `pos` refers to. For example, an origin of `0.5 0.5` and a `pos` of `0.5 0.5` would place the textlist exactly in the middle of the screen. If the position and size attributes are themeable, origin is implied. - Minimum value per axis is `0` and maximum value per axis is `1` - Default is `0 0` +* `selectorWidth` - type: FLOAT + - Width of the selector bar. If an image has been defined using `selectorImagePath` then setting this property to zero will retain the aspect ratio for that image. + - Minimum value is `0` and maximum value is `1` + - Default is the equivalent value as the width of the overall element. * `selectorHeight` - type: FLOAT - Height of the selector bar. This is expanded downwards so you'll probably want to adjust its position using `selectorVerticalOffset` if making use of this property. - Minimum value is `0` and maximum value is `1` @@ -2031,6 +2170,10 @@ Properties: - `always` - Set element as stationary during all transitions. - `never` - Don't set element as stationary during any transitions. - Default is `never` +* `renderDuringTransitions` - type: BOOLEAN + - This special property which is only usable for slide transitions between the system and gamelist views makes it possible to for example have a background image stay seamlessly in place when transitioning, or being able to use semi-transparent stationary elements without having them render on top of each other during transitions. For this to work correctly only define `stationary` for one view and set `renderDuringTransitions` to false for the corresponding element in the other view. This way the element from the former view will keep rendering until the slide animation has been completed, after which the latter view will "take over" by rendering the element normally. + - This property can only be used if slide transitions are used, and only when moving from the system view to the gamelist view, or vice versa. + - Default is `true` * `flipHorizontal` - type: BOOLEAN - Flips the image texture horizontally. - Default is `false` @@ -2601,7 +2744,7 @@ Properties: - `sourceSystemName` - The source short system name of the game. For regular systems this value will be identical to `systemName` but for collections it will show the actual system that the game is located in instead of the collection system name. - `sourceSystemFullname` - The source full system name of the game. For regular systems this value will be identical to `systemFullname` but for collections it will show the actual system that the game is located in instead of the collection system name. * `defaultValue` - type: STRING - - This property makes it possible to override the default "unknown" text that is displayed if `metadata` has been set to `developer`, `publisher`, `genre` or `players` and there is no metadata available for the defined type. Any string can be used but you can't set it to a blank value. If you don't want to display anything when there is no metadata available, then set this property to `:space:` in which case a blankspace will be used. This property has no effect on the metadata editor where "unknown" will still be shown for blank values. + - This property makes it possible to override the default "unknown" text that is displayed if `metadata` has been set to `developer`, `publisher`, `genre` or `players` and there is no metadata available for the defined type. Any string can be used but you can't set it to a blank value. If you don't want to display anything when there is no metadata available, then set this property to `:space:` in which case a blankspace will be used. This property has no effect on the metadata editor where "unknown" will still be shown for blank values. A secondary use for this property is to set a default value if `metadata` has been set to `systemName`, `systemFullname`, `sourceSystemName` or `sourceSystemFullname` in which case the value will be used if the metadata value is blank. This is useful for defining a specific string at the root of the custom collections system. * `systemNameSuffix` - type: BOOLEAN - Whether to add the system name in square brackets after the game name when inside a collection system (automatic as well as custom collections). If `metadata` has been set to `description` then this property will only apply when inside the root of the grouped custom collections system where a summary of available games for the currently selected collection is displayed. - Default is `true` @@ -2882,6 +3025,9 @@ Properties: - `always` - Set element as stationary during all transitions. - `never` - Don't set element as stationary during any transitions. - Default is `never` +* `hideIfZero` - type: BOOLEAN + - If set to true then the element will not get rendered if the rating value is zero. + - Default is `false` * `gameselector` - type: STRING - If more than one gameselector element has been defined, this property makes it possible to state which one to use. If multiple gameselector elements have been defined and this property is missing then the first entry will be chosen and a warning message will be logged. If only a single gameselector has been defined, this property is ignored. The value of this property must match the `name` attribute value of the gameselector element. This property is only needed for the `system` view. * `gameselectorEntry` - type: UNSIGNED_INTEGER @@ -2944,7 +3090,7 @@ Properties: #### helpsystem -The helpsystem is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Note that this element does not have a zIndex value, instead it's always rendered on top of all other elements. +The helpsystem is a special element that displays a context-sensitive list of actions the user can take at any time. You should try and keep the position constant throughout every screen. Note that this element does not have a zIndex value, instead it's always rendered on top of all other elements. It also has to have its name attribute set to `help` or the configuration will not get loaded. It's possible to set this element as right-aligned or center-aligned using a combination of the `pos` and `origin` properties. For example `1 1` and `1 1` will place it in the lower right corner of the screen. diff --git a/USERGUIDE-DEV.md b/USERGUIDE-DEV.md index 4c40abd59..18a62fe3f 100644 --- a/USERGUIDE-DEV.md +++ b/USERGUIDE-DEV.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 (development version) - User guide +# ES-DE (EmulationStation Desktop Edition) v3.0 (development version) - User guide This version of the user guide is only relevant for the current ES-DE development version, if you are using the latest stable release, refer to [USERGUIDE.md](USERGUIDE.md) instead. @@ -38,12 +38,12 @@ The installation procedure is just covered briefly here and may differ a bit for The AppImage release should be usable on most modern x86 64-bit Linux distributions. After download you may have to set the file as executable, such as this: ``` -chmod +x EmulationStation-DE-x64.AppImage +chmod +x ES-DE_x64.AppImage ``` Or if you're using the Steam Deck AppImage: ``` -chmod +x EmulationStation-DE-x64_SteamDeck.AppImage +chmod +x ES-DE_x64_SteamDeck.AppImage ``` To run AppImage files you need libfuse2 installed, but some newer distributions like Ubuntu 22.04 LTS no longer ship with this library preinstalled. You can however easily install it like this: @@ -59,11 +59,11 @@ There's not really much to say about these operating systems, just install ES-DE **On first application startup** -Upon first startup, ES-DE will create its `~/.emulationstation` home directory. +Upon first startup, ES-DE will create its `~/ES-DE` application data directory. -On Unix this means `/home//.emulationstation`, on macOS `/Users//.emulationstation` and on Windows `C:\Users\\.emulationstation` or `EmulationStation-DE\.emulationstation` depending on whether the installer release or the portable release is used. +On Linux this means `/home//ES-DE`, on macOS `/Users//ES-DE` and on Windows `C:\Users\\ES-DE` or `ES-DE\ES-DE` depending on whether the installer release or the portable release is used. -Also on first startup the configuration file `es_settings.xml` will be generated in the ES-DE home directory, containing all the application settings at their default values. Following this, a file named `es_systems.xml` will be loaded from the resources directory (which is part of the ES-DE installation). This file contains the game system definitions including which emulator to use per platform. For many systems there are also alternative emulators defined which can be applied system-wide or per game. How that works is explained later in this guide. A customized systems configuration file can also be used, as described in the next section below. +Also on first startup the configuration file `es_settings.xml` will be generated in the `ES-DE/settings` directory, containing all the application settings at their default values. Following this, a file named `es_systems.xml` will be loaded from the resources directory (which is part of the ES-DE installation). This file contains the game system definitions including which emulator to use per platform. For many systems there are also alternative emulators defined which can be applied system-wide or per game. How that works is explained later in this guide. A customized systems configuration file can also be used, as described in the next section below. In addition to es_systems.xml there's an `es_find_rules.xml` file that gets loaded as well and which contains rules on how to locate the emulators, i.e. how to find out where they've been installed. @@ -71,7 +71,7 @@ There's an application log file created in the ES-DE home directory named `es_lo After ES-DE finds at least one game file, it will populate that game system and the application will start. If there are no game files, a dialog will be shown explaining that you need to install your game files into your ROM directory. You will also be given a choice to change that ROM directory path if you don't want to use the default one. As well you have the option to generate the complete game systems directory structure based on information in es_systems.xml. -When generating the directory structure, a file named systeminfo.txt will be created in each game system folder which will provide you with some information about the system. Here's an example for the _dos_ system as seen on Unix: +When generating the directory structure, a file named systeminfo.txt will be created in each game system folder which will provide you with some information about the system. Here's an example for the _dos_ system as seen on Linux: ``` System name: dos @@ -113,18 +113,18 @@ epic: Epic Games Store famicom: Nintendo Family Computer ``` -If a custom es_systems.xml file is present in ~/.emulationstation/custom_systems/ any entries from this file will have their names trailed by the text _(custom system)_. So if the _dos_ system in the example above would be present in the custom systems configuration file, the system would be shown as _dos (custom system)_ instead of simply _dos_. This is only applicable for the systems.txt and systeminfo.txt files, the trailing text is not applied or used anywhere else in the application. +If a custom es_systems.xml file is present in ~/ES-DE/custom_systems/ any entries from this file will have their names trailed by the text _(custom system)_. So if the _dos_ system in the example above would be present in the custom systems configuration file, the system would be shown as _dos (custom system)_ instead of simply _dos_. This is only applicable for the systems.txt and systeminfo.txt files, the trailing text is not applied or used anywhere else in the application. ![alt text](images/es-de_ui_easy_setup.png "ES-DE Easy Setup") _This is the dialog shown if no game files were found. It lets you configure the ROM directory if you don't want to use the default one, and you can also generate the game systems directory structure. Note that the directory is the physical path, and that your operating system may present this as a localized path if you are using a language other than English._ ## Upgrading to a newer release -**Note:** Before upgrading ES-DE, make sure that you have not made any system customizations anywhere in the installation directory structure as these files will be overwritten during the upgrade process. All customizations should go into ~/.emulationstation/custom_systems/ as described elsewhere in this guide. None of the upgrade methods mentioned below will ever touch any files inside your .emulationstation directory tree. +**Note:** Before upgrading ES-DE, make sure that you have not made any system customizations anywhere in the installation directory structure as these files will be overwritten during the upgrade process. All customizations should go into ~/ES-DE/custom_systems/ as described elsewhere in this guide. None of the upgrade methods mentioned below will ever touch any files inside your ES-DE directory tree. -There is a built-in application updater that can automatically update the Linux AppImage releases, and as of ES-DE 2.2.0 there is also support for downloading the Windows and macOS packages. Just be aware that these will still need to be manually installed. Using the application updater is straightforward, just follow the on-screen instructions. For the AppImage releases the old file is retained by renaming it, adding its version to the filename followed by the .OLD extension, for example `EmulationStation-DE-x64_SteamDeck.AppImage_2.1.0.OLD` +There is a built-in application updater that can automatically update the Linux AppImage releases, and as of ES-DE 2.2.0 there is also support for downloading the Windows and macOS packages. Just be aware that these will still need to be manually installed. Using the application updater is straightforward, just follow the on-screen instructions. For the AppImage releases the old file is retained by renaming it, adding its version to the filename followed by the .OLD extension, for example `ES-DE_x64_SteamDeck.AppImage_3.0.0.OLD` -Note that the updater will keep whatever filename you had for your running AppImage file, which could potentially be confusing if you for example added version information to the filename. It's always recommend to keep the default AppImage filenames, i.e. `EmulationStation-DE-x64.AppImage` and `EmulationStation-DE-x64_SteamDeck.AppImage` +Note that the updater will keep whatever filename you had for your running AppImage file, which could potentially be confusing if you for example added version information to the filename. It's always recommend to keep the default AppImage filenames, i.e. `ES-DE_x64.AppImage` and `ES-DE_x64_SteamDeck.AppImage` On Windows and macOS you can specify to which directory you want to save the downloaded file. The default is `C:\Users\myusername\Downloads` on Windows and `/Users/myusername/Downloads` on macOS. @@ -145,7 +145,7 @@ AUR upgrades should be automatically handled via your package manager and it sho **macOS** -Open _Applications_ in Finder and right click on _EmulationStation Desktop Edition_ and choose _Move to Trash_. Then simply install the new release using the .dmg drag-and-drop installer. +Open _Applications_ in Finder and right click on _ES-DE_ and choose _Move to Trash_. Then simply install the new release using the .dmg drag-and-drop installer. **Windows installer** @@ -166,7 +166,7 @@ In theory it's possible to make a custom system entry and hardcode the path to a If you really insist on not placing your games into the ES-DE standard directory structure, a much better solution is to symlink the game directories into the standard directory. In this way you don't need to make a custom es_systems.xml file and any additional emulators and other configuration added to future ES-DE releases will just work after upgrading. -This is an example of symlinking the Super Nintendo game directory on Unix and macOS: +This is an example of symlinking the Super Nintendo game directory on Linux and macOS: ``` cd ~/ROMs ln -s ~/my_games/super_nintendo/ snes @@ -191,7 +191,7 @@ Note that if the setting _Only show games from gamelist.xml files_ has been enab ## Placing games and other resources on network shares -Although ES-DE does support placing game ROMs, the `.emulationstation` home directory and the `downloaded_media` directory on network shares, this can lead to serious performance problems in some instances. Especially problematic is the Microsoft SMB protocol as it offers abysmal performance for some disk operations on which ES-DE relies heavily. For small game libraries this can still be acceptable, but for libraries with hundreds or thousands of games the application startup time and overall usage will be very painful or even unusable. Similar issues could occur when using file hosting services like Google Drive. +Although ES-DE does support placing game ROMs, the `ES-DE` application data directory and the `downloaded_media` directory on network shares, this can lead to serious performance problems in some instances. Especially problematic is the Microsoft SMB protocol as it offers abysmal performance for some disk operations on which ES-DE relies heavily. For small game libraries this can still be acceptable, but for libraries with hundreds or thousands of games the application startup time and overall usage will be very painful or even unusable. Similar issues could occur when using file hosting services like Google Drive. A general recommendation is to place all game files and other data on drives connected directly to the machine where ES-DE is running. Even using low speed technology like USB thumb drives, SD cards etc. is generally fine and leads to acceptable performance in most instances. @@ -233,7 +233,7 @@ In order for ES-DE to run, graphics drivers with OpenGL support have to be insta On some GPUs with buggy drivers, ES-DE may only display a black screen on startup or when launching a game. The problem can be worked around by specifying a window size for ES-DE that is a single pixel wider than the actual screen resolution. So for example for a 1280x800 display, the resolution can be set to 1281x800 and then rendering should work correctly. This is applied using the --resolution command line option, for example: ``` -EmulationStation.exe --resolution 1281 800 +ES-DE.exe --resolution 1281 800 ``` Some computers using Intel Iris Xe GPUs refuse to start ES-DE or display excessive graphics corruption. These problems are seemingly caused by driver bugs and do not occur when using Linux with the same hardware. There is no known solution or workaround to this issue other than switching to Linux or waiting for Intel to resolve the problem with a driver update. @@ -254,6 +254,8 @@ If you want to create your own portable intallation from scratch or customize th A number of systems have alternative emulator entries named _Shortcut or script_ which allows the direct execution of .lnk shortcut files or .bat batch files. It's not possible by default to directly launch .ps1 PowerShell scripts. As running PowerShell scripts is not even enabled by default on Windows they are for sure not recommended. If you still want to use them the best approach is to execute them via either a .lnk shortcut file or a .bat wrapper script where you explicitly call powershell.exe with the -command flag. If you instead insist on running them directly from ES-DE, you'll need to add a custom system or find rule configuration where you execute powershell.exe instead of cmd.exe and you'll also need to add .ps1 as a file extension for each relevant system. +Some disk operations can have abysmal performance on Windows, and this may be especially obvious for the theme downloader. This is often caused by anti-virus software like Microsoft Defender. If it takes say 30 seconds rather than 300 milliseconds to open the theme downloader then it may be a good idea to add an exlusion for the ES-DE\themes\ directory to Microsoft Defender. The same may also be true for other directories like the ROMs folder if disk performance is terrible. Refer to your anti-virus software documentation on how to setup such exclusions. + ## Specific notes for macOS As macOS does not support Vulkan some emulators are not available, and some that do exist have not been updated for this operating system in recent years. But emulator support is steadily improving and native ARM releases ("Apple Silicon") are also getting more common. One issue though is that some emulators are not codesigned and notarized so macOS refuses to run them by default. You can override the operating system's security settings however, which will work around this problem. Some emulators are also available via the [Homebrew](https://brew.sh) package manager and in many instances ES-DE includes support for these releases using the bundled configuration. @@ -268,13 +270,11 @@ At the time of writing there is an additional issue with the ARM release of Retr The first time you launch a RetroArch-emulated game from within ES-DE the operating system will present you with a security option with the following description: -`"EmulationStation Desktop Edition" would like to access files in your Documents folder.` +`"ES-DE" would like to access files in your Documents folder.` If you don't allow this, you will not be able to place system BIOS ROMs in the RetroArch default system directory `~/Documents/RetroArch/system` even if you've already given RetroArch access to this folder. This is so because RetroArch runs as a subprocess to ES-DE and therefore inherits the security settings from the parent application. Attempting to launch a game without enabling the access will simply display an error message in the emulator that the BIOS files are missing. This of course only applies to emulators that require BIOS ROMs, all other games should work fine regardless of this security setting. -If you accidentally refused ES-DE the folder access, you can fix this by opening _System Settings_, selecting _Privacy & Security_ and within the GUI choose _Files and Folders_. The option you need to enable is _Documents Folder_ under _EmulationStation Desktop Edition_. - -By default files and directories starting with a dot are hidden on macOS, so to show the .emulationstation directory in your home directory you need to enable hidden files in Finder. You do this using the keyboard combination Shift + Command + . (dot). +If you accidentally refused ES-DE the folder access, you can fix this by opening _System Settings_, selecting _Privacy & Security_ and within the GUI choose _Files and Folders_. The option you need to enable is _Documents Folder_ under _ES-DE_. A minor annoyance is that macOS creates metadata files starting with ._ in the filename when placing game/ROM files on some filesystem types such as exFAT. This means that you will see double entries inside ES-DE for all such games. To hide these extra files, the option _Show hidden files and folders (requires restart)_ in the _Other settings_ menu can be set to disabled. @@ -288,12 +288,16 @@ It's also possible to install ES-DE using [EmuDeck](https://www.emudeck.com) whi Unless RetroDECK is used, Flatpak releases of some emulators may need some extra permissions to be able to launch games placed on external devices such as a memory card. This is the case for instance for melonDS and RPCS3. The easiest way to do this is by using [Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal). The option you need to enable is generally _All system files_ in the _Filesystem_ section. If using EmuDeck some of these settings will be applied automatically via their installer. -If you are unfamiliar with Unix operating systems, make sure to at least read up on the concepts of _dotfiles_ (hidden files and directories), _home directories_ (including use of the tilde ~ character) and _symbolic links_ (symlinks): +If you are unfamiliar with Linux/Unix operating systems, make sure to at least read up on the concepts of _dotfiles_ (hidden files and directories), _home directories_ (including use of the tilde ~ character) and _symbolic links_ (symlinks): [https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory#Unix_and_Unix-like_environments](https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory#Unix_and_Unix-like_environments) \ [https://en.wikipedia.org/wiki/Home_directory#Unix](https://en.wikipedia.org/wiki/Home_directory#Unix) \ [https://en.wikipedia.org/wiki/Symbolic_link](https://en.wikipedia.org/wiki/Symbolic_link) +## Specific notes for Android + +The Android port of ES-DE is quite different than the other versions, so it has its specifics covered by a dedicated [ANDROID.md](ANDROID.md) document. + ## Specific notes for Raspberry Pi ES-DE on the Raspberry Pi requires a desktop environment, or more specifically a window manager and a sound server (like PulseAudio or PipeWire). There are no plans to add support for direct hardware access to the framebuffer or to ALSA. If you want to use your Raspberry Pi as an appliance, take a look at [RetroPie](https://retropie.org.uk), [Recalbox](https://www.recalbox.com) or [Batocera](https://batocera.org) instead. @@ -308,9 +312,9 @@ In general, 720p works fine with the RPi 4, and 1080p is tolerable but not reall The game systems configuration file `es_systems.xml` is located in the ES-DE resources directory which is part of the application installation. As such this file is not intended to be modified directly. If system customizations are required, a separate es_systems.xml file should instead be placed in the `custom_systems` folder in the ES-DE home directory. -On Unix this means `/home//.emulationstation/custom_systems/es_systems.xml`, on macOS `/Users//.emulationstation/custom_systems/es_systems.xml` and on Windows `C:\Users\\.emulationstation\custom_systems\es_systems.xml` or `EmulationStation-DE\.emulationstation\custom_systems\es_systems.xml` depending on whether the installer release or the portable release is used. +On Linux this means `/home//ES-DE/custom_systems/es_systems.xml`, on macOS `/Users//ES-DE/custom_systems/es_systems.xml` and on Windows `C:\Users\\ES-DE\custom_systems\es_systems.xml` or `ES-DE\ES-DE\custom_systems\es_systems.xml` depending on whether the installer release or the portable release is used. -If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. You can extract it if you need it as a reference when creating your customized entries, or you can find it [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/systems/unix). +If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. You can extract it if you need it as a reference when creating your customized entries, or you can find it [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/systems/linux). Although it's possible to make a copy of the bundled configuration file, to modify it and then place it in this directory, that is not how the system customization is designed to be used. Instead the intention is that the file in `custom_systems` complements the bundled configuration, meaning only systems that are to be customized should be included. @@ -320,26 +324,13 @@ Instructions on how to customize the es_systems.xml file can be found in [INSTAL In addition to the above it's also possible to customize the find rules via the `es_find_rules.xml` file. The logic is essentially identical to what is described for es_systems.xml, and details regarding this file can be found in [INSTALL-DEV.md](INSTALL-DEV.md#es_find_rulesxml) as well. -## Migrating from other EmulationStation forks +## Migrating from EmulationStation **IMPORTANT!!! IMPORTANT!!! IMPORTANT!!!** -ES-DE is designed to be backward compatible to a certain degree. That is, it should be able to read data from other/previous EmulationStation versions such as the RetroPie and Batocera forks. But the opposite is not true and it's a one-way ticket for your gamelist.xml files and your custom collection files when migrating to ES-DE as they will be modified in ways that previous ES versions will see as data loss. For instance ES-DE does not use tags inside the gamelist.xml files to find game media but instead matches the media to the names of the game/ROM files. So it will not save any such tags back to the gamelist files during updates, effectively disabling the game media if the files are opened in another ES fork. +ES-DE is partially compatible with EmulationStation as both frontends originally shared the same source code. That is, ES-DE should generally be able to read data from EmulationStation. But the opposite is not true and it's a one-way ticket for your gamelist.xml files and your custom collection files when migrating to ES-DE as they will be modified in ways that EmulationStation will see as data loss. For instance ES-DE does not use tags inside the gamelist.xml files to find game media but instead matches the media to the names of the game/ROM files. So it will not save any such tags back to the gamelist files during updates, effectively disabling the game media if the files are opened in EmulationStation. -Due to this, always make backups of at least the following directories before testing ES-DE for the first time: - -``` -~/.emulationstation/gameslists/ -~/.emulationstation/collections/ -``` - -If you have gamelist.xml files in your ROMs directory tree then ES-DE will ignore those by default, so you need to move them to the ~/.emulationstation/gamelists/ tree. - -It's also strongly adviced to not rename an old es_settings.cfg file to es_settings.xml for use in ES-DE as it may cause undefined behavior and crashes. - -If migrating from Batocera, RetroBat or Recalbox, be aware that ES-DE follows the RetroPie naming conventions for most game systems. This means that your game files may not be found unless the folders are renamed accordingly. Such an example is the Sega SG-1000 system which in Batocera, RetroBat and Recalbox has the _sg1000_ system name, but is _sg-1000_ in RetroPie and ES-DE. See the [Supported game systems](USERGUIDE-DEV.md#supported-game-systems) table at the bottom of this guide for the correct system names in ES-DE. - -Another potential issue when migrating from another EmulationStation fork is that the path tag requires a leading ./ in ES-DE while that may not be present in other forks. If you don't see any metadata for your games inside ES-DE, then simply add the ./ characters to each path tag and it should hopefully work. +Another potential issue when migrating gamelist.xml files from EmulationStation is that the path tag requires a leading ./ in ES-DE while that may not be present in files coming from EmulationStation. If you don't see any metadata for your games inside ES-DE, then simply add the ./ characters to each path tag and it should hopefully work. Example of an unreadable path tag: ``` @@ -351,11 +342,16 @@ Example of a correct path tag readable by ES-DE: ./Another World.lha ``` +And if you have gamelist.xml files in your ROMs directory tree then ES-DE will ignore those by default, so you need to move them to the ~/ES-DE/gamelists/ tree. + +If migrating from Batocera, RetroBat or Recalbox, be aware that ES-DE does not always use the same system names as those frontends. This means that your game files may not be found unless the folders are renamed accordingly. Such an example is the Sega SG-1000 system which in Batocera, RetroBat and Recalbox has the _sg1000_ system name, but is _sg-1000_ in ES-DE. See the [Supported game systems](USERGUIDE-DEV.md#supported-game-systems) table at the bottom of this guide for the correct system names in ES-DE. + + ## Removing orphaned data Manually removing game files from the ROMs directory tree instead of deleting them from ES-DE using the metadata editor will make any corresponding scraped media files, gamelist.xml entries and custom collection entries orphaned, i.e. they will refer to non-existent files. Although this is correctly handled by ES-DE and is not causing any serious issues, it does lead to unnecessary disk space usage and it does produce log warnings in es_log.txt on application startup. If a huge amount of game files have been manually removed it can also lead to performance problems. -In order to remove such unnecessary media files and configuration file entries, the _Orphaned data cleanup_ utility in the _Utilities_ menu can be used. This tool should be largely self-explanatory. And although it should generally be safe to use, unforeseen issues can occur so make sure to make backups of at least your `.emulationstation/gamelists` and `.emulationstation/collections` directories before attempting to use this tool. +In order to remove such unnecessary media files and configuration file entries, the _Orphaned data cleanup_ utility in the _Utilities_ menu can be used. This tool should be largely self-explanatory. And although it should generally be safe to use, unforeseen issues can occur so make sure to make backups of at least your `ES-DE/gamelists` and `ES-DE/collections` directories before attempting to use this tool. It's recommended to run this utility with the _Show hidden games_ setting enabled as orphaned gamelist.xml folder entries may otherwise not get purged. @@ -365,17 +361,17 @@ Note that there are no guarantees that any processed gamelist.xml files will be If the utility finds any data to be removed, a backup of the old files will be made. This will end up in a `CLEANUP` directory and will contain a date and time stamp. For example: ``` -~/.emulationstation/gamelists/CLEANUP/2023-07-27_142830/dos/gamelist.xml -~/.emulationstation/gamelists/CLEANUP/2023-07-27_142830/ports/gamelist.xml -~/.emulationstation/collections/CLEANUP/2023-07-27_143216/custom-Action.cfg -~/.emulationstation/collections/CLEANUP/2023-07-27_143216/custom-Fighting.cfg -~/.emulationstation/downloaded_media/CLEANUP/2023-07-27_123406/atari2600/titlescreens/H.E.R.O..png -~/.emulationstation/downloaded_media/CLEANUP/2023-07-27_123406/c64/3dboxes/Minerer 2049.crt.png +~/ES-DE/gamelists/CLEANUP/2023-07-27_142830/dos/gamelist.xml +~/ES-DE/gamelists/CLEANUP/2023-07-27_142830/ports/gamelist.xml +~/ES-DE/collections/CLEANUP/2023-07-27_143216/custom-Action.cfg +~/ES-DE/collections/CLEANUP/2023-07-27_143216/custom-Fighting.cfg +~/ES-DE/downloaded_media/CLEANUP/2023-07-27_123406/atari2600/titlescreens/H.E.R.O..png +~/ES-DE/downloaded_media/CLEANUP/2023-07-27_123406/c64/3dboxes/Minerer 2049.crt.png ``` This means that you will need to manually delete these backup directories to free up disk space when you are certain that you no longer need the data. -All files and entries that are removed are logged to `~/.emulationstation/es_log.txt` so it could be a good idea to make a backup copy of this file after running the cleanup, for future reference. +All files and entries that are removed are logged to `~/ES-DE/logs/es_log.txt` so it could be a good idea to make a backup copy of this file after running the cleanup, for future reference. Any media directories that are empty after the cleanup will also be removed by this utility. @@ -388,7 +384,7 @@ _The Orphaned data cleanup utility after successfully removing some gamelist.xml ES-DE fully supports high resolution displays such as 1440p, 4K, 6K, 8K, ultrawide monitors etc. But many emulators (e.g. RetroArch) will also run using the same resolution which may cause performance problems on slower machines or when using resource intensive shaders. Although some emulator cores will have options to set their internal resolution, they still need to be scaled up to the screen resolution. -A solution to this is to use the custom event scripts functionality to set a temporary resolution upon launching a game that will be reverted when returning to ES-DE. Such a setup is detailed in [INSTALL-DEV.md](INSTALL-DEV.md#custom-event-scripts) for Unix, but should hopefully be possible to implement similarly on Windows. When going for this setup it's important that the setting _Run in background (while game is launched)_ is disabled or ES-DE may not be able to correctly switch to the emulator window when launching games. +A solution to this is to use the custom event scripts functionality to set a temporary resolution upon launching a game that will be reverted when returning to ES-DE. Such a setup is detailed in [INSTALL-DEV.md](INSTALL-DEV.md#custom-event-scripts) for Linux, but should hopefully be possible to implement similarly on Windows. When going for this setup it's important that the setting _Run in background (while game is launched)_ is disabled or ES-DE may not be able to correctly switch to the emulator window when launching games. On macOS it's problematic to change screen resolutions on the fly or on a per-application basis as Apple has seemingly disabled most of this functionality in recent operating system releases. The only real option here is to lower the display resolution prior to launching ES-DE. @@ -402,22 +398,22 @@ Below are some examples. For consistency it's assumed that the display resolutio Running at a lower application resolution in a window: ``` -emulationstation --resolution 1280 720 +es-de --resolution 1280 720 ``` Running at a lower application resolution in padded fullscreen mode: ``` -emulationstation --resolution 1824 1026 --fullscreen-padding 1 +es-de --resolution 1824 1026 --fullscreen-padding 1 ``` Same as above but also offsetting the screen slightly to the left and downwards: ``` -emulationstation --resolution 1824 1026 --fullscreen-padding 1 --screenoffset -40 22 +es-de --resolution 1824 1026 --fullscreen-padding 1 --screenoffset -40 22 ``` Rotate application screen contents 90 degrees while running at the native 1920x1080 screen resolution: ``` -emulationstation --screenrotate 90 +es-de --screenrotate 90 ``` ## Input device configuration @@ -430,7 +426,7 @@ The actual procedure to map the inputs should be self-explanatory, just follow t Any custom configuration is applied per unique device ID (GUID). So if two identical controllers are used with ES-DE, both will have the same configuration applied. If connecting controllers of the same type but of different revisions, the GUID may differ and therefore the custom configuration would need to be applied to each device individually. -If you have issues with your input configuration, as a last resort you can reset all mappings by deleting or renaming the file `~/.emulationstation/es_input.xml` +If you have issues with your input configuration, as a last resort you can reset all mappings by deleting or renaming the file `~/ES-DE/settings/es_input.xml` ## System view (main screen) @@ -488,6 +484,8 @@ When editing text it's also possible to paste from the clipboard into ES-DE usin Default keyboard mappings are shown in brackets below. +It's assumed that the option _Swap the A/B and X/Y buttons_ in the _Input device settings_ menu is disabled as some buttons will otherwise obviously be swapped. + **Up and down**\ _(Arrow up / Arrow down)_ @@ -539,7 +537,7 @@ _(Delete)_ Starts the media viewer in the gamelist view or the screensaver in the system view (if the _Enable screensaver controls_ setting is enabled). Used by some other minor functions as explained by the help system and/or this guide. **Y button**\ -_(Insert on Unix and Windows, F13 on macOS)_ +_(Insert on Linux and Windows, F13 on macOS)_ Marks games as favorites in the gamelist view (if the _Enable toggle favorites button_ option has been enabled). Used by some other minor functions as explained by the help system and/or this guide. @@ -555,13 +553,13 @@ As of ES-DE 2.2.0 no legacy EmulationStation themes are supported, such as those There are several user-selectable theme options in the _UI Settings_ menu, most notably _Theme variant_ which is essentially a form of theme profile. This could be anything, like different ways to navigate the themes, different layouts and designs etc. Additionally the _Theme color scheme_ setting makes it possible to select between different color schemes, if supported by the theme. The two remaining options _Theme aspect ratio_ and _Theme transitions_ are also important but you can normally leave them at their default _Automatic_ values, especially the _Theme aspect ratio_ option as it will be automatically detected. Be aware that all these theme settings are optional, it's up to the theme developer whether to add support for them to their themes. -Themes are most easily installed using the built-in theme downloader, but you can also manually add them to your ES-DE home directory, i.e. `~/.emulationstation/themes/`. By just adding them there, one folder each, they will be found during startup and you can then choose between them via the _UI Settings_ menu on the main menu. If using the portable release of ES-DE on Windows, the .emulationstation folder can be found in the root of the EmulationStation-DE directory. +Themes are most easily installed using the built-in theme downloader, but you can also manually add them to your ES-DE home directory, i.e. `~/ES-DE/themes/`. By just adding them there, one folder each, they will be found during startup and you can then choose between them via the _UI Settings_ menu on the main menu. If using the portable release of ES-DE on Windows, the ES-DE application data can be found in the root of the ES-DE directory. -Although you should place additional themes in your ES-DE home directory, the default Slate and Modern themes are located in the installation folder as they come bundled with the application. For example this could be `/usr/share/emulationstation/themes/` on Unix, `/Applications/EmulationStation Desktop Edition.app/Contents/Resources/themes/` on macOS or `C:\Program Files\EmulationStation-DE\themes\` on Windows. If using the portable ES-DE release on Windows, the themes folder will be located in the root of the EmulationStation-DE directory. +Although you should place additional themes in your ES-DE home directory, the default Slate and Modern themes are located in the installation folder as they come bundled with the application. For example this could be `/usr/share/es-de/themes/` on Linux, `/Applications/ES-DE.app/Contents/Resources/themes/` on macOS or `C:\Program Files\ES-DE\themes\` on Windows. If using the portable ES-DE release on Windows, the themes folder will be located in the root of the ES-DE directory. Note that if using the AppImage release on Linux, then there is no installation folder as all files are contained inside the AppImage file. -If you would like to customize the Slate or Modern themes, simply make a copy of their directories to `~/.emulationstation/themes/` and then those copies will take precedence over the ones in the application installation directory. +If you would like to customize the Slate or Modern themes, simply make a copy of their directories to `~/ES-DE/themes/` and then those copies will take precedence over the ones in the application installation directory. Refer to the official themes list for a selection of high-quality themes (these are also available via the built-in theme downloader):\ https://gitlab.com/es-de/themes/themes-list @@ -583,7 +581,7 @@ If you have manually downloaded any of the themes from the [official themes list If you have customized a theme by for instance modifying any of its XML files, then this will be highlighted with an exclamation mark and the text _LOCAL CHANGES_ in the theme downloader interface. If you attempt to fetch updates for such a theme you will be asked a question of whether to overwrite your local changes, or whether to cancel. If you have however added additional files to the theme that are not included in the theme repository, then these will not interfere and you can go ahead and fetch theme updates without any risk of having your local files being deleted. But there is a special (although unlikely) situation, if you add files that are not part of the theme repository but that are later added by the theme developer as well, then your local copies of any such files will be ovewritten when fetching theme updates. -In worst case there could be a situation where a repository is corrupted and the theme downloader can't properly identify or handle the corruption. In this case you will have to rename or delete that directory. This could also apply to the actual themes list repository. The latter is named _themes-list_ so by just deleting this directory (i.e. `~/.emulationstation/themes/themes-list`) you'll reset the theme downloader to its initial state. +In worst case there could be a situation where a repository is corrupted and the theme downloader can't properly identify or handle the corruption. In this case you will have to rename or delete that directory. This could also apply to the actual themes list repository. The latter is named _themes-list_ so by just deleting this directory (i.e. `~/ES-DE/themes/themes-list`) you'll reset the theme downloader to its initial state. Note that the exFAT filesystem can't be used as it makes the theme downloader fail. But using this filesystem is strongly discouraged anyway as it offers very poor disk I/O performance which makes ES-DE run really slowly. @@ -684,6 +682,7 @@ The following emulators are supported in AppImage format when using the bundled | ps2 | PCSX2 | pcsx2*.AppImage | | ps2 | Play! | Play!*.AppImage | | ps3 | RPCS3 | rpcs3*.AppImage | +| psvita | Vita3K | Vita3K*.AppImage | | psx | DuckStation | DuckStation*.AppImage | | snes | Snes9x | Snes9x*.AppImage | | switch | Yuzu | yuzu*.AppImage | @@ -730,7 +729,7 @@ There is however a workaround available to launch the Flatpak first, should you For example if using the ES-DE AppImage release, this would be the command to execute: ``` -PATH=/var/lib/flatpak/exports/bin:~/.local/share/flatpak/exports/bin:$PATH ./EmulationStation-DE-x64.AppImage +PATH=/var/lib/flatpak/exports/bin:~/.local/share/flatpak/exports/bin:$PATH ./ES-DE_x64.AppImage ``` Obviously you would need to change the path to the AppImage if it's not in your current working directory. @@ -812,6 +811,12 @@ cd ~/Applications/SkyEmu chmod +x SkyEmu ``` +And for VPinballX_GL: +``` +cd ~/Applications/VPinballX +chmod +x VPinballX_GL +``` + ## Running Windows emulators on Linux using Wine or Proton On Linux it's possible to run emulators developed specifically for Microsoft Windows via the Wine compatibility layer. Support is also included for the Proton fork of Wine. @@ -918,9 +923,9 @@ But for some systems a more elaborate setup is required, and the configuration f Let's start with the simple scenario of a single ROM file per game, which is the case for the majority of platforms. For this example we're setting up ES-DE to play Nintendo Entertainment System games. -The supported file extensions are listed in [unix/es_systems.xml](resources/systems/unix/es_systems.xml), [macos/es_systems.xml](resources/systems/macos/es_systems.xml) and [windows/es_systems.xml](resources/systems/windows/es_systems.xml) but if you generated the game system directories on first application startup or later via _Create/update system directories_ in the _Utilities_ menu, then there will be a file named systeminfo.txt in each game system directory that includes the list of supported file extensions. +The supported file extensions are listed in [linux/es_systems.xml](resources/systems/linux/es_systems.xml), [macos/es_systems.xml](resources/systems/macos/es_systems.xml) and [windows/es_systems.xml](resources/systems/windows/es_systems.xml) but if you generated the game system directories on first application startup or later via _Create/update system directories_ in the _Utilities_ menu, then there will be a file named systeminfo.txt in each game system directory that includes the list of supported file extensions. -Here is a simplified example from unix/es_systems.xml: +Here is a simplified example from linux/es_systems.xml: ```xml @@ -943,20 +948,20 @@ It's highly recommended to use filenames that correspond to the full name of the Symlinks are supported for both ROM directories and individual game files, but make sure to never symlink between files within the same system directory or there may be undefined application behavior when scraping, launching games etc. -The default game folder is ~/ROMs. On Unix this defaults to `/home//ROMs`, on macOS `/Users//ROMs` and on Windows `C:\Users\\ROMs` or `EmulationStation-DE\ROMs` depending on whether the installer release or the portable release is used. If the --home command line option was used to start ES-DE, the tilde symbol will resolve to whatever directory was passed as an argument to this option. +The default game folder is ~/ROMs. On Linux this defaults to `/home//ROMs`, on macOS `/Users//ROMs` and on Windows `C:\Users\\ROMs` or `ES-DE\ROMs` depending on whether the installer release or the portable release is used. If the --home command line option was used to start ES-DE, the tilde symbol will resolve to whatever directory was passed as an argument to this option. Assuming the default ROM directory is used, we need to create a subdirectory corresponding to the \ tag in es_systems.xml, for this example it's `nes`. So it would look something like the following: ``` -/home/myusername/ROMs/nes # Unix/Linux +/home/myusername/ROMs/nes # Linux /Users/myusername/ROMs/nes # macOS C:\Users\myusername\ROMs\nes # Windows installer -EmulationStation-DE\ROMs\nes # Windows portable +ES-DE\ROMs\nes # Windows portable ``` -Now simply copy your game ROMs into this folder, and you should end up with something like this Unix example: +Now simply copy your game ROMs into this folder, and you should end up with something like this Linux example: ``` ~/ROMs/nes/Legend of Zelda, the.zip @@ -964,7 +969,7 @@ Now simply copy your game ROMs into this folder, and you should end up with some ~/ROMs/nes/Super Mario Bros. 3.zip ``` -Note that these directories are case sensitive on Unix, so creating a directory named `Nes` instead of `nes` won't work. +Note that these directories are case sensitive on Linux/Unix, so creating a directory named `Nes` instead of `nes` won't work. That's it, start ES-DE and the NES game system should be populated. You can now scrape information and media for the games, and assuming you've setup RetroArch correctly with the Mesen core, you can launch games. If you instead prefer to use any of the three alternative emulators listed above (Nestopia UE, FCEUmm or QuickNES) then you can install one of those cores instead and change your emulator preference using the _Alternative emulators_ interface in the _Other settings_ menu or on a per-game basis via the metadata editor. Note that alternative emulators are only available for some game systems. @@ -1095,9 +1100,9 @@ Not all systems are as simple to setup as what was described in the previous sec ### Apple II -On Unix/Linux the default emulator for the apple2 system is [LinApple](http://linapple.sourceforge.net) and on Windows it's [AppleWin](https://github.com/AppleWin/AppleWin). Additionally the alternative emulators [Mednafen](https://mednafen.github.io) and [MAME](https://www.mamedev.org) standalone are supported. On macOS there is a port of AppleWin available named [Mariani](https://github.com/sh95014/AppleWin) but it appears broken at the moment as it does not accept any command line parameters. So instead only Mednafen and MAME are supported on macOS. +On Linux the default emulator for the apple2 system is [LinApple](http://linapple.sourceforge.net) and on Windows it's [AppleWin](https://github.com/AppleWin/AppleWin). Additionally the alternative emulators [Mednafen](https://mednafen.github.io) and [MAME](https://www.mamedev.org) standalone are supported. On macOS there is a port of AppleWin available named [Mariani](https://github.com/sh95014/AppleWin) but it appears broken at the moment as it does not accept any command line parameters. So instead only Mednafen and MAME are supported on macOS. -Depending on which Unix/Linux operating system you're using, LinApple may not be readily available and you may have to build it from source code or obtain a binary from somewhere on the Internet. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where it needs to be installed. If you're using an OS with access to the AUR, such as Arch or Manjaro, then LinApple is available there. Note that you need to use the _linapple-git_ package as the regular _linapple_ package does not work correctly. +Depending on which Linux operating system you're using, LinApple may not be readily available and you may have to build it from source code or obtain a binary from somewhere on the Internet. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where it needs to be installed. If you're using an OS with access to the AUR, such as Arch or Manjaro, then LinApple is available there. Note that you need to use the _linapple-git_ package as the regular _linapple_ package does not work correctly. Once the LinApple or AppleWin emulator is installed no additional configuration is required, just drop your games into the ~/ROMs/apple2 folder and launch them from inside ES-DE. @@ -1274,7 +1279,7 @@ ln -s /usr/local/Cellar/mame/0.248/share/mame/hash ~/.mame/ # on x86/Int These systems are generally straightforward to setup. For regular Atari Jaguar games you'll have a single ROM or zip archive per game that you place in the root of the `~/ROMs/atarijaguar` system directory. For Atari Jaguar CD games it's recommended to go for the .cdi format and you place these directly in the root of the `~/ROMs/atarijaguarcd` directory. -The only emulator that can run Atari Jaguar CD games is [BigPEmu](https://www.richwhitehouse.com/jaguar/) and while it's officially only available for the Windows operating system it's still possible to run it on Linux. To accomplish this you need to run it via the Wine (or Proton) translation layer. +The only emulator that can run Atari Jaguar CD games is [BigPEmL](https://www.richwhitehouse.com/jaguar/) and while it's officially only available for the Windows operating system it's still possible to run it on Linux. To accomplish this you need to run it via the Wine (or Proton) translation layer. How to setup Wine is covered in the [Running Windows emulators on Linux using Wine or Proton](USERGUIDE-DEV.md#running-windows-emulators-on-linux-using-wine-or-proton) section. @@ -1473,9 +1478,9 @@ Regardless of game setup method, per-game settings can be applied. If using the These computers as well as the Dragon 64 are slight varations of the Tandy Color Computer and as these machines are largely compatible with each other they're all emulated using the [XRoar](http://www.6809.org.uk/xroar) emulator. -This emulator is available for Unix/Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. +This emulator is available for Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. -In order to emulate the Dragon 32 you need the ROM file `d32.rom` and to emulate the Dragon 64 or Tano Dragon you need the `d64rom1.rom` and `d64rom2.rom` files. It's unclear whether `ddos10.rom` will also be needed for some games and applications. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Unix/Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. +In order to emulate the Dragon 32 you need the ROM file `d32.rom` and to emulate the Dragon 64 or Tano Dragon you need the `d64rom1.rom` and `d64rom2.rom` files. It's unclear whether `ddos10.rom` will also be needed for some games and applications. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. Following this setup there is not much to it, launching a cartridge or cassette image file will automatically run the game. @@ -1729,7 +1734,7 @@ You could optionally create a .commands file as well to specify some additional The next step is to modify the _\.singe_ file to point to the exact game directory. -So for example on Unix, modify the file `~/ROMs/laserdisc/mononoke.singe/mononoke.singe` by changing the following line: +So for example on Linux, modify the file `~/ROMs/laserdisc/mononoke.singe/mononoke.singe` by changing the following line: ``` MYDIR = "singe/mononoke/" ``` @@ -1757,11 +1762,13 @@ There are two ways to play these games, either via emulation or via simulation. **Method 1, emulation** -Proper emulation is done via the MAME standalone emulator. The games need to be in the MAME format and follow the MAME software list naming conventions, i.e. it will not be possible to run .mgw games with this emulator. The example game _Donkey Kong_ would have the filename `gnw_dkong.zip` and you'll place this file in the `gameandwatch` or `lcdgames` directory. +Proper emulation is done via the MAME - Current RetroArch core or the MAME standalone emulator. The games need to be in the MAME format and follow the MAME software list naming conventions, i.e. it will not be possible to run .mgw games with this emulator. The example game _Donkey Kong_ would have the filename `gnw_dkong.zip` and you'll place this file in the `gameandwatch` or `lcdgames` directory. However the game is only half of what's needed to properly emulate these games as you'll also need the artwork to see an image of the actual physical device when running the game. The artwork would also come in a .zip file with the same name as the game itself, e.g. `gnw_dkong.zip` and it must be located in the MAME artwork directory so it can be found by MAME. -For the artwork location there are two options available in the form of two separate MAME emulator entries, either the default _MAME Local Artwork (Standalone)_ entry or _MAME (Standalone)_. The former will require the artwork files to be placed in a directory inside the `gameandwatch` or `lcdgames` folder, which can be quite convenient as it's then bundled with the game files. Simply create an `artwork` subdirectory and place the files there. The second emulator entry will require the artwork files to be placed in the default MAME artwork directory. This location differs between operating systems and distributions so refer to the MAME documentation on where to find this folder. Here's an example of what _Donkey Kong_ would look like when going for the default option using the `gameandwatch` system: +For the RetroArch core this means it has to be placed in the system directory, specifically in `system/mame/artwork/` + +For MAME standalone there are two options available for the artwork location in the form of two separate MAME emulator entries, either the default _MAME Local Artwork (Standalone)_ entry or _MAME (Standalone)_. The former will require the artwork files to be placed in a directory inside the `gameandwatch` or `lcdgames` folder, which can be quite convenient as it's then bundled with the game files. Simply create an `artwork` subdirectory and place the files there. The second emulator entry will require the artwork files to be placed in the default MAME artwork directory. This location differs between operating systems and distributions so refer to the MAME documentation on where to find this folder. Here's an example of what _Donkey Kong_ would look like when going for the default option using the `gameandwatch` system: ``` ~/ROMs/gameandwatch/gnw_dkong.zip @@ -1770,7 +1777,7 @@ For the artwork location there are two options available in the form of two sepa As the artwork files also come with the .zip file extension they will show up inside ES-DE as if they were game files. So it's recommended to hide the entire artwork directory using the _Hidden_ option in the metadata editor, or alternatively exclude them from the multi-scraper using the _Exclude from multi-scraper_ option. -Be aware that neither ScreenScraper nor TheGamesDB currently support the MAME software list names natively so you'll need to refine the searches or the scraper services are unlikely to return any results at all (or very inaccurate results at best). +Be aware that neither ScreenScraper nor TheGamesDB currently support the MAME software list names natively so you'll need to refine the searches or the scraper services are unlikely to return any results at all (or very inaccurate results at best). However, if you have game files that match the MD5 hashes in the ScreenScraper database, then the games will scrape correctly regardless of their names. **Method 2, simulation** @@ -2134,10 +2141,21 @@ Starting ES-DE should now show the _Super Mario 3D World_ entry for the Wii U sy ### OpenBOR -The Open Beats of Rage (OpenBOR) game engine is available on Windows and Linux. Unfortunately the macOS ports seems to have been abandoned. +The Open Beats of Rage (OpenBOR) game engine is available on Android, Windows and Linux. Unfortunately the macOS port seems to have been abandoned. These games are often but not always distributed together with the game engine as specific engine versions may be required for some games. The setup is slightly different between Windows and Linux so they are described separately here. +**Android** + +Unfortunately there does not seem to be a way to launch individual OpenBOR games from ES-DE on Android, instead the OpenBOR user interface will open on game launch and you need to manually start your game from there. This means games need to be installed upfront in OpenBOR and .openbor dummy files should be added to the `ROMs/openbor` directory. These will then appear as individual games inside ES-DE and you can add metadata to them, scrape them etc. Refer to the OpenBOR documentation on how to add your game PAKs. + +Here's an example setup: + +``` +/storage/emulated/0/ROMs/openbor/D&D - K&D - The Endless Quest LNS.openbor +/storage/emulated/0/ROMs/openbor/He-Man.openbor +``` + **Windows:** There are two different OpenBOR setup methods supported on Windows, either to place the game directories directly inside the ROMs\openbor directory or to place the games somewhere else on the filesystems and create .lnk shortcuts and place these inside the ROMs\openbor directory. @@ -2210,6 +2228,8 @@ Doing this will make the game show up as if it was a single file inside ES-DE an PICO-8 Fantasy Console is a game engine developed by [Lexaloffle Games](https://www.lexaloffle.com/pico-8.php) that you need to buy a license to use. Doing so will provide you with download links to releases for Linux, macOS and Windows. Make sure to use the 64-bit release as the 32-bit release reportedly has some technical issues. On macOS and Windows the installation is straightforward, but on Linux you need to place PICO-8 in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. +On Android it's recommended to use the Fake-08 RetroArch core, although this needs to be manually downloaded. How that is done is covered briefly in the [ANDROID.md](ANDROID.md#fake-08) document. + After the emulator has been installed you are ready to add some games. There are two ways to play games using PICO-8, either to add them to ES-DE as for any other system, or using the built-in Splore tool to explore and run games all through the PICO-8 user interface. For the first approach you can download games from the [PICO-8 forum](https://www.lexaloffle.com/bbs/?cat=7) and these are quite uniquely distributed as .png images. You just download these and place them inside the ~/ROMs/pico8 directory, for example: @@ -2229,16 +2249,17 @@ This is what the complete setup could look like: ~/ROMs/pico8/xzero-3.p8.png ``` -**Using the Retro8 RetroArch core** +**Using the Fake-08 and Retro8 RetroArch cores** + +On Android the Fake-08 core provides a good alternative to the official PICO-8 engine which is not available on this operating system. ES-DE also includes support for the Retro8 RetroArch core across all platforms, but it's borderline unusable and does not seem to be actively developed any longer. + +Neither Fake-08 nor Retro8 support the .png file extension, so in order to use these cores you need to remove that extension from your game files and only keep the .p8 extension, such as this: -ES-DE also includes support for the Retro8 RetroArch core but it's borderline unusable and does not seem to be actively developed any longer. If you still want to use it, then you first need to rename your game files by removing _.png_ from the end of the filenames, like this: ``` ~/ROMs/pico8/c_e_l_e_s_t_e-0.p8 ~/ROMs/pico8/xzero-3.p8 ``` -Following this just select the _Retro8_ alternative emulator and the games will (somehow) work. - ### Ports and desktop applications _The emulators system is essentially a clone of the desktop system so it's not discussed specifically in this section._ @@ -2254,7 +2275,7 @@ For the _desktop_ system specifically, you can choose to suspend ES-DE while an Shortcuts are very easy to setup, on Windows you can simply copy any .lnk file from the Start Menu into the `ports` or `desktop` system folders and then you can launch them directly from inside ES-DE. You can also create shortcuts manually to any file by right clicking on it in Explorer and selecting _Create shortcut_. -Likewise on Unix you can copy any .desktop shortcut into these system directories and they can then be launched by ES-DE. +Likewise on Linux you can copy any .desktop shortcut into these system directories and they can then be launched by ES-DE. Here's an example on Windows: ``` @@ -2262,7 +2283,7 @@ Here's an example on Windows: ~\ROMs\ports\openxcom.lnk ``` -And here's an example on Unix: +And here's an example on Linux: ``` ~/ROMs/desktop/org.libretro.RetroArch.desktop ~/ROMs/desktop/spotify.desktop @@ -2278,7 +2299,7 @@ Here's an example using alias files on macOS: **Method 2, scripts** -For more advanced setups you may want to use scripts. While it's possible to add these files directly to the root of the system directories it's instead generally recommended to setup a separate directory per game as there may be more than a single file required. For instance you may have multiple game variants or mods or you may want to keep game data files within the ROM directory tree. Only examples for Unix are provided here, but it's the same process for Windows and macOS except that in Windows .bat batch files are used instead of shell scripts. +For more advanced setups you may want to use scripts. While it's possible to add these files directly to the root of the system directories it's instead generally recommended to setup a separate directory per game as there may be more than a single file required. For instance you may have multiple game variants or mods or you may want to keep game data files within the ROM directory tree. Only examples for Linux are provided here, but it's the same process for Windows and macOS except that in Windows .bat batch files are used instead of shell scripts. Here's a setup of GZDoom and vkQuake: ``` @@ -2359,7 +2380,7 @@ Apart from this you need to install the PS3 system firmware to use the emulator, **Method 1, shortcuts** -First install your games inside RPCS3, then right click on each entry and select _Create Shortcut_ followed by _Create Desktop Shortcut_. On Windows this will create shortcuts with the .lnk extension, on macOS they will have the .app extension and on Unix/Linux they will have the .desktop extension. +First install your games inside RPCS3, then right click on each entry and select _Create Shortcut_ followed by _Create Desktop Shortcut_. On Windows this will create shortcuts with the .lnk extension, on macOS they will have the .app extension and on Linux they will have the .desktop extension. Then simply move these files from your desktop to your ~/ROMs/ps3 directory and you're done. Here's an example of what this could look like on Linux: ``` @@ -2398,7 +2419,7 @@ When using this setup method you need to set the alternative emulator to _RPCS3 Support for the PS Vita is currently experimental due to the early stages of development for the Vita3K emulator. While there's a growing list of games that are playable, integration with ES-DE is a bit rough at the moment. Hopefully this will improve as Vita3K evolves. -On Windows the Vita3K installation is straightforward, but on Linux you may need to place the emulator in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. If using a Linux distribution that provides Vita3K via the repository (such as the AUR on Arch/Manjaro) then you can skip this step and install the emulator using your OS package manager. +On Android and Windows the Vita3K installation is straightforward, but on Linux you may need to place the emulator in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. If using a Linux distribution that provides Vita3K via the repository (such as the AUR on Arch/Manjaro) then you can skip this step and install the emulator using your OS package manager. Although a macOS release of Vita3K seems to be in the works this does not seem to be readily available for download so there is currently no macOS support for this system in ES-DE. @@ -2428,7 +2449,7 @@ Simply copy the Start Menu entries for your Steam games into the ~\ROMs\steam di ~\ROMs\steam\Undertale.url ``` -**Unix/Linux** +**Linux** Copy the .desktop shortcuts for your games into the ~/ROMs/steam directory. If your desktop environment does not allow you to copy them directly from the application menu then you may need to navigate to `~/.local/share/applications` using your file manager and copy the .desktop files from there. Alternatively you can also create shortcuts from inside Steam by right clicking on a game, selecting _Manage_ and then _Add desktop shortcut_. These file can then be moved from your desktop to your ~/ROMs/steam directory. This is an example of what you could end up with: @@ -2452,6 +2473,19 @@ On macOS the shortcuts come with the .app extension and are actually directories As the Nokia N-Gage was running Symbian it may seem like the _ngage_ and _symbian_ systems would be identical. There is however a difference in that N-Gage games were shipped on MMC memory cards while regular Symbian games were packaged as _Software Installation Script_ files with the .sis or .sisx extension. Although the EKA2L1 emulator is used for both systems the setup is quite different, as detailed below. +**Android** + +Unfortunately there does not seem to be a way to launch individual games from ES-DE on Android specifically, so instead the EKA2L1 user interface will open on game launch and you need to manually start your game from inside the emulator. As games need to be installed upfront in the emulator as described below it's probably a good idea to just setup dummy game files with the .symbian or .ngage file extensions inside the ES-DE ROMs directory tree. These will then appear as indvidual games inside ES-DE and you can add metadata to them, scrape them etc. + +Here's an example setup: +``` +/storage/emulated/0/ROMs/ngage/Asphalt 2.ngage +/storage/emulated/0/ROMs/ngage/Bomberman.ngage +/storage/emulated/0/ROMs/ngage/CallofDuty.ngage +/storage/emulated/0/ROMs/symbian/Animal Farm.symbian +/storage/emulated/0/ROMs/symbian/AnotherWorld.symbian +``` + **General setup** The EKA2L1 installation should be fairly straightforward, for Linux there is an official AppImage, for macOS there is a DMG installer and for Windows a zip archive release. Just be aware that the AppImage has the very generic name `ubuntu-latest.AppImage` and needs to be renamed and moved to `~/Applications/EKA2L1.AppImage` in order for ES-DE to find it. @@ -2539,9 +2573,9 @@ Finally there's an emulator entry named _EKA2L1 [Custom device] (Standalone)_ wh This computer (which is confusingly also known as _TRS-80 Color Computer_ even though it's a completely different machine than the _TRS-80_) is emulated using the [XRoar](http://www.6809.org.uk/xroar) emulator. -This emulator is available for Unix/Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. +This emulator is available for Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. -In order for XRoar to work correctly you need the ROM files `bas13.rom`, `disk11.rom` and `extbas11.rom`. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Unix/Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. +In order for XRoar to work correctly you need the ROM files `bas13.rom`, `disk11.rom` and `extbas11.rom`. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. Following this setup there is not much to it, launching a cartridge or cassette image file will automatically run the game. If launching a diskette image you will probably need to manually run the game file from inside the emulated operating system. Such commands are beyond the scope of this document, but the following [quick reference PDF](https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%20Disk%20System%20-%20Quick%20Reference%20Guide%20(Tandy).pdf) provides a good command overview. @@ -2553,7 +2587,7 @@ Two emulator entries are available for this system, _XRoar CoCo 2 NTSC (Standalo Tandy Corporation made the somewhat dumb decision of naming several unrelated computers as TRS-80 which has caused decades of confusion. The _Tandy TRS-80_ system in ES-DE emulates the original black-and-white TRS-80 Model I. If you want to emulate the TRS-80 Color Computer then you'll want to use the _Tandy Color Computer_ system instead. -The TRS-80 is emulated using [sdl2trs](https://gitlab.com/jengun/sdltrs) which is available for Unix/Linux and Windows, seemingly there is no macOS port. If you use a Debian-based Linux distribution there is a .deb package made by the developers and if you're using an Arch-based distribution you can install it using the AUR. For other distributions you may have to build from source code or download a pre-built binary from some other location. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where sdl2trs will need to be installed in that case. +The TRS-80 is emulated using [sdl2trs](https://gitlab.com/jengun/sdltrs) which is available for Linux and Windows, seemingly there is no macOS port. If you use a Debian-based Linux distribution there is a .deb package made by the developers and if you're using an Arch-based distribution you can install it using the AUR. For other distributions you may have to build from source code or download a pre-built binary from some other location. See the [Using manually downloaded emulators on Linux](USERGUIDE-DEV.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where sdl2trs will need to be installed in that case. On Windows only the 64-bit release of the emulator is supported, with the filename `sdl2trs64.exe`. @@ -2586,11 +2620,11 @@ Here's what a complete setup could look like: ### Tangerine Computer Systems Oric -These games are executed using the Oricutron emulator which is readily available on Windows but quite problematic to get hold on for Unix and macOS. +These games are executed using the Oricutron emulator which is readily available on Windows but quite problematic to get hold on for Linux and macOS. Although there is a macOS build available at the Oricutron [download page](http://www.petergordon.org.uk/oricutron/) this seems to not work properly, or it's unclear how it should be used. As such this system is unsupported on macOS, but the configuration entries still exist in the bundled es_find_rules.xml and es_systems.xml files so if you manage to get the emulator to run, ES-DE should work with these games. -Likewise on Unix there seems to be no binaries available for download so you need to build the emulator yourself. As multiple files like images and roms are needed to run this emulator, it's easiest to download and extract the Windows version which contains all this data and then build from source code and simply copy over the `Oricutron` binary (example below using Ubuntu): +Likewise on Linux there seems to be no binaries available for download so you need to build the emulator yourself. As multiple files like images and roms are needed to run this emulator, it's easiest to download and extract the Windows version which contains all this data and then build from source code and simply copy over the `Oricutron` binary (example below using Ubuntu): ``` mkdir -p ~/Applications/oricutron @@ -2620,6 +2654,76 @@ https://docs.mamedev.org/usingmame/defaultkeys.html Scraping can also be a bit challenging as MAME software list names are used and neither ScreenScraper nor TheGamesDB can parse these names. So it's recommended to run the scraper in interactive mode and refine the searches for all games that are not properly identified. +### Visual Pinball + +The pinball simulator Visual Pinball can be a bit tricky to setup as it supports a wide range of tables. Some of these require [PinMAME](https://github.com/vpinball/pinmame) and some don't. Some simulated tables are older electromechnical design and some are of more modern solid state designs. Some are recreations of real physical games and some are purely virtual and don't exist in physical form. In many cases there is not a definitive release for a table and you may need to assemble various files to get to a fully working game. + +As pinball games is a complex topic it will only be covered briefly here, refer to the official Visual Pinball [documentation](https://github.com/vpinball/vpinball/blob/standalone/standalone/README.md) for more details. + +The Windows release of Visual Pinball can be downloaded here (make sure to get the GL version):\ +https://github.com/vpinball/vpinball/releases + +Apart from this the Windows-specific setup is not covered in this document, but you should be able to find a lot of resources online on this topic. + +The Linux and macOS releases need to be downloaded from the GitHub Actions page for the time being:\ +https://github.com/vpinball/vpinball/actions + +On Linux simply unpack the archive into `~/Applications/VPinballX` and make sure to give the binary executable permissions: +``` +cd ~/Applications/VPinballX +chmod +x VPinballX_GL +``` + +On macOS there is a DMG package that you simply install. + +Once you've installed Visual Pinball start it once outside ES-DE and its .ini configuration file will be created. On Linux and macOS this is `~/.vpinball/VPinballX.ini` + +Set the following entries in this file: +``` +VPRegPath = ./ +PinMAMEPath = ./ +PinMAMEIniPath = ./ +``` + +If you don't do this the table may still start but won't work properly and you'll not be able to actually start a game. + +ES-DE launches .vpx and .vpt files for the vpinball system, but most tables come shipped with multiple additional files that are needed for the table to work, for example: +``` +~/ROMs/vpinball/fh/pinmame/ +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +``` + +Assembling the necessary files to run a table is beyond the scope of this guide but there are various resources available online for this. + +This specific table requires PinMAME to run, and the _fh_ directory name is an example of the abbreviations commonly used in the pinball community. You can for instance find these names in the [Internet Pinball Database](https://www.ipdb.org/) where they are referred to as _Common Abbreviations_. + +If you don't need to retain these abbreviations then you can simply setup your games using the _directories interpreted as files_ functionality: +``` +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/pinmame/ +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +``` + +If you however insist on retaining the abbreviations then you could use folder links to launch the .vpx or .vpt file inside the fh directory by editing the folder in the metadata editor and selecting the game file via the _Folder link_ entry. + +A final option would be to use the _folder flattening_ functionality, although this has many negative side effects that you need to be aware of. If going for this approach make sure to thoroughly read the [Folder flattening](USERGUIDE-DEV.md#folder-flattening) section of this document. + +``` +~/ROMs/vpinball/fh/pinmame/ +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +~/ROMs/vpinball/flatten.txt +``` + +With folder flattening in place the .vpx and .vpt files will show up as file entries directly in the root of the gamelist. + ## Scraping Scraping means downloading metadata and game media files (images and videos) for the games in your collection. @@ -2689,33 +2793,33 @@ Apart from this, hopefully the scraping process should be self-explanatory. If you already have a library of game media (images, videos and PDF manuals) you can manually copy these files into ES-DE. The same procedure applies if you want to add media for individual games, for instance when the scraper did not return any results or if you didn't like the media it provided. -The default media directory is `~/.emulationstation/downloaded_media//` +The default media directory is `~/ES-DE/downloaded_media//` This directory can however be changed using the _Game media directory_ setting in the _Other settings_ menu so make sure to check this setting before attempting to follow the instructions below. If the setting is blank, then the default directory is in use. See the [Supported game systems](USERGUIDE-DEV.md#supported-game-systems) table at the bottom of this guide for a list of all system names. -An example on Unix: +An example on Linux: ``` -/home/myusername/.emulationstation/downloaded_media/c64/screenshots/ +/home/myusername/ES-DE/downloaded_media/c64/screenshots/ ``` An example on macOS: ``` -/Users/myusername/.emulationstation/downloaded_media/c64/screenshots/ +/Users/myusername/ES-DE/downloaded_media/c64/screenshots/ ``` An example on Windows (installer release): ``` -C:\Users\Myusername\.emulationstation\downloaded_media\c64\screenshots\ +C:\Users\Myusername\ES-DE\downloaded_media\c64\screenshots\ ``` An example on Windows (portable release): ``` -EmulationStation-DE\.emulationstation\downloaded_media\c64\screenshots\ +ES-DE\ES-DE\downloaded_media\c64\screenshots\ ``` The media directories per game system are: @@ -2746,8 +2850,8 @@ The media files must correspond exactly to the game files. Take for example this For this example, the filename structure needs to look like the following: ``` -~/.emulationstation/downloaded_media/c64/screenshots/Multidisk/Last Ninja 2/Last Ninja 2.jpg -~/.emulationstation/downloaded_media/c64/videos/Multidisk/Last Ninja 2/Last Ninja 2.mp4 +~/ES-DE/downloaded_media/c64/screenshots/Multidisk/Last Ninja 2/Last Ninja 2.jpg +~/ES-DE/downloaded_media/c64/videos/Multidisk/Last Ninja 2/Last Ninja 2.mp4 ``` Note that there is seemingly an exception to this logic if the _Directories interpreted as files_ functionality has been used, in which case the "file extension" added to the directory is also included in the game media filenames. Take for example the following ScummVM game: @@ -2758,15 +2862,15 @@ Note that there is seemingly an exception to this logic if the _Directories inte The media files for this directory which is interpreted as a file will be: ``` -~/.emulationstation/downloaded_media/scummvm/screenshots/dig.scummvm.png -~/.emulationstation/downloaded_media/scummvm/videos/dig.scummvm.mp4 +~/ES-DE/downloaded_media/scummvm/screenshots/dig.scummvm.png +~/ES-DE/downloaded_media/scummvm/videos/dig.scummvm.mp4 ``` This is not a bug as these are not really file extensions after all, it's just a directory with a dot in the filename that happens to look like a file extension because that's how the _Directories interpreted as files_ logic works. For images .jpg and .png file extensions are supported and for videos .avi, .mkv, .mov, .mp4 and .wmv are supported. -Remember that on Unix filenames are case sensitive, and as well the file extensions must be in lower case, such as .png instead of .PNG or .Png or the file won't be found. +Remember that on Linux filenames are case sensitive, and as well the file extensions must be in lower case, such as .png instead of .PNG or .Png or the file won't be found. It's possible to change the game media directory location from within ES-DE, for this see the option _Game media directory_ in the _Other settings_ menu. @@ -2977,10 +3081,6 @@ If file hash searching is enabled, then this specifies the maximum allowed file Affects both overwriting of metadata as well as actual game media files on the filesystem. Even with this option disabled, metadata entries which are set to their default values will be populated by the scraper. In other words, this option only affects overwriting of previously scraped data, or data manually entered via the metadata editor. Game names are considered as set to their default values if either corresponding to the physical game file on disk minus the extension (e.g. the entry _Commando_ if the file is named _Commando.zip_), or for arcade games if corresponding to the MAME names as defined in the bundled mamenames.xml. Note that this setting does not affect generated miximages, that is instead controlled by the setting _Overwrite miximages (scraper/offline generator)_ found in the miximage settings menu. -**Halt on invalid media files** - -With this setting enabled, if any media files returned by the scraper seem to be invalid, the scraping is halted and an error message is presented where it's possible to retry or cancel the scraping of the specific game. In the case of multi-scraping it's also possible to skip the game and proceed to the next one in the queue. With this setting disabled, all media files will always be accepted and saved to disk. The file verification is quite basic and future versions may improve on this by using file checksums or other file integrity checks. There is an exception in place for box back covers when using ScreenScraper. As many of these specific images are broken, there is an automatic filter built in that is always active and which removes blank images and those containing only a few lines of pixels. - **Search using file hashes (non-interactive mode)** _(ScreenScraper only)_ When running the non-interactive scraper it's possible to search using a hash value calculated from the actual game file. Assuming ScreenScraper has a match for your file in their database, this will lead to 100% accuracy as the game name will be completely ignored. If there is no match for the hash value, then a fallback will be made to the game name and the normal search logic applies. The maximum allowed file size to apply this type of search to can be set using the _Hash searches max file size_ slider. Note that file hash searching can increase scraping times significantly if applied to large game files as the entire file needs to be read and processed to calculate its hash value. And obviously file hash searching will not work for directories, scripts, shortcuts, .m3u files and so on which will have no matching entries in the ScreenScraper database. @@ -3041,6 +3141,10 @@ Themes optionally support variants which are a type of theme profiles defined by If the theme author has included multiple color schemes, then these can be selected between using this menu option. +**Theme font size** + +If the theme author has included support for multiple font/text sizes, then these can be selected between using this menu option. Possible choices are _medium, large, small, extra large_ and _extra small_. What layout changes these font size options actually make is completely up to the theme author. + **Theme aspect ratio** Themes could optionally be optimized for different screen aspect ratios. ES-DE supports 16:9, 16:10, 3:2, 4:3, 5:4, 21:9 and 32:9 in both horizontal and vertical orientation, but it's completely up to the theme author which of these are actually supported by the theme. It's normally best to leave this setting at _Automatic_ in which case ES-DE will automatically select the aspect ratio that most closely matches the screen resolution. The _Automatic_ option is however only available if the theme supports at least two aspect ratios. @@ -3059,7 +3163,7 @@ If set to _None_, the system view will be displayed on startup. Any other value **Systems sorting** -The order in which to sort the game systems. The default option is _Full names or custom_ which will sort by full system names, unless there is a ~/.emulationstation/custom_systems/es_systems_sorting.xml file present which will then be used instead. The other options are using the bundled sorting configuration files for _Release year_ or _Manufacturer, release year_ or _HW type, release year_ or _Manufacturer, HW type, release year_. If using any of these bundled sorting files, then any ~/.emulationstation/custom_systems/es_systems_sorting.xml will be ignored. When changing this setting ES-DE will automatically reload. +The order in which to sort the game systems. The default option is _Full names or custom_ which will sort by full system names, unless there is a ~/ES-DE/custom_systems/es_systems_sorting.xml file present which will then be used instead. The other options are using the bundled sorting configuration files for _Release year_ or _Manufacturer, release year_ or _HW type, release year_ or _Manufacturer, HW type, release year_. If using any of these bundled sorting files, then any ~/ES-DE/custom_systems/es_systems_sorting.xml will be ignored. When changing this setting ES-DE will automatically reload. **Game default sort order** @@ -3119,7 +3223,7 @@ With this option enabled, there will be an overlay displayed when quickly scroll **Enable virtual keyboard** -This enables a virtual (on-screen) keyboard that can be used at various places throughout the application to input text and numbers using a controller. The Shift and Alt keys can be toggled individually or combined to access many special characters. The general use of the virtual keyboard should hopefully be self-explanatory. +This enables a virtual (on-screen) keyboard that can be used at various places throughout the application to input text and numbers using a controller. The Shift and Alt keys can be toggled individually or combined to access many special characters. The general use of the virtual keyboard should hopefully be self-explanatory. On Android the virtual keyboard from the operating system will be used if this setting has been disabled. **Enable toggle favorites button** @@ -3215,7 +3319,7 @@ Whether to search the custom image directory recursively. **Custom image directory** -The directory for custom images. The tilde `~` symbol can be used which will expand to the user home directory. It's also possible to use the %ESPATH% and %ROMPATH% variables which will set the directory relative to the ES-DE binary directory or the ROM directory. +The directory for custom images. The tilde `~` symbol can be used which will expand to the user home directory. It's also possible to use the %ESPATH% and %ROMPATH% variables which will set the directory relative to the ES-DE binary directory or the ROM directory. Images in the .jpg, .png, .webp, .svg and unanimated .gif formats are supported. #### Video screensaver settings @@ -3285,13 +3389,33 @@ Settings related to the input devices, i.e. the keyboard and controllers. This setting gives the ability to choose between the controller types _Xbox, Xbox 360, PlayStation 1/2/3, PlayStation 4, PlayStation 5, Switch Pro_ and _SNES_. Doing so alters the help icons and help text as well as the icons and text for the input device configurator. The setting is only cosmetic and does not change the controller behavior or the controller button mappings. +**Touch overlay size** _(Android only)_ + +If the touch input overlay has been enabled, then this setting makes it possible to select between a _medium, large, small_ or _extra small_ overlay size. + +**Touch overlay opacity** _(Android only)_ + +Sets the opacity of the input overlay to _normal, low_ or _very low_. + +**Touch overlay fade-out time** _(Android only)_ + +How long, in seconds, to display the overlay before fading it. Tapping anywhere on the screen will bring back the overlay if it's been faded out. + +**Enable touch overlay** _(Android only)_ + +The touch overlay applies a layer of virtual buttons on top of the ES-DE window. This makes it possible to use the application on devices that lack physical buttons, such as a mobile phone or tablet. Be careful to not accidentally disable this setting as you may lock yourself out of the application. If you do that, you'll need to temporarily plug in a controller or keyboard to enable the setting again, or you could clear the ES-DE storage in the Android App settings which will force the configurator to run on next startup. + **Only accept input from first controller** If enabling this option, only the first controller detected during startup will send its input to ES-DE (the keyboard input is unaffected by this setting and will be enabled regardless). This is a good way to limit potential chaos with multiple persons fighting over which games to play. Note that disconnecting and reconnecting controllers while ES-DE is running may change what is considered the first controller. This setting does not affect the emulators in any way, it's only applied to ES-DE. Another issue is that some wireless controllers have buggy drivers and will register as two devices, meaning all button presses will be registered twice inside ES-DE. Using this option is one solution to the problem, although it's also possible to blacklist the extra controller entry, as described [here](INSTALL-DEV.md#adding-custom-controller-profiles). +**Swap the A/B and X/Y buttons** + +When enabling this setting the functions for the A/B and X/Y buttons will be swapped and the helpsystem will be updated accordingly. The primary purpose of this setting is for using controllers like Nintendo Switch Pro and some handhelds which have swapped the physical positions of these buttons. With this setting enabled you'll be able to rely on your muscle memory from using any other controller type with a normal button layout. Note that the button swap does not apply to the keyboard which leads to a slight inconsistency as the helpsystem will only match the controller and not the keyboard. + **Ignore keyboard input** -If this setting is enabled then all keyboard input will be ignored, except the quit shortcut used to shut down the application. The main reason for ignoring keyboard input is if running Steam in parallel to ES-DE and you need to use the Steam Input's _Desktop Layout_ functionality to send keyboard input using the controller. In this case double or conflicting input will be sent to ES-DE as both the controller and keyboard events are read by the application. It's however generally a better idea to disable this functionality altogether in Steam and leave the ES-DE setting untouched. If you accidentally enable this setting when using a keyboard as input device, then you'll either need to plug in a controller to disable it again, or you'll need to modify the _InputIgnoreKeyboard_ entry in the ~/.emulationstation/es_settings.xml configuration file. +If this setting is enabled then all keyboard input will be ignored, except the quit shortcut used to shut down the application. The main reason for ignoring keyboard input is if running Steam in parallel to ES-DE and you need to use the Steam Input's _Desktop Layout_ functionality to send keyboard input using the controller. In this case double or conflicting input will be sent to ES-DE as both the controller and keyboard events are read by the application. It's however generally a better idea to disable this functionality altogether in Steam and leave the ES-DE setting untouched. If you accidentally enable this setting when using a keyboard as input device, then you'll either need to plug in a controller to disable it again, or you'll need to modify the _InputIgnoreKeyboard_ entry in the ~/ES-DE/settings/es_settings.xml configuration file. **Configure keyboard and controllers** @@ -3350,13 +3474,13 @@ _The system-wide alternative emulators interface. An entry in bold and with a ge **Game media directory** -This setting defines the directory for game media, i.e. images, videos and PDF manuals that have normally been downloaded by the scraper. The default location is _~/.emulationstation/downloaded_media_ +This setting defines the directory for game media, i.e. images, videos and PDF manuals that have normally been downloaded by the scraper. The default location is _~/ES-DE/downloaded_media_ **VRAM limit** The amount of video RAM to use for the application. Defaults to 512 MiB (192 MiB on the Raspberry Pi) which works fine most of the time when using moderately demanding themes with medium-sized collections at up to 4K display resolution. For large collections (as in many different systems rather than many games per system) in combination with demanding themes which use lots of full-screen images and similar it's recommended to increase this number to 1024 MiB or possibly higher to avoid stuttering and texture pop-in. Enabling the GPU statistics overlay gives some indications regarding the amount of texture memory currently used, which is helpful to determine a reasonable value for this setting. The allowed range for the settings is 128 to 2048 MiB. If you try to set it lower or higher than this by passing such values as command line parameters or by editing the es_settings.xml file manually, ES-DE will log a warning and automatically adjust to a value within the allowable range. -**Anti-aliasing (MSAA) (requires restart)** +**Anti-aliasing (MSAA) (requires restart)** _(All operating systems except Android)_ Sets the level of anti-aliasing for the application. You can select between _disabled_, _2x_ or _4x_. Note that this is a potentially dangerous option which may prevent the application from starting altogether with some GPU drivers. If you're unable to run the application after changing this option then you can reset it via the `--anti-aliasing 0` command line option. Be aware that enabling anti-aliasing has a slight to moderate performance impact. @@ -3388,7 +3512,7 @@ For platforms and package formats where the previous setting above is available With this setting enabled, the taskbar will be hidden when launching ES-DE, and it will be restored when the application exits. This can make for a more seamless experience as the taskbar could otherwise flash by briefly when launching and returning from games. -**Run in background (while game is launched)** +**Run in background (while game is launched)** _(All operating systems except Android)_ Enabling this option makes ES-DE continue to run while a game is launched. This is normally not recommended as it leads to a slightly strange application behavior and it also removes the ability to capture return codes and log output from the emulators. Generally this option should only be enabled if there are issues with launching games while suspending ES-DE. Note however that some systems like Valve Steam will always keep ES-DE running in the background because they require it for technical reasons (i.e. those systems will override this menu option). @@ -3402,7 +3526,7 @@ If enabled, you will be able to select alternative emulators per game using the **Show hidden files and folders** -If this option is disabled, hidden files and folders within the ROM directory tree are excluded from ES-DE. On Unix and macOS this means those starting with a dot, and on Windows it's those set as hidden by using an NTFS attribute. This setting is only intended for special situations and is not to be confused with the next option below which hides files based on metadata configuration within ES-DE. When changing this setting ES-DE will automatically reload. +If this option is disabled, hidden files and folders within the ROM directory tree are excluded from ES-DE. On Linux and macOS this means those starting with a dot, and on Windows it's those set as hidden by using an NTFS attribute. This setting is only intended for special situations and is not to be confused with the next option below which hides files based on metadata configuration within ES-DE. When changing this setting ES-DE will automatically reload. **Show hidden games** @@ -3420,7 +3544,7 @@ If enabled, only games that have metadata saved to the gamelist.xml files will b MAME software list names for all arcade systems are automatically expanded to their full game names using a bundled MAME name translation file. By default any extra information from this file that is located inside brackets is removed. This includes information like region, version/revision, license, release date and more. By setting this option to disabled that information is retained. Note that this is only applicable for any game names which have not been scraped as the scaper will overwrite the expanded information with whatever value the scraper service returns. It's however possible to disable scraping of game names altogether as covered elsewhere in this guide. -**Disable desktop composition (requires restart)** _(Unix and X11/Xorg only)_ +**Disable desktop composition (requires restart)** _(Linux and X11/Xorg only)_ The window manager desktop composition can adversely affect the framerate of ES-DE, especially on weaker graphics cards and when running at higher resolution. As such the desktop compositor can be disabled when running ES-DE, although the window manager has to be configured to allow applications to do this for the option to have any effect. Note that enabling this setting can cause problems with some graphics drivers so if you experience strange flickering and similar, then make sure to keep this setting disabled. In case of such issues, make sure that the emulator is also not blocking the composition (e.g. RetroArch has a corresponding option). This setting has no effect if using Wayland, it only applies to X11/Xorg. @@ -3436,7 +3560,7 @@ Displays the framerate and VRAM statistics as an overlay. This can be useful to Enabling or disabling the menu when the UI mode is set to _Kid_. Mostly intended for testing purposes as it's not recommended to enable the menu in this restricted mode. -**Show quit menu (reboot and power off entries)** _(All operating systems except macOS)_ +**Show quit menu (reboot and power off entries)** _(All operating systems except macOS and Android)_ With this setting enabled, there is a Quit menu shown as the last entry on the main menu which provides options to quit ES-DE, to reboot the computer or to power off the computer. With this setting disabled, there will simply be an entry to quit the application instead of the complete quit menu. @@ -3456,21 +3580,21 @@ This utility will create all game system directories inside your ROM directory t This utility will rescan the ROM directory for any changes such as added or removed games and systems without having to restart the application. But don't use this utility to reload changes to gamelist.xml files that you have made outside ES-DE as this can lead to data corruption. If you need to manually edit your gamelist.xml files then do this while ES-DE is shut down. -### Quit / Quit EmulationStation +### Quit / Quit ES-DE -The _Quit_ menu or _Quit EmulationStation_ entry as described by the _Show quit menu (reboot and power off entries)_ option above. +The _Quit_ menu or _Quit ES-DE_ entry as described by the _Show quit menu (reboot and power off entries)_ option above. If the menu is enabled, these are its entries: -**Quit EmulationStation** +**Quit ES-DE** -If the option _When to save game metadata_ has been set to _On exit_, the gamelist.xml files will be updated at this point. This applies also if the Quit menu is disabled and replaced by the _Quit EmulationStation_ entry. +If the option _When to save game metadata_ has been set to _On exit_, the gamelist.xml files will be updated at this point. This applies also if the Quit menu is disabled and replaced by the _Quit ES-DE_ entry. -**Reboot system** _(All operating systems except macOS)_ +**Reboot system** _(All operating systems except macOS and Android)_ Self explanatory. -**Power off system** _(All operating systems except macOS)_ +**Power off system** _(All operating systems except macOS and Android)_ Self explanatory. @@ -3772,9 +3896,9 @@ _Example of custom collections, here configured as genres._ _When editing a custom collection and the theme uses a textlist, then a tick symbol will be displayed for any game that is part of the collection._ -The way that custom collections are implemented is very simple. There is a single configuration file per collection inside the folder `~/.emulationstation/collections` +The way that custom collections are implemented is very simple. There is a single configuration file per collection inside the folder `~/ES-DE/collections` -For this example a file will have been created named `~/.emulationstation/collections/custom-Platform.cfg` +For this example a file will have been created named `~/ES-DE/collections/custom-Platform.cfg` The file contents is simply a list of ROM files, such as the following: @@ -3790,7 +3914,7 @@ The file contents is simply a list of ROM files, such as the following: Any changes to custom collections, for example adding or removing a game, will be immediately written to the corresponding collection configuration file. -If you copy or migrate a collection from a previous version of EmulationStation or if you're setting up ES-DE on a new computer, the collection will not be enabled by just copying its configuration file to the `~/.emulationstation/collections` directory. You always need to explicitly enable each collection via the menu. +If you copy or migrate a collection from a previous version of EmulationStation or if you're setting up ES-DE on a new computer, the collection will not be enabled by just copying its configuration file to the `~/ES-DE/collections` directory. You always need to explicitly enable each collection via the menu. If you're migrating from a previous version of EmulationStation that has absolute paths in the collection files, then these will be rewritten with the %ROMPATH% variable the first time you make a change to the collection. @@ -3810,9 +3934,9 @@ The **System name** column corresponds to the directory where you should put you For the **Full name** column, text inside square brackets [] are comments and not part of the actual system name. -The **Default emulator** column lists the primary emulator as configured in es_systems.xml. If this differs between Unix, macOS and Windows then it's specified in square brackets, such as [UW] for Unix and Windows and [M] for macOS. +The **Default emulator** column lists the primary emulator as configured in es_systems.xml. If this differs between Linux, macOS and Windows then it's specified in square brackets, such as [LW] for Linux and Windows and [M] for macOS. -The **Alternative emulators** column lists additional emulators configured in es_systems.xml that can be selected per system and per game. In the same manner as the _Default emulator_ column, differences between Unix, macOS and Windows are marked using square brackets. +The **Alternative emulators** column lists additional emulators configured in es_systems.xml that can be selected per system and per game. In the same manner as the _Default emulator_ column, differences between Linux, macOS and Windows are marked using square brackets. The **Needs BIOS** column indicates if any BIOS/system ROMs are required. Additional details should be covered by the emulator documentation. @@ -3838,7 +3962,7 @@ On Windows the following emulators provide a way to inform ES-DE where they have * Yuzu Default emulator/Alternative emulators columns: \ -**[U]**: Unix/Linux, **[M]**: macOS, **[W]**: Windows +**[L]**: Linux, **[M]**: macOS, **[W]**: Windows All emulators are RetroArch cores unless marked as **(Standalone)**, **(Wine)** or **(Proton)** @@ -3849,190 +3973,190 @@ The **@** symbol indicates that the emulator is _deprecated_ and will be removed | 3do | 3DO Interactive Multiplayer | Opera | | Yes | | | adam | Coleco Adam | MAME [Diskette] **(Standalone)** | MAME [Tape] **(Standalone)**,
MAME [Cartridge] **(Standalone)**,
MAME [Software list] **(Standalone)** | Yes | | | ags | Adventure Game Studio Game Engine | _Shortcut or script_ | | No | | -| amiga | Commodore Amiga | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amiga1200 | Commodore Amiga 1200 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amiga600 | Commodore Amiga 600 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amigacd32 | Commodore Amiga CD32 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga | Commodore Amiga | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga1200 | Commodore Amiga 1200 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga600 | Commodore Amiga 600 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amigacd32 | Commodore Amiga CD32 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | | amstradcpc | Amstrad CPC | Caprice32 | CrocoDS,
CPCemu **(Standalone)**,
MAME **(Standalone)** | Yes for MAME | Single archive or disk file | | android | Google Android | BlueStacks **(Standalone)** [W] | | No | Shortcut (.lnk) file | -| apple2 | Apple II | LinApple **(Standalone)** [U],
Mednafen **(Standalone)** [M],
AppleWin **(Standalone)** [W] | Mednafen **(Standalone)** [UW],
MAME - Current,
MAME **(Standalone)** | Yes for Mednafen and MAME | See the specific _Apple II_ section elsewhere in this guide | +| apple2 | Apple II | LinApple **(Standalone)** [L],
Mednafen **(Standalone)** [M],
AppleWin **(Standalone)** [W] | Mednafen **(Standalone)** [LW],
MAME - Current,
MAME **(Standalone)** | Yes for Mednafen and MAME | See the specific _Apple II_ section elsewhere in this guide | | apple2gs | Apple IIGS | MAME - Current | MAME **(Standalone)** | Yes | See the specific _Apple IIGS_ section elsewhere in this guide | -| arcade | Arcade | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [UW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| arcade | Arcade | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [LW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | arcadia | Emerson Arcadia 2001 | MAME - Current | MAME **(Standalone)** | No | Single archive or ROM file | | archimedes | Acorn Archimedes | MAME [Model A440/1] **(Standalone)** | MAME [Model A3000] **(Standalone)**,
MAME [Model A310] **(Standalone)**,
MAME [Model A540] **(Standalone)** | Yes | | | arduboy | Arduboy Miniature Game System | Arduous | | No | Single archive or .hex file | | astrocde | Bally Astrocade | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| atari2600 | Atari 2600 | Stella | Stella 2014,
Stella **(Standalone)**,
Gopher2600 **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | +| atari2600 | Atari 2600 | Stella | Stella 2014,
Stella **(Standalone)**,
Gopher2600 **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | atari5200 | Atari 5200 | a5200 | Atari800,
Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | Single archive or ROM file | | atari7800 | Atari 7800 ProSystem | ProSystem | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | atari800 | Atari 800 | Atari800 | Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | | -| atarijaguar | Atari Jaguar | Virtual Jaguar | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [U],
BigPEmu **(Proton)** [U],
MAME **(Standalone)** | Yes for MAME | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | -| atarijaguarcd | Atari Jaguar CD | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [U] | BigPEmu **(Proton)** [U] | No | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | -| atarilynx | Atari Lynx | Handy | Beetle Lynx,
Mednafen **(Standalone)** | | | +| atarijaguar | Atari Jaguar | Virtual Jaguar | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [L],
BigPEmu **(Proton)** [L],
MAME **(Standalone)** | Yes for MAME | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | +| atarijaguarcd | Atari Jaguar CD | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [L] | BigPEmu **(Proton)** [L] | No | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | +| atarilynx | Atari Lynx | Handy | Beetle Lynx,
Mednafen **(Standalone)** | No | Single archive or ROM file | | atarist | Atari ST [also STE and Falcon] | Hatari | Hatari **(Standalone)** | Yes | Single archive or image file for single-diskette games, .m3u playlist for multi-diskette games | | atarixe | Atari XE | Atari800 | Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | | | atomiswave | Sammy Corporation Atomiswave | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Depends | Single archive file | | bbcmicro | Acorn Computers BBC Micro | MAME **(Standalone)** | | Yes | Single archive or diskette image file | | c64 | Commodore 64 | VICE x64sc Accurate | VICE x64sc Accurate **(Standalone)**,
VICE x64 Fast,
VICE x64 SuperCPU,
VICE x128,
Frodo | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | | cdimono1 | Philips CD-i | SAME CDi | CDi 2015 @,
MAME **(Standalone)** | Yes | Single .bin/.cue pair | -| cdtv | Commodore CDTV | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| cdtv | Commodore CDTV | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | | chailove | ChaiLove Game Engine | ChaiLove | | | | | channelf | Fairchild Channel F | FreeChaF | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | coco | Tandy Color Computer | XRoar CoCo 2 NTSC **(Standalone)** | XRoar CoCo 2 PAL **(Standalone)** | Yes | See the specific _Tandy Color Computer_ section elsewhere in this guide | | colecovision | Coleco ColecoVision | blueMSX | Gearcoleco,
openMSX **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | -| consolearcade | Console Arcade Systems | MAME - Current | MAME **(Standalone)**,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Mednafen [Sega Saturn] **(Standalone)**,
Play! **(Standalone)**,
RPCS3 Shortcut **(Standalone)**,
Triforce **(Standalone)** [UW],
xemu **(Standalone)**,
Cxbx-Reloaded **(Standalone)** [W],
_Shortcut or script_ | Depends | See the specific _Console Arcade Systems_ section elsewhere in this guide | -| cps | Capcom Play System | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps1 | Capcom Play System I | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-1 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps2 | Capcom Play System II | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-2 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps3 | Capcom Play System III | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| consolearcade | Console Arcade Systems | MAME - Current | MAME **(Standalone)**,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Mednafen [Sega Saturn] **(Standalone)**,
Play! **(Standalone)**,
RPCS3 Shortcut **(Standalone)**,
Triforce **(Standalone)** [LW],
xemu **(Standalone)**,
Cxbx-Reloaded **(Standalone)** [W],
_Shortcut or script_ | Depends | See the specific _Console Arcade Systems_ section elsewhere in this guide | +| cps | Capcom Play System | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps1 | Capcom Play System I | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-1 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps2 | Capcom Play System II | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-2 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps3 | Capcom Play System III | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | crvision | VTech CreatiVision | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | daphne | Daphne Arcade LaserDisc Emulator | Hypseus [Daphne] **(Standalone)** | Hypseus [Singe] **(Standalone)**,
MAME - Current,
MAME **(Standalone)**,
DirkSimple | Depends | See the specific _LaserDisc Games_ section elsewhere in this guide | -| desktop | Desktop Applications | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | -| doom | Doom | PrBoom | PrBoom+ **(Standalone)**,
Boom 3 [UW],
Boom 3 xp [UW],
_Shortcut or script_ | No | | +| desktop | Desktop Applications | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| doom | Doom | PrBoom | PrBoom+ **(Standalone)**,
Boom 3 [LW],
Boom 3 xp [LW],
_Shortcut or script_ | No | | | dos | DOS (PC) | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN,
DOSBox-X **(Standalone)**,
DOSBox Staging **(Standalone)** | No | See the specific _DOS / PC_ section elsewhere in this guide | | dragon32 | Dragon Data Dragon 32 | XRoar Dragon 32 **(Standalone)** | XRoar Dragon 64 **(Standalone)** | Yes | See the specific _Dragon 32 and Tano Dragon_ section elsewhere in this guide | | dreamcast | Sega Dreamcast | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Redream **(Standalone)**,
Demul **(Standalone)** [W] | No | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | | easyrpg | EasyRPG Game Engine | EasyRPG | EasyRPG Player **(Standalone)** | No | See the specific _EasyRPG Game Engine_ section elsewhere in this guide | | electron | Acorn Electron | MAME [Tape] **(Standalone)** | MAME [Diskette DFS] **(Standalone)**,
MAME [Diskette ADFS] **(Standalone)** | Yes | Single archive, or single tape or diskette image file | -| emulators | Emulators | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| emulators | Emulators | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | | epic | Epic Games Store | Epic Games Store **(Standalone)** | | No | Shortcut (.desktop/.app/.lnk) file | -| famicom | Nintendo Family Computer | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
QuickNES,
puNES **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [U],
3dSen **(Proton)** [U],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For Famicom games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | +| famicom | Nintendo Family Computer | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
QuickNES,
puNES **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [L],
3dSen **(Proton)** [L],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For Famicom games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | | fba | FinalBurn Alpha | FB Alpha 2012 | FB Alpha 2012 Neo Geo,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| fbneo | FinalBurn Neo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [UW] | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| fds | Nintendo Famicom Disk System | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
Mednafen **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | -| flash | Adobe Flash | Ruffle **(Standalone)** | Lightspark **(Standalone)** [U],
ArcadeFlashWeb **(Standalone)** [W] | No | Single .swf file | +| fbneo | FinalBurn Neo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [LW] | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| fds | Nintendo Famicom Disk System | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
Mednafen **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | +| flash | Adobe Flash | Ruffle **(Standalone)** | Lightspark **(Standalone)** [L],
ArcadeFlashWeb **(Standalone)** [W] | No | Single .swf file | | fm7 | Fujitsu FM-7 | MAME [FM-7 Diskette] **(Standalone)** | MAME [FM-7 Tape] **(Standalone)**,
MAME [FM-7 Software list] **(Standalone)**,
MAME [FM77AV Diskette] **(Standalone)**,
MAME [FM77AV Tape] **(Standalone)**,
MAME [FM77AV Software list] **(Standalone)** | Yes | For tape files you need to manually start the cassette player from the MAME menu after the "load" command, as well as entering the "run" command after loading is complete | -| fmtowns | Fujitsu FM Towns | MAME - Current,
MAME **(Standalone)** | Tsugaru **(Standalone)** [UW] | Yes | See the specific _Fujitsu FM Towns_ section elsewhere in this guide | +| fmtowns | Fujitsu FM Towns | MAME - Current,
MAME **(Standalone)** | Tsugaru **(Standalone)** [LW] | Yes | See the specific _Fujitsu FM Towns_ section elsewhere in this guide | | fpinball | Future Pinball | Future Pinball **(Standalone)** [W] | | No | | | gamate | Bit Corporation Gamate | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| gameandwatch | Nintendo Game and Watch | MAME Local Artwork **(Standalone)** | MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | +| gameandwatch | Nintendo Game and Watch | MAME - Current | MAME Local Artwork **(Standalone)**,
MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | | gamecom | Tiger Electronics Game.com | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| gamegear | Sega Game Gear | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
SMS Plus GX,
PicoDrive,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| gb | Nintendo Game Boy | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [UW],
TGB Dual,
Mesen-S,
Mesen **(Standalone)** [UW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| gba | Nintendo Game Boy Advance | mGBA | mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
VBA Next,
gpSP,
ares **(Standalone)**,
SkyEmu **(Standalone)** | Yes for ares | Single archive or ROM file | -| gbc | Nintendo Game Boy Color | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [UW],
TGB Dual,
Mesen-S,
Mesen **(Standalone)** [UW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| gc | Nintendo GameCube | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [UW],
Triforce **(Standalone)** [UW] | No | Disc image file for single-disc games, .m3u playlist for multi-disc games | -| genesis | Sega Genesis | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| gamegear | Sega Game Gear | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
SMS Plus GX,
PicoDrive,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| gb | Nintendo Game Boy | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [LW],
TGB Dual,
DoubleCherryGB [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| gba | Nintendo Game Boy Advance | mGBA | mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
VBA Next,
gpSP,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | Yes for ares | Single archive or ROM file | +| gbc | Nintendo Game Boy Color | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [LW],
TGB Dual,
DoubleCherryGB [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| gc | Nintendo GameCube | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [LW],
Triforce **(Standalone)** [LW] | No | Disc image file for single-disc games, .m3u playlist for multi-disc games | +| genesis | Sega Genesis | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | gmaster | Hartung Game Master | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | gx4000 | Amstrad GX4000 | Caprice32 | CrocoDS,
MAME **(Standalone)** | No | Single archive or ROM file | | intellivision | Mattel Electronics Intellivision | FreeIntv | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | j2me | Java 2 Micro Edition (J2ME) | SquirrelJME | KEmulator **(Standalone)** [W] | No | Single .jar file | | kodi | Kodi Home Theatre Software | Kodi **(Standalone)** | | No | Shortcut (.desktop/.app/.lnk) file | | laserdisc | LaserDisc Games | Hypseus [Daphne] **(Standalone)** | Hypseus [Singe] **(Standalone)**,
MAME - Current,
MAME **(Standalone)**,
DirkSimple | Depends | See the specific _LaserDisc Games_ section elsewhere in this guide | -| lcdgames | LCD Handheld Games | MAME Local Artwork **(Standalone)** | MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | +| lcdgames | LCD Handheld Games | MAME - Current | MAME Local Artwork **(Standalone)**,
MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | | lowresnx | LowRes NX Fantasy Console | LowRes NX | | No | Single ROM file | -| lutris | Lutris Open Gaming Platform | Lutris **(Standalone)** [U] | | No | See the specific _Lutris_ section elsewhere in this guide | +| lutris | Lutris Open Gaming Platform | Lutris **(Standalone)** [L] | | No | See the specific _Lutris_ section elsewhere in this guide | | lutro | Lutro Game Engine | Lutro | | | | | macintosh | Apple Macintosh | MAME Mac SE Bootable **(Standalone)** | MAME Mac SE Boot Disk **(Standalone)**,
MAME Mac Plus Bootable **(Standalone)**,
MAME Mac Plus Boot Disk **(Standalone)**,
Basilisk II **(Standalone)**,
SheepShaver **(Standalone)** | Yes | See the specific _Apple Macintosh_ section elsewhere in this guide | -| mame | Multiple Arcade Machine Emulator | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [UW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| mame-advmame | AdvanceMAME | AdvanceMAME **(Standalone)** [UW] | | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| mastersystem | Sega Master System | Genesis Plus GX | Genesis Plus GX Wide,
SMS Plus GX,
Gearsystem,
PicoDrive,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| mame | Multiple Arcade Machine Emulator | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [LW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| mame-advmame | AdvanceMAME | AdvanceMAME **(Standalone)** [LW] | | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| mastersystem | Sega Master System | Genesis Plus GX | Genesis Plus GX Wide,
SMS Plus GX,
Gearsystem,
PicoDrive,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | megacd | Sega Mega-CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | | megacdjp | Sega Mega-CD [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | -| megadrive | Sega Mega Drive | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| megadrivejp | Sega Mega Drive [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| megadrive | Sega Mega Drive | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| megadrivejp | Sega Mega Drive [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | megaduck | Creatronic Mega Duck | SameDuck | MAME - Current,
MAME **(Standalone)** | No | Single archive or ROM file | | mess | Multi Emulator Super System | MESS 2015 | | | | -| model2 | Sega Model 2 | Model 2 Emulator **(Standalone)** [W],
MAME - Current [UM] | Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
MAME - Current [W],
MAME **(Standalone)**,
Model 2 Emulator **(Wine)** [U],
Model 2 Emulator **(Proton)** [U] | Yes for MAME | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| model3 | Sega Model 3 | Supermodel **(Standalone)** [UW] | | No | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| model2 | Sega Model 2 | Model 2 Emulator **(Standalone)** [W],
MAME - Current [LM] | Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
MAME - Current [W],
MAME **(Standalone)**,
Model 2 Emulator **(Wine)** [L],
Model 2 Emulator **(Proton)** [L] | Yes for MAME | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| model3 | Sega Model 3 | Supermodel **(Standalone)** [LW] | | No | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | moto | Thomson MO/TO Series | Theodore | | | | | msx | MSX | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msx1 | MSX1 | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msx2 | MSX2 | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msxturbor | MSX Turbo R | blueMSX | openMSX **(Standalone)**,
openMSX No Machine **(Standalone)** | Yes | | | mugen | M.U.G.E.N Game Engine | Ikemen GO **(Standalone)** | | No | See the specific _M.U.G.E.N Game Engine_ section elsewhere in this guide | -| multivision | Othello Multivision | Gearsystem | | | | +| multivision | Othello Multivision | Gearsystem | Mesen **(Standalone)** [LW] | No | Single archive or ROM file | | naomi | Sega NAOMI | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | | naomi2 | Sega NAOMI 2 | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | | naomigd | Sega NAOMI GD-ROM | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)** | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | -| n3ds | Nintendo 3DS | Citra [UW],
Citra **(Standalone)** [M] | Citra 2018 [UW],
Citra **(Standalone)** [UW] | No | Single ROM file | -| n64 | Nintendo 64 | Mupen64Plus-Next | Mupen64Plus **(Standalone)**,
ParaLLEl N64,
simple64 **(Standalone)** [UW],
Rosalie's Mupen GUI **(Standalone)** [UW],
Project64 **(Standalone)** [W],
ares **(Standalone)**,
sixtyforce **(Standalone)** [M] | No | Single archive or ROM file | -| n64dd | Nintendo 64DD | ParaLLEl N64 [UW],
Mupen64Plus-Next [M] | Mupen64Plus-Next [UW],
ParaLLEl N64 [M],
Rosalie's Mupen GUI **(Standalone)** [UW],
ares **(Standalone)** | Yes | See the specific _Nintendo 64DD_ section elsewhere in this guide | -| nds | Nintendo DS | DeSmuME | DeSmuME 2015,
DeSmuME **(Standalone)** [U],
melonDS,
melonDS **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| neogeo | SNK Neo Geo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [UW],
MAME **(Standalone)** | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| neogeocd | SNK Neo Geo CD | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [U],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | -| neogeocdjp | SNK Neo Geo CD [Japan] | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [U],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | -| nes | Nintendo Entertainment System | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
QuickNES,
puNES **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [U],
3dSen **(Proton)** [U],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For NES games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | -| ngage | Nokia N-Gage | EKA2L1 [Mounted] **(Standalone)** | EKA2L1 [Installed] **(Standalone)**,
EKA2L1 [Mounted] **(Wine)** [U],
EKA2L1 [Installed] **(Wine)** [U] | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | -| ngp | SNK Neo Geo Pocket | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | | | -| ngpc | SNK Neo Geo Pocket Color | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | | | +| n3ds | Nintendo 3DS | Citra [LW],
Citra **(Standalone)** [M] | Citra 2018 [LW],
Citra **(Standalone)** [LW] | No | Single ROM file | +| n64 | Nintendo 64 | Mupen64Plus-Next | Mupen64Plus **(Standalone)**,
ParaLLEl N64,
simple64 **(Standalone)** [LW],
Rosalie's Mupen GUI **(Standalone)** [LW],
Project64 **(Standalone)** [W],
ares **(Standalone)**,
sixtyforce **(Standalone)** [M] | No | Single archive or ROM file | +| n64dd | Nintendo 64DD | ParaLLEl N64 [LW],
Mupen64Plus-Next [M] | Mupen64Plus-Next [LW],
ParaLLEl N64 [M],
Rosalie's Mupen GUI **(Standalone)** [LW],
ares **(Standalone)** | Yes | See the specific _Nintendo 64DD_ section elsewhere in this guide | +| nds | Nintendo DS | melonDS DS | melonDS @,
melonDS **(Standalone)**,
DeSmuME,
DeSmuME 2015,
DeSmuME **(Standalone)** [L],
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| neogeo | SNK Neo Geo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [LW],
MAME **(Standalone)** | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| neogeocd | SNK Neo Geo CD | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [L],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | +| neogeocdjp | SNK Neo Geo CD [Japan] | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [L],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | +| nes | Nintendo Entertainment System | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
QuickNES,
puNES **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [L],
3dSen **(Proton)** [L],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For NES games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | +| ngage | Nokia N-Gage | EKA2L1 [Mounted] **(Standalone)** | EKA2L1 [Installed] **(Standalone)**,
EKA2L1 [Mounted] **(Wine)** [L],
EKA2L1 [Installed] **(Wine)** [L] | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | +| ngp | SNK Neo Geo Pocket | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| ngpc | SNK Neo Geo Pocket Color | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | odyssey2 | Magnavox Odyssey 2 | O2EM | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | -| openbor | OpenBOR Game Engine | OpenBOR **(Standalone)** [UW] | | No | See the specific _OpenBOR_ section elsewhere in this guide | -| oric | Tangerine Computer Systems Oric | Oricutron **(Standalone)** [UW] | | | See the specific _Tangerine Computer Systems Oric_ section elsewhere in this guide | +| openbor | OpenBOR Game Engine | OpenBOR **(Standalone)** [LW] | | No | See the specific _OpenBOR_ section elsewhere in this guide | +| oric | Tangerine Computer Systems Oric | Oricutron **(Standalone)** [LW] | | | See the specific _Tangerine Computer Systems Oric_ section elsewhere in this guide | | palm | Palm OS | Mu | | | | | pc | IBM PC | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN,
DOSBox-X **(Standalone)**,
DOSBox Staging **(Standalone)** | No | See the specific _DOS / PC_ section elsewhere in this guide | | pc88 | NEC PC-8800 Series | QUASI88 | QUASI88 **(Standalone)** | Yes | | | pc98 | NEC PC-9800 Series | Neko Project II Kai | Neko Project II | | | -| pcarcade | PC Arcade Systems | Wine **(Standalone)** [U],
_Shortcut or script_ [MW] | Proton **(Standalone)** [U],
_AppImage_ [U],
_Shortcut or script_ [U] | No | | -| pcengine | NEC PC Engine | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | -| pcenginecd | NEC PC Engine CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | Yes | | +| pcarcade | PC Arcade Systems | Wine **(Standalone)** [L],
_Shortcut or script_ [MW] | Proton **(Standalone)** [L],
_AppImage_ [L],
_Shortcut or script_ [L] | No | | +| pcengine | NEC PC Engine | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| pcenginecd | NEC PC Engine CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | Yes | | | pcfx | NEC PC-FX | Beetle PC-FX | Mednafen **(Standalone)** | Yes | | | pico8 | PICO-8 Fantasy Console | PICO-8 **(Standalone)** | PICO-8 Splore **(Standalone)**,
Retro8 | No | See the specific _PICO-8_ section elsewhere in this guide | | plus4 | Commodore Plus/4 | VICE xplus4 | VICE xplus4 **(Standalone)** | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | | pokemini | Nintendo Pokémon Mini | PokeMini | | No | | -| ports | Ports | _Shortcut or script_ | _AppImage_ [U],
ECWolf (Wolfenstein 3D),
NXEngine (Cave Story),
OpenLara (Tomb Raider) [UW],
Super Bros War | Yes for ECWolf | See the specific _Ports and desktop applications_ section elsewhere in this guide | -| ps2 | Sony PlayStation 2 | LRPS2 [UW],
PCSX2 **(Standalone)** [M] | PCSX2 [UW] @,
PCSX2 **(Standalone)** [UW],
PCSX2 Legacy **(Standalone)** @,
Play! **(Standalone)**,
AetherSX2 **(Standalone)** [M] | Yes except for Play! | | +| ports | Ports | _Shortcut or script_ | _AppImage_ [L],
ECWolf (Wolfenstein 3D),
NXEngine (Cave Story),
OpenLara (Tomb Raider) [LW],
Super Bros War | Yes for ECWolf | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| ps2 | Sony PlayStation 2 | LRPS2 [LW],
PCSX2 **(Standalone)** [M] | PCSX2 [LW] @,
PCSX2 **(Standalone)** [LW],
PCSX2 Legacy **(Standalone)** @,
Play! **(Standalone)**,
AetherSX2 **(Standalone)** [M] | Yes except for Play! | | | ps3 | Sony PlayStation 3 | RPCS3 Shortcut **(Standalone)** | RPCS3 Directory **(Standalone)** | Yes | See the specific _Sony PlayStation 3_ section elsewhere in this guide | | ps4 | Sony PlayStation 4 | _Placeholder_ | | | | | psp | Sony PlayStation Portable | PPSSPP | PPSSPP **(Standalone)** | No | Single disc image file | -| psvita | Sony PlayStation Vita | Vita3K **(Standalone)** [UW] | | Yes | See the specific _Sony PlayStation Vita_ section elsewhere in this guide | +| psvita | Sony PlayStation Vita | Vita3K **(Standalone)** [LW] | | Yes | See the specific _Sony PlayStation Vita_ section elsewhere in this guide | | psx | Sony PlayStation | Beetle PSX | Beetle PSX HW,
PCSX ReARMed,
SwanStation,
DuckStation **(Standalone)**,
Mednafen **(Standalone)** | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | | pv1000 | Casio PV-1000 | MAME - Current | MAME **(Standalone)** | No | Single archive or ROM file | -| quake | Quake | TyrQuake | vitaQuake 2,
vitaQuake 2 [Rogue],
vitaQuake 2 [Xatrix],
vitaQuake 2 [Zaero],
vitaQuake 3 [UW],
_Shortcut or script_ | No | | +| quake | Quake | TyrQuake | vitaQuake 2,
vitaQuake 2 [Rogue],
vitaQuake 2 [Xatrix],
vitaQuake 2 [Zaero],
vitaQuake 3 [LW],
_Shortcut or script_ | No | | | samcoupe | MGT SAM Coupé | SimCoupé **(Standalone)** | | No | Single archive or ROM file | -| satellaview | Nintendo Satellaview | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | | | -| saturn | Sega Saturn | Beetle Saturn | Kronos [UW],
YabaSanshiro [UW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | -| saturnjp | Sega Saturn [Japan] | Beetle Saturn | Kronos [UW],
YabaSanshiro [UW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | +| satellaview | Nintendo Satellaview | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | | | +| saturn | Sega Saturn | Beetle Saturn | Kronos [LW],
YabaSanshiro [LW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | +| saturnjp | Sega Saturn [Japan] | Beetle Saturn | Kronos [LW],
YabaSanshiro [LW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | | scummvm | ScummVM Game Engine | ScummVM | ScummVM **(Standalone)** | No | See the specific _ScummVM_ section elsewhere in this guide | | scv | Epoch Super Cassette Vision | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | sega32x | Sega Mega Drive 32X | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | sega32xjp | Sega Super 32X [Japan] | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | sega32xna | Sega Genesis 32X [North America] | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | segacd | Sega CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | -| sfc | Nintendo SFC (Super Famicom) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| sg-1000 | Sega SG-1000 | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
blueMSX,
ares **(Standalone)** | No | | -| sgb | Nintendo Super Game Boy | Mesen-S | Mesen **(Standalone)** [UW],
SameBoy,
mGBA,
mGBA **(Standalone)** | | Single archive or ROM file | -| snes | Nintendo SNES (Super Nintendo) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| snesna | Nintendo SNES (Super Nintendo) [North America] | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| sfc | Nintendo SFC (Super Famicom) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| sg-1000 | Sega SG-1000 | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
blueMSX,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| sgb | Nintendo Super Game Boy | Mesen-S | Mesen **(Standalone)** [LW],
SameBoy,
mGBA,
mGBA **(Standalone)** | | Single archive or ROM file | +| snes | Nintendo SNES (Super Nintendo) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| snesna | Nintendo SNES (Super Nintendo) [North America] | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | solarus | Solarus Game Engine | Solarus **(Standalone)** | | No | Single .solarus game file | | spectravideo | Spectravideo | blueMSX | | | | | steam | Valve Steam | Steam **(Standalone)** | | No | See the specific _Steam_ section elsewhere in this guide | -| stv | Sega Titan Video Game System | Kronos [UW],
MAME - Current [M] | MAME - Current [UW],
MAME **(Standalone)**,
Mednafen **(Standalone)** | Yes | Single archive file | -| sufami | Bandai SuFami Turbo | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
ares **(Standalone)** | | | -| supergrafx | NEC SuperGrafx | Beetle SuperGrafx | Beetle PCE,
ares **(Standalone)** | | | +| stv | Sega Titan Video Game System | Kronos [LW],
MAME - Current [M] | MAME - Current [LW],
MAME **(Standalone)**,
Mednafen **(Standalone)** | Yes | Single archive file | +| sufami | Bandai SuFami Turbo | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
ares **(Standalone)** | | | +| supergrafx | NEC SuperGrafx | Beetle SuperGrafx | Beetle PCE,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | supervision | Watara Supervision | Potator | MAME - Current,
MAME **(Standalone)** | No | Single archive or ROM file | | supracan | Funtech Super A'Can | MAME - Current | MAME **(Standalone)** | Yes/No | Single archive or ROM file. To make MAME start these games create an empty file named internal_68k.bin and zip it into supracan.zip | -| switch | Nintendo Switch | Yuzu **(Standalone)** [UW],
Ryujinx **(Standalone)** [M] | Ryujinx **(Standalone)** [UW] | Yes | | +| switch | Nintendo Switch | Yuzu **(Standalone)** [LW],
Ryujinx **(Standalone)** [M] | Ryujinx **(Standalone)** [LW] | Yes | | | symbian | Symbian | EKA2L1 [Nokia N-Gage] **(Standalone)** | EKA2L1 [Nokia N70] **(Standalone)**,
EKA2L1 [Nokia N97] **(Standalone)**,
EKA2L1 [Custom device] **(Standalone)** | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | | tanodragon | Tano Dragon | XRoar **(Standalone)** | | Yes | See the specific _Dragon 32 and Tano Dragon_ section elsewhere in this guide | -| tg16 | NEC TurboGrafx-16 | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | -| tg-cd | NEC TurboGrafx-CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | Yes | | +| tg16 | NEC TurboGrafx-16 | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| tg-cd | NEC TurboGrafx-CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | Yes | | | ti99 | Texas Instruments TI-99 | MAME **(Standalone)** | | Yes | See the specific _Texas Instruments TI-99_ section elsewhere in this guide | | tic80 | TIC-80 Fantasy Computer | TIC-80 | TIC-80 **(Standalone)** | No | Single .tic file | | to8 | Thomson TO8 | Theodore | | | | -| triforce | Namco-Sega-Nintendo Triforce | Triforce **(Standalone)** [UW] | | No | | -| trs-80 | Tandy TRS-80 | sdl2trs DOS Diskette **(Standalone)** [UW] | sdl2trs Bootable Diskette **(Standalone)** [UW],
sdl2trs CMD File **(Standalone)** [UW] | Yes | See the specific _Tandy TRS-80_ section elsewhere in this guide | -| type-x | Taito Type X | Wine **(Standalone)** [U],
_Shortcut or script_ [MW] | Proton **(Standalone)** [U],
_AppImage_ [U],
_Shortcut or script_ [U] | No | | +| triforce | Namco-Sega-Nintendo Triforce | Triforce **(Standalone)** [LW] | | No | | +| trs-80 | Tandy TRS-80 | sdl2trs DOS Diskette **(Standalone)** [LW] | sdl2trs Bootable Diskette **(Standalone)** [LW],
sdl2trs CMD File **(Standalone)** [LW] | Yes | See the specific _Tandy TRS-80_ section elsewhere in this guide | +| type-x | Taito Type X | Wine **(Standalone)** [L],
_Shortcut or script_ [MW] | Proton **(Standalone)** [L],
_AppImage_ [L],
_Shortcut or script_ [L] | No | | | uzebox | Uzebox Open Source Console | Uzem | | | | | vectrex | GCE Vectrex | vecx | MAME - Current,
MAME **(Standalone)** | Yes for MAME | Single archive or ROM file | | vic20 | Commodore VIC-20 | VICE xvic | VICE xvic **(Standalone)** | No | Single archive or tape, cartridge or diskette image file | | videopac | Philips Videopac G7000 | O2EM | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | | virtualboy | Nintendo Virtual Boy | Beetle VB | Mednafen **(Standalone)** | No | | -| vpinball | Visual Pinball | Visual Pinball **(Standalone)** [UW] | | No | In separate folder interpreted as a file | +| vpinball | Visual Pinball | Visual Pinball **(Standalone)** | | No | See the specific _Visual Pinball_ section elsewhere in this guide | | vsmile | VTech V.Smile | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | wasm4 | WASM-4 Fantasy Console | WASM-4 | | No | Single .wasm file | -| wii | Nintendo Wii | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [UW] | No | | +| wii | Nintendo Wii | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [LW] | No | | | wiiu | Nintendo Wii U | Cemu **(Standalone)** | | No | See the specific _Nintendo Wii U_ section elsewhere in this guide | -| windows | Microsoft Windows | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | Shortcut (.desktop/.app/.lnk) file, script or AppImage | -| windows3x | Microsoft Windows 3.x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | -| windows9x | Microsoft Windows 9x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | +| windows | Microsoft Windows | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | Shortcut (.desktop/.app/.lnk) file, script or AppImage | +| windows3x | Microsoft Windows 3.x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | +| windows9x | Microsoft Windows 9x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | | wonderswan | Bandai WonderSwan | Beetle Cygne | Mednafen **(Standalone)**,
ares **(Standalone)**,
ares [Benesse Pocket Challenge V2] **(Standalone)** | No | Single archive or ROM file | | wonderswancolor | Bandai WonderSwan Color | Beetle Cygne | Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | x1 | Sharp X1 | X Millennium | MAME [Diskette] **(Standalone)**,
MAME [Tape] **(Standalone)** | Yes for MAME | Single archive or diskette/tape file | | x68000 | Sharp X68000 | PX68k | MAME **(Standalone)** | Yes | | | xbox | Microsoft Xbox | xemu **(Standalone)** | Cxbx-Reloaded **(Standalone)** [W] | Yes for xemu | Single .iso file for xemu or unpacked .iso directory for Cxbx-Reloaded | -| xbox360 | Microsoft Xbox 360 | xenia **(Standalone)** [W],
xenia **(Wine)** [U] | xenia **(Proton)** [U],
_Shortcut or script_ [U] | No | See the specific _Microsoft Xbox 360_ section elsewhere in this guide | +| xbox360 | Microsoft Xbox 360 | xenia **(Standalone)** [W],
xenia **(Wine)** [L] | xenia **(Proton)** [L],
_Shortcut or script_ [L] | No | See the specific _Microsoft Xbox 360_ section elsewhere in this guide | | zmachine | Infocom Z-machine | Gargoyle **(Standalone)** | | No | | | zx81 | Sinclair ZX81 | EightyOne | | | | -| zxnext | Sinclair ZX Spectrum Next | #CSpect **(Standalone)** [UW],
ZEsarUX **(Standalone)** [M] | ZEsarUX **(Standalone)** [UW] | No | In separate folder interpreted as a file | -| zxspectrum | Sinclair ZX Spectrum | Fuse | Fuse **(Standalone)** | No | | +| zxnext | Sinclair ZX Spectrum Next | #CSpect **(Standalone)** [LW],
ZEsarUX **(Standalone)** [M] | ZEsarUX **(Standalone)** [LW] | No | In separate folder interpreted as a file | +| zxspectrum | Sinclair ZX Spectrum | Fuse | Fuse **(Standalone)** | No | Single archive or ROM file | diff --git a/USERGUIDE.md b/USERGUIDE.md index 983e45050..deb4a9e09 100644 --- a/USERGUIDE.md +++ b/USERGUIDE.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) v2.2 - User guide +# ES-DE (EmulationStation Desktop Edition) v3.0 - User guide It's generally recommended to read the [Frequently Asked Questions (FAQ)](FAQ.md) document prior to diving into the information in this guide. @@ -36,12 +36,12 @@ The installation procedure is just covered briefly here and may differ a bit for The AppImage release should be usable on most modern x86 64-bit Linux distributions. After download you may have to set the file as executable, such as this: ``` -chmod +x EmulationStation-DE-x64.AppImage +chmod +x ES-DE_x64.AppImage ``` Or if you're using the Steam Deck AppImage: ``` -chmod +x EmulationStation-DE-x64_SteamDeck.AppImage +chmod +x ES-DE_x64_SteamDeck.AppImage ``` To run AppImage files you need libfuse2 installed, but some newer distributions like Ubuntu 22.04 LTS no longer ship with this library preinstalled. You can however easily install it like this: @@ -57,11 +57,11 @@ There's not really much to say about these operating systems, just install ES-DE **On first application startup** -Upon first startup, ES-DE will create its `~/.emulationstation` home directory. +Upon first startup, ES-DE will create its `~/ES-DE` application data directory. -On Unix this means `/home//.emulationstation`, on macOS `/Users//.emulationstation` and on Windows `C:\Users\\.emulationstation` or `EmulationStation-DE\.emulationstation` depending on whether the installer release or the portable release is used. +On Linux this means `/home//ES-DE`, on macOS `/Users//ES-DE` and on Windows `C:\Users\\ES-DE` or `ES-DE\ES-DE` depending on whether the installer release or the portable release is used. -Also on first startup the configuration file `es_settings.xml` will be generated in the ES-DE home directory, containing all the application settings at their default values. Following this, a file named `es_systems.xml` will be loaded from the resources directory (which is part of the ES-DE installation). This file contains the game system definitions including which emulator to use per platform. For many systems there are also alternative emulators defined which can be applied system-wide or per game. How that works is explained later in this guide. A customized systems configuration file can also be used, as described in the next section below. +Also on first startup the configuration file `es_settings.xml` will be generated in the `ES-DE/settings` directory, containing all the application settings at their default values. Following this, a file named `es_systems.xml` will be loaded from the resources directory (which is part of the ES-DE installation). This file contains the game system definitions including which emulator to use per platform. For many systems there are also alternative emulators defined which can be applied system-wide or per game. How that works is explained later in this guide. A customized systems configuration file can also be used, as described in the next section below. In addition to es_systems.xml there's an `es_find_rules.xml` file that gets loaded as well and which contains rules on how to locate the emulators, i.e. how to find out where they've been installed. @@ -69,7 +69,7 @@ There's an application log file created in the ES-DE home directory named `es_lo After ES-DE finds at least one game file, it will populate that game system and the application will start. If there are no game files, a dialog will be shown explaining that you need to install your game files into your ROM directory. You will also be given a choice to change that ROM directory path if you don't want to use the default one. As well you have the option to generate the complete game systems directory structure based on information in es_systems.xml. -When generating the directory structure, a file named systeminfo.txt will be created in each game system folder which will provide you with some information about the system. Here's an example for the _dos_ system as seen on Unix: +When generating the directory structure, a file named systeminfo.txt will be created in each game system folder which will provide you with some information about the system. Here's an example for the _dos_ system as seen on Linux: ``` System name: dos @@ -111,18 +111,18 @@ epic: Epic Games Store famicom: Nintendo Family Computer ``` -If a custom es_systems.xml file is present in ~/.emulationstation/custom_systems/ any entries from this file will have their names trailed by the text _(custom system)_. So if the _dos_ system in the example above would be present in the custom systems configuration file, the system would be shown as _dos (custom system)_ instead of simply _dos_. This is only applicable for the systems.txt and systeminfo.txt files, the trailing text is not applied or used anywhere else in the application. +If a custom es_systems.xml file is present in ~/ES-DE/custom_systems/ any entries from this file will have their names trailed by the text _(custom system)_. So if the _dos_ system in the example above would be present in the custom systems configuration file, the system would be shown as _dos (custom system)_ instead of simply _dos_. This is only applicable for the systems.txt and systeminfo.txt files, the trailing text is not applied or used anywhere else in the application. ![alt text](images/es-de_ui_easy_setup.png "ES-DE Easy Setup") _This is the dialog shown if no game files were found. It lets you configure the ROM directory if you don't want to use the default one, and you can also generate the game systems directory structure. Note that the directory is the physical path, and that your operating system may present this as a localized path if you are using a language other than English._ ## Upgrading to a newer release -**Note:** Before upgrading ES-DE, make sure that you have not made any system customizations anywhere in the installation directory structure as these files will be overwritten during the upgrade process. All customizations should go into ~/.emulationstation/custom_systems/ as described elsewhere in this guide. None of the upgrade methods mentioned below will ever touch any files inside your .emulationstation directory tree. +**Note:** Before upgrading ES-DE, make sure that you have not made any system customizations anywhere in the installation directory structure as these files will be overwritten during the upgrade process. All customizations should go into ~/ES-DE/custom_systems/ as described elsewhere in this guide. None of the upgrade methods mentioned below will ever touch any files inside your ES-DE directory tree. -There is a built-in application updater that can automatically update the Linux AppImage releases, and as of ES-DE 2.2.0 there is also support for downloading the Windows and macOS packages. Just be aware that these will still need to be manually installed. Using the application updater is straightforward, just follow the on-screen instructions. For the AppImage releases the old file is retained by renaming it, adding its version to the filename followed by the .OLD extension, for example `EmulationStation-DE-x64_SteamDeck.AppImage_2.1.0.OLD` +There is a built-in application updater that can automatically update the Linux AppImage releases, and as of ES-DE 2.2.0 there is also support for downloading the Windows and macOS packages. Just be aware that these will still need to be manually installed. Using the application updater is straightforward, just follow the on-screen instructions. For the AppImage releases the old file is retained by renaming it, adding its version to the filename followed by the .OLD extension, for example `ES-DE_x64_SteamDeck.AppImage_3.0.0.OLD` -Note that the updater will keep whatever filename you had for your running AppImage file, which could potentially be confusing if you for example added version information to the filename. It's always recommend to keep the default AppImage filenames, i.e. `EmulationStation-DE-x64.AppImage` and `EmulationStation-DE-x64_SteamDeck.AppImage` +Note that the updater will keep whatever filename you had for your running AppImage file, which could potentially be confusing if you for example added version information to the filename. It's always recommend to keep the default AppImage filenames, i.e. `ES-DE_x64.AppImage` and `ES-DE_x64_SteamDeck.AppImage` On Windows and macOS you can specify to which directory you want to save the downloaded file. The default is `C:\Users\myusername\Downloads` on Windows and `/Users/myusername/Downloads` on macOS. @@ -143,7 +143,7 @@ AUR upgrades should be automatically handled via your package manager and it sho **macOS** -Open _Applications_ in Finder and right click on _EmulationStation Desktop Edition_ and choose _Move to Trash_. Then simply install the new release using the .dmg drag-and-drop installer. +Open _Applications_ in Finder and right click on _ES-DE_ and choose _Move to Trash_. Then simply install the new release using the .dmg drag-and-drop installer. **Windows installer** @@ -164,7 +164,7 @@ In theory it's possible to make a custom system entry and hardcode the path to a If you really insist on not placing your games into the ES-DE standard directory structure, a much better solution is to symlink the game directories into the standard directory. In this way you don't need to make a custom es_systems.xml file and any additional emulators and other configuration added to future ES-DE releases will just work after upgrading. -This is an example of symlinking the Super Nintendo game directory on Unix and macOS: +This is an example of symlinking the Super Nintendo game directory on Linux and macOS: ``` cd ~/ROMs ln -s ~/my_games/super_nintendo/ snes @@ -189,7 +189,7 @@ Note that if the setting _Only show games from gamelist.xml files_ has been enab ## Placing games and other resources on network shares -Although ES-DE does support placing game ROMs, the `.emulationstation` home directory and the `downloaded_media` directory on network shares, this can lead to serious performance problems in some instances. Especially problematic is the Microsoft SMB protocol as it offers abysmal performance for some disk operations on which ES-DE relies heavily. For small game libraries this can still be acceptable, but for libraries with hundreds or thousands of games the application startup time and overall usage will be very painful or even unusable. Similar issues could occur when using file hosting services like Google Drive. +Although ES-DE does support placing game ROMs, the `ES-DE` application data directory and the `downloaded_media` directory on network shares, this can lead to serious performance problems in some instances. Especially problematic is the Microsoft SMB protocol as it offers abysmal performance for some disk operations on which ES-DE relies heavily. For small game libraries this can still be acceptable, but for libraries with hundreds or thousands of games the application startup time and overall usage will be very painful or even unusable. Similar issues could occur when using file hosting services like Google Drive. A general recommendation is to place all game files and other data on drives connected directly to the machine where ES-DE is running. Even using low speed technology like USB thumb drives, SD cards etc. is generally fine and leads to acceptable performance in most instances. @@ -231,7 +231,7 @@ In order for ES-DE to run, graphics drivers with OpenGL support have to be insta On some GPUs with buggy drivers, ES-DE may only display a black screen on startup or when launching a game. The problem can be worked around by specifying a window size for ES-DE that is a single pixel wider than the actual screen resolution. So for example for a 1280x800 display, the resolution can be set to 1281x800 and then rendering should work correctly. This is applied using the --resolution command line option, for example: ``` -EmulationStation.exe --resolution 1281 800 +ES-DE.exe --resolution 1281 800 ``` Some computers using Intel Iris Xe GPUs refuse to start ES-DE or display excessive graphics corruption. These problems are seemingly caused by driver bugs and do not occur when using Linux with the same hardware. There is no known solution or workaround to this issue other than switching to Linux or waiting for Intel to resolve the problem with a driver update. @@ -252,6 +252,8 @@ If you want to create your own portable intallation from scratch or customize th A number of systems have alternative emulator entries named _Shortcut or script_ which allows the direct execution of .lnk shortcut files or .bat batch files. It's not possible by default to directly launch .ps1 PowerShell scripts. As running PowerShell scripts is not even enabled by default on Windows they are for sure not recommended. If you still want to use them the best approach is to execute them via either a .lnk shortcut file or a .bat wrapper script where you explicitly call powershell.exe with the -command flag. If you instead insist on running them directly from ES-DE, you'll need to add a custom system or find rule configuration where you execute powershell.exe instead of cmd.exe and you'll also need to add .ps1 as a file extension for each relevant system. +Some disk operations can have abysmal performance on Windows, and this may be especially obvious for the theme downloader. This is often caused by anti-virus software like Microsoft Defender. If it takes say 30 seconds rather than 300 milliseconds to open the theme downloader then it may be a good idea to add an exlusion for the ES-DE\themes\ directory to Microsoft Defender. The same may also be true for other directories like the ROMs folder if disk performance is terrible. Refer to your anti-virus software documentation on how to setup such exclusions. + ## Specific notes for macOS As macOS does not support Vulkan some emulators are not available, and some that do exist have not been updated for this operating system in recent years. But emulator support is steadily improving and native ARM releases ("Apple Silicon") are also getting more common. One issue though is that some emulators are not codesigned and notarized so macOS refuses to run them by default. You can override the operating system's security settings however, which will work around this problem. Some emulators are also available via the [Homebrew](https://brew.sh) package manager and in many instances ES-DE includes support for these releases using the bundled configuration. @@ -266,13 +268,11 @@ At the time of writing there is an additional issue with the ARM release of Retr The first time you launch a RetroArch-emulated game from within ES-DE the operating system will present you with a security option with the following description: -`"EmulationStation Desktop Edition" would like to access files in your Documents folder.` +`"ES-DE" would like to access files in your Documents folder.` If you don't allow this, you will not be able to place system BIOS ROMs in the RetroArch default system directory `~/Documents/RetroArch/system` even if you've already given RetroArch access to this folder. This is so because RetroArch runs as a subprocess to ES-DE and therefore inherits the security settings from the parent application. Attempting to launch a game without enabling the access will simply display an error message in the emulator that the BIOS files are missing. This of course only applies to emulators that require BIOS ROMs, all other games should work fine regardless of this security setting. -If you accidentally refused ES-DE the folder access, you can fix this by opening _System Settings_, selecting _Privacy & Security_ and within the GUI choose _Files and Folders_. The option you need to enable is _Documents Folder_ under _EmulationStation Desktop Edition_. - -By default files and directories starting with a dot are hidden on macOS, so to show the .emulationstation directory in your home directory you need to enable hidden files in Finder. You do this using the keyboard combination Shift + Command + . (dot). +If you accidentally refused ES-DE the folder access, you can fix this by opening _System Settings_, selecting _Privacy & Security_ and within the GUI choose _Files and Folders_. The option you need to enable is _Documents Folder_ under _ES-DE_. A minor annoyance is that macOS creates metadata files starting with ._ in the filename when placing game/ROM files on some filesystem types such as exFAT. This means that you will see double entries inside ES-DE for all such games. To hide these extra files, the option _Show hidden files and folders (requires restart)_ in the _Other settings_ menu can be set to disabled. @@ -286,12 +286,16 @@ It's also possible to install ES-DE using [EmuDeck](https://www.emudeck.com) whi Unless RetroDECK is used, Flatpak releases of some emulators may need some extra permissions to be able to launch games placed on external devices such as a memory card. This is the case for instance for melonDS and RPCS3. The easiest way to do this is by using [Flatseal](https://flathub.org/apps/details/com.github.tchx84.Flatseal). The option you need to enable is generally _All system files_ in the _Filesystem_ section. If using EmuDeck some of these settings will be applied automatically via their installer. -If you are unfamiliar with Unix operating systems, make sure to at least read up on the concepts of _dotfiles_ (hidden files and directories), _home directories_ (including use of the tilde ~ character) and _symbolic links_ (symlinks): +If you are unfamiliar with Linux/Unix operating systems, make sure to at least read up on the concepts of _dotfiles_ (hidden files and directories), _home directories_ (including use of the tilde ~ character) and _symbolic links_ (symlinks): [https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory#Unix_and_Unix-like_environments](https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory#Unix_and_Unix-like_environments) \ [https://en.wikipedia.org/wiki/Home_directory#Unix](https://en.wikipedia.org/wiki/Home_directory#Unix) \ [https://en.wikipedia.org/wiki/Symbolic_link](https://en.wikipedia.org/wiki/Symbolic_link) +## Specific notes for Android + +The Android port of ES-DE is quite different than the other versions, so it has its specifics covered by a dedicated [ANDROID.md](ANDROID.md) document. + ## Specific notes for Raspberry Pi ES-DE on the Raspberry Pi requires a desktop environment, or more specifically a window manager and a sound server (like PulseAudio or PipeWire). There are no plans to add support for direct hardware access to the framebuffer or to ALSA. If you want to use your Raspberry Pi as an appliance, take a look at [RetroPie](https://retropie.org.uk), [Recalbox](https://www.recalbox.com) or [Batocera](https://batocera.org) instead. @@ -306,9 +310,9 @@ In general, 720p works fine with the RPi 4, and 1080p is tolerable but not reall The game systems configuration file `es_systems.xml` is located in the ES-DE resources directory which is part of the application installation. As such this file is not intended to be modified directly. If system customizations are required, a separate es_systems.xml file should instead be placed in the `custom_systems` folder in the ES-DE home directory. -On Unix this means `/home//.emulationstation/custom_systems/es_systems.xml`, on macOS `/Users//.emulationstation/custom_systems/es_systems.xml` and on Windows `C:\Users\\.emulationstation\custom_systems\es_systems.xml` or `EmulationStation-DE\.emulationstation\custom_systems\es_systems.xml` depending on whether the installer release or the portable release is used. +On Linux this means `/home//ES-DE/custom_systems/es_systems.xml`, on macOS `/Users//ES-DE/custom_systems/es_systems.xml` and on Windows `C:\Users\\ES-DE\custom_systems\es_systems.xml` or `ES-DE\ES-DE\custom_systems\es_systems.xml` depending on whether the installer release or the portable release is used. -If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. You can extract it if you need it as a reference when creating your customized entries, or you can find it [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/systems/unix). +If you're using the AppImage release of ES-DE then the bundled es_systems.xml file is embedded in the AppImage together with the rest of the resources. You can extract it if you need it as a reference when creating your customized entries, or you can find it [here](https://gitlab.com/es-de/emulationstation-de/-/tree/master/resources/systems/linux). Although it's possible to make a copy of the bundled configuration file, to modify it and then place it in this directory, that is not how the system customization is designed to be used. Instead the intention is that the file in `custom_systems` complements the bundled configuration, meaning only systems that are to be customized should be included. @@ -318,26 +322,13 @@ Instructions on how to customize the es_systems.xml file can be found in [INSTAL In addition to the above it's also possible to customize the find rules via the `es_find_rules.xml` file. The logic is essentially identical to what is described for es_systems.xml, and details regarding this file can be found in [INSTALL.md](INSTALL.md#es_find_rulesxml) as well. -## Migrating from other EmulationStation forks +## Migrating from EmulationStation **IMPORTANT!!! IMPORTANT!!! IMPORTANT!!!** -ES-DE is designed to be backward compatible to a certain degree. That is, it should be able to read data from other/previous EmulationStation versions such as the RetroPie and Batocera forks. But the opposite is not true and it's a one-way ticket for your gamelist.xml files and your custom collection files when migrating to ES-DE as they will be modified in ways that previous ES versions will see as data loss. For instance ES-DE does not use tags inside the gamelist.xml files to find game media but instead matches the media to the names of the game/ROM files. So it will not save any such tags back to the gamelist files during updates, effectively disabling the game media if the files are opened in another ES fork. +ES-DE is partially compatible with EmulationStation as both frontends originally shared the same source code. That is, ES-DE should generally be able to read data from EmulationStation. But the opposite is not true and it's a one-way ticket for your gamelist.xml files and your custom collection files when migrating to ES-DE as they will be modified in ways that EmulationStation will see as data loss. For instance ES-DE does not use tags inside the gamelist.xml files to find game media but instead matches the media to the names of the game/ROM files. So it will not save any such tags back to the gamelist files during updates, effectively disabling the game media if the files are opened in EmulationStation. -Due to this, always make backups of at least the following directories before testing ES-DE for the first time: - -``` -~/.emulationstation/gameslists/ -~/.emulationstation/collections/ -``` - -If you have gamelist.xml files in your ROMs directory tree then ES-DE will ignore those by default, so you need to move them to the ~/.emulationstation/gamelists/ tree. - -It's also strongly adviced to not rename an old es_settings.cfg file to es_settings.xml for use in ES-DE as it may cause undefined behavior and crashes. - -If migrating from Batocera, RetroBat or Recalbox, be aware that ES-DE follows the RetroPie naming conventions for most game systems. This means that your game files may not be found unless the folders are renamed accordingly. Such an example is the Sega SG-1000 system which in Batocera, RetroBat and Recalbox has the _sg1000_ system name, but is _sg-1000_ in RetroPie and ES-DE. See the [Supported game systems](USERGUIDE.md#supported-game-systems) table at the bottom of this guide for the correct system names in ES-DE. - -Another potential issue when migrating from another EmulationStation fork is that the path tag requires a leading ./ in ES-DE while that may not be present in other forks. If you don't see any metadata for your games inside ES-DE, then simply add the ./ characters to each path tag and it should hopefully work. +Another potential issue when migrating gamelist.xml files from EmulationStation is that the path tag requires a leading ./ in ES-DE while that may not be present in files coming from EmulationStation. If you don't see any metadata for your games inside ES-DE, then simply add the ./ characters to each path tag and it should hopefully work. Example of an unreadable path tag: ``` @@ -349,11 +340,16 @@ Example of a correct path tag readable by ES-DE: ./Another World.lha ``` +And if you have gamelist.xml files in your ROMs directory tree then ES-DE will ignore those by default, so you need to move them to the ~/ES-DE/gamelists/ tree. + +If migrating from Batocera, RetroBat or Recalbox, be aware that ES-DE does not always use the same system names as those frontends. This means that your game files may not be found unless the folders are renamed accordingly. Such an example is the Sega SG-1000 system which in Batocera, RetroBat and Recalbox has the _sg1000_ system name, but is _sg-1000_ in ES-DE. See the [Supported game systems](USERGUIDE.md#supported-game-systems) table at the bottom of this guide for the correct system names in ES-DE. + + ## Removing orphaned data Manually removing game files from the ROMs directory tree instead of deleting them from ES-DE using the metadata editor will make any corresponding scraped media files, gamelist.xml entries and custom collection entries orphaned, i.e. they will refer to non-existent files. Although this is correctly handled by ES-DE and is not causing any serious issues, it does lead to unnecessary disk space usage and it does produce log warnings in es_log.txt on application startup. If a huge amount of game files have been manually removed it can also lead to performance problems. -In order to remove such unnecessary media files and configuration file entries, the _Orphaned data cleanup_ utility in the _Utilities_ menu can be used. This tool should be largely self-explanatory. And although it should generally be safe to use, unforeseen issues can occur so make sure to make backups of at least your `.emulationstation/gamelists` and `.emulationstation/collections` directories before attempting to use this tool. +In order to remove such unnecessary media files and configuration file entries, the _Orphaned data cleanup_ utility in the _Utilities_ menu can be used. This tool should be largely self-explanatory. And although it should generally be safe to use, unforeseen issues can occur so make sure to make backups of at least your `ES-DE/gamelists` and `ES-DE/collections` directories before attempting to use this tool. It's recommended to run this utility with the _Show hidden games_ setting enabled as orphaned gamelist.xml folder entries may otherwise not get purged. @@ -363,17 +359,17 @@ Note that there are no guarantees that any processed gamelist.xml files will be If the utility finds any data to be removed, a backup of the old files will be made. This will end up in a `CLEANUP` directory and will contain a date and time stamp. For example: ``` -~/.emulationstation/gamelists/CLEANUP/2023-07-27_142830/dos/gamelist.xml -~/.emulationstation/gamelists/CLEANUP/2023-07-27_142830/ports/gamelist.xml -~/.emulationstation/collections/CLEANUP/2023-07-27_143216/custom-Action.cfg -~/.emulationstation/collections/CLEANUP/2023-07-27_143216/custom-Fighting.cfg -~/.emulationstation/downloaded_media/CLEANUP/2023-07-27_123406/atari2600/titlescreens/H.E.R.O..png -~/.emulationstation/downloaded_media/CLEANUP/2023-07-27_123406/c64/3dboxes/Minerer 2049.crt.png +~/ES-DE/gamelists/CLEANUP/2023-07-27_142830/dos/gamelist.xml +~/ES-DE/gamelists/CLEANUP/2023-07-27_142830/ports/gamelist.xml +~/ES-DE/collections/CLEANUP/2023-07-27_143216/custom-Action.cfg +~/ES-DE/collections/CLEANUP/2023-07-27_143216/custom-Fighting.cfg +~/ES-DE/downloaded_media/CLEANUP/2023-07-27_123406/atari2600/titlescreens/H.E.R.O..png +~/ES-DE/downloaded_media/CLEANUP/2023-07-27_123406/c64/3dboxes/Minerer 2049.crt.png ``` This means that you will need to manually delete these backup directories to free up disk space when you are certain that you no longer need the data. -All files and entries that are removed are logged to `~/.emulationstation/es_log.txt` so it could be a good idea to make a backup copy of this file after running the cleanup, for future reference. +All files and entries that are removed are logged to `~/ES-DE/logs/es_log.txt` so it could be a good idea to make a backup copy of this file after running the cleanup, for future reference. Any media directories that are empty after the cleanup will also be removed by this utility. @@ -386,7 +382,7 @@ _The Orphaned data cleanup utility after successfully removing some gamelist.xml ES-DE fully supports high resolution displays such as 1440p, 4K, 6K, 8K, ultrawide monitors etc. But many emulators (e.g. RetroArch) will also run using the same resolution which may cause performance problems on slower machines or when using resource intensive shaders. Although some emulator cores will have options to set their internal resolution, they still need to be scaled up to the screen resolution. -A solution to this is to use the custom event scripts functionality to set a temporary resolution upon launching a game that will be reverted when returning to ES-DE. Such a setup is detailed in [INSTALL.md](INSTALL.md#custom-event-scripts) for Unix, but should hopefully be possible to implement similarly on Windows. When going for this setup it's important that the setting _Run in background (while game is launched)_ is disabled or ES-DE may not be able to correctly switch to the emulator window when launching games. +A solution to this is to use the custom event scripts functionality to set a temporary resolution upon launching a game that will be reverted when returning to ES-DE. Such a setup is detailed in [INSTALL.md](INSTALL.md#custom-event-scripts) for Linux, but should hopefully be possible to implement similarly on Windows. When going for this setup it's important that the setting _Run in background (while game is launched)_ is disabled or ES-DE may not be able to correctly switch to the emulator window when launching games. On macOS it's problematic to change screen resolutions on the fly or on a per-application basis as Apple has seemingly disabled most of this functionality in recent operating system releases. The only real option here is to lower the display resolution prior to launching ES-DE. @@ -400,22 +396,22 @@ Below are some examples. For consistency it's assumed that the display resolutio Running at a lower application resolution in a window: ``` -emulationstation --resolution 1280 720 +es-de --resolution 1280 720 ``` Running at a lower application resolution in padded fullscreen mode: ``` -emulationstation --resolution 1824 1026 --fullscreen-padding 1 +es-de --resolution 1824 1026 --fullscreen-padding 1 ``` Same as above but also offsetting the screen slightly to the left and downwards: ``` -emulationstation --resolution 1824 1026 --fullscreen-padding 1 --screenoffset -40 22 +es-de --resolution 1824 1026 --fullscreen-padding 1 --screenoffset -40 22 ``` Rotate application screen contents 90 degrees while running at the native 1920x1080 screen resolution: ``` -emulationstation --screenrotate 90 +es-de --screenrotate 90 ``` ## Input device configuration @@ -428,7 +424,7 @@ The actual procedure to map the inputs should be self-explanatory, just follow t Any custom configuration is applied per unique device ID (GUID). So if two identical controllers are used with ES-DE, both will have the same configuration applied. If connecting controllers of the same type but of different revisions, the GUID may differ and therefore the custom configuration would need to be applied to each device individually. -If you have issues with your input configuration, as a last resort you can reset all mappings by deleting or renaming the file `~/.emulationstation/es_input.xml` +If you have issues with your input configuration, as a last resort you can reset all mappings by deleting or renaming the file `~/ES-DE/settings/es_input.xml` ## System view (main screen) @@ -486,6 +482,8 @@ When editing text it's also possible to paste from the clipboard into ES-DE usin Default keyboard mappings are shown in brackets below. +It's assumed that the option _Swap the A/B and X/Y buttons_ in the _Input device settings_ menu is disabled as some buttons will otherwise obviously be swapped. + **Up and down**\ _(Arrow up / Arrow down)_ @@ -537,7 +535,7 @@ _(Delete)_ Starts the media viewer in the gamelist view or the screensaver in the system view (if the _Enable screensaver controls_ setting is enabled). Used by some other minor functions as explained by the help system and/or this guide. **Y button**\ -_(Insert on Unix and Windows, F13 on macOS)_ +_(Insert on Linux and Windows, F13 on macOS)_ Marks games as favorites in the gamelist view (if the _Enable toggle favorites button_ option has been enabled). Used by some other minor functions as explained by the help system and/or this guide. @@ -553,13 +551,13 @@ As of ES-DE 2.2.0 no legacy EmulationStation themes are supported, such as those There are several user-selectable theme options in the _UI Settings_ menu, most notably _Theme variant_ which is essentially a form of theme profile. This could be anything, like different ways to navigate the themes, different layouts and designs etc. Additionally the _Theme color scheme_ setting makes it possible to select between different color schemes, if supported by the theme. The two remaining options _Theme aspect ratio_ and _Theme transitions_ are also important but you can normally leave them at their default _Automatic_ values, especially the _Theme aspect ratio_ option as it will be automatically detected. Be aware that all these theme settings are optional, it's up to the theme developer whether to add support for them to their themes. -Themes are most easily installed using the built-in theme downloader, but you can also manually add them to your ES-DE home directory, i.e. `~/.emulationstation/themes/`. By just adding them there, one folder each, they will be found during startup and you can then choose between them via the _UI Settings_ menu on the main menu. If using the portable release of ES-DE on Windows, the .emulationstation folder can be found in the root of the EmulationStation-DE directory. +Themes are most easily installed using the built-in theme downloader, but you can also manually add them to your ES-DE home directory, i.e. `~/ES-DE/themes/`. By just adding them there, one folder each, they will be found during startup and you can then choose between them via the _UI Settings_ menu on the main menu. If using the portable release of ES-DE on Windows, the ES-DE application data can be found in the root of the ES-DE directory. -Although you should place additional themes in your ES-DE home directory, the default Slate and Modern themes are located in the installation folder as they come bundled with the application. For example this could be `/usr/share/emulationstation/themes/` on Unix, `/Applications/EmulationStation Desktop Edition.app/Contents/Resources/themes/` on macOS or `C:\Program Files\EmulationStation-DE\themes\` on Windows. If using the portable ES-DE release on Windows, the themes folder will be located in the root of the EmulationStation-DE directory. +Although you should place additional themes in your ES-DE home directory, the default Slate and Modern themes are located in the installation folder as they come bundled with the application. For example this could be `/usr/share/es-de/themes/` on Linux, `/Applications/ES-DE.app/Contents/Resources/themes/` on macOS or `C:\Program Files\ES-DE\themes\` on Windows. If using the portable ES-DE release on Windows, the themes folder will be located in the root of the ES-DE directory. Note that if using the AppImage release on Linux, then there is no installation folder as all files are contained inside the AppImage file. -If you would like to customize the Slate or Modern themes, simply make a copy of their directories to `~/.emulationstation/themes/` and then those copies will take precedence over the ones in the application installation directory. +If you would like to customize the Slate or Modern themes, simply make a copy of their directories to `~/ES-DE/themes/` and then those copies will take precedence over the ones in the application installation directory. Refer to the official themes list for a selection of high-quality themes (these are also available via the built-in theme downloader):\ https://gitlab.com/es-de/themes/themes-list @@ -581,7 +579,7 @@ If you have manually downloaded any of the themes from the [official themes list If you have customized a theme by for instance modifying any of its XML files, then this will be highlighted with an exclamation mark and the text _LOCAL CHANGES_ in the theme downloader interface. If you attempt to fetch updates for such a theme you will be asked a question of whether to overwrite your local changes, or whether to cancel. If you have however added additional files to the theme that are not included in the theme repository, then these will not interfere and you can go ahead and fetch theme updates without any risk of having your local files being deleted. But there is a special (although unlikely) situation, if you add files that are not part of the theme repository but that are later added by the theme developer as well, then your local copies of any such files will be ovewritten when fetching theme updates. -In worst case there could be a situation where a repository is corrupted and the theme downloader can't properly identify or handle the corruption. In this case you will have to rename or delete that directory. This could also apply to the actual themes list repository. The latter is named _themes-list_ so by just deleting this directory (i.e. `~/.emulationstation/themes/themes-list`) you'll reset the theme downloader to its initial state. +In worst case there could be a situation where a repository is corrupted and the theme downloader can't properly identify or handle the corruption. In this case you will have to rename or delete that directory. This could also apply to the actual themes list repository. The latter is named _themes-list_ so by just deleting this directory (i.e. `~/ES-DE/themes/themes-list`) you'll reset the theme downloader to its initial state. Note that the exFAT filesystem can't be used as it makes the theme downloader fail. But using this filesystem is strongly discouraged anyway as it offers very poor disk I/O performance which makes ES-DE run really slowly. @@ -682,6 +680,7 @@ The following emulators are supported in AppImage format when using the bundled | ps2 | PCSX2 | pcsx2*.AppImage | | ps2 | Play! | Play!*.AppImage | | ps3 | RPCS3 | rpcs3*.AppImage | +| psvita | Vita3K | Vita3K*.AppImage | | psx | DuckStation | DuckStation*.AppImage | | snes | Snes9x | Snes9x*.AppImage | | switch | Yuzu | yuzu*.AppImage | @@ -728,7 +727,7 @@ There is however a workaround available to launch the Flatpak first, should you For example if using the ES-DE AppImage release, this would be the command to execute: ``` -PATH=/var/lib/flatpak/exports/bin:~/.local/share/flatpak/exports/bin:$PATH ./EmulationStation-DE-x64.AppImage +PATH=/var/lib/flatpak/exports/bin:~/.local/share/flatpak/exports/bin:$PATH ./ES-DE_x64.AppImage ``` Obviously you would need to change the path to the AppImage if it's not in your current working directory. @@ -810,6 +809,12 @@ cd ~/Applications/SkyEmu chmod +x SkyEmu ``` +And for VPinballX_GL: +``` +cd ~/Applications/VPinballX +chmod +x VPinballX_GL +``` + ## Running Windows emulators on Linux using Wine or Proton On Linux it's possible to run emulators developed specifically for Microsoft Windows via the Wine compatibility layer. Support is also included for the Proton fork of Wine. @@ -916,9 +921,9 @@ But for some systems a more elaborate setup is required, and the configuration f Let's start with the simple scenario of a single ROM file per game, which is the case for the majority of platforms. For this example we're setting up ES-DE to play Nintendo Entertainment System games. -The supported file extensions are listed in [unix/es_systems.xml](resources/systems/unix/es_systems.xml), [macos/es_systems.xml](resources/systems/macos/es_systems.xml) and [windows/es_systems.xml](resources/systems/windows/es_systems.xml) but if you generated the game system directories on first application startup or later via _Create/update system directories_ in the _Utilities_ menu, then there will be a file named systeminfo.txt in each game system directory that includes the list of supported file extensions. +The supported file extensions are listed in [linux/es_systems.xml](resources/systems/linux/es_systems.xml), [macos/es_systems.xml](resources/systems/macos/es_systems.xml) and [windows/es_systems.xml](resources/systems/windows/es_systems.xml) but if you generated the game system directories on first application startup or later via _Create/update system directories_ in the _Utilities_ menu, then there will be a file named systeminfo.txt in each game system directory that includes the list of supported file extensions. -Here is a simplified example from unix/es_systems.xml: +Here is a simplified example from linux/es_systems.xml: ```xml @@ -941,20 +946,20 @@ It's highly recommended to use filenames that correspond to the full name of the Symlinks are supported for both ROM directories and individual game files, but make sure to never symlink between files within the same system directory or there may be undefined application behavior when scraping, launching games etc. -The default game folder is ~/ROMs. On Unix this defaults to `/home//ROMs`, on macOS `/Users//ROMs` and on Windows `C:\Users\\ROMs` or `EmulationStation-DE\ROMs` depending on whether the installer release or the portable release is used. If the --home command line option was used to start ES-DE, the tilde symbol will resolve to whatever directory was passed as an argument to this option. +The default game folder is ~/ROMs. On Linux this defaults to `/home//ROMs`, on macOS `/Users//ROMs` and on Windows `C:\Users\\ROMs` or `ES-DE\ROMs` depending on whether the installer release or the portable release is used. If the --home command line option was used to start ES-DE, the tilde symbol will resolve to whatever directory was passed as an argument to this option. Assuming the default ROM directory is used, we need to create a subdirectory corresponding to the \ tag in es_systems.xml, for this example it's `nes`. So it would look something like the following: ``` -/home/myusername/ROMs/nes # Unix/Linux +/home/myusername/ROMs/nes # Linux /Users/myusername/ROMs/nes # macOS C:\Users\myusername\ROMs\nes # Windows installer -EmulationStation-DE\ROMs\nes # Windows portable +ES-DE\ROMs\nes # Windows portable ``` -Now simply copy your game ROMs into this folder, and you should end up with something like this Unix example: +Now simply copy your game ROMs into this folder, and you should end up with something like this Linux example: ``` ~/ROMs/nes/Legend of Zelda, the.zip @@ -962,7 +967,7 @@ Now simply copy your game ROMs into this folder, and you should end up with some ~/ROMs/nes/Super Mario Bros. 3.zip ``` -Note that these directories are case sensitive on Unix, so creating a directory named `Nes` instead of `nes` won't work. +Note that these directories are case sensitive on Linux/Unix, so creating a directory named `Nes` instead of `nes` won't work. That's it, start ES-DE and the NES game system should be populated. You can now scrape information and media for the games, and assuming you've setup RetroArch correctly with the Mesen core, you can launch games. If you instead prefer to use any of the three alternative emulators listed above (Nestopia UE, FCEUmm or QuickNES) then you can install one of those cores instead and change your emulator preference using the _Alternative emulators_ interface in the _Other settings_ menu or on a per-game basis via the metadata editor. Note that alternative emulators are only available for some game systems. @@ -1093,9 +1098,9 @@ Not all systems are as simple to setup as what was described in the previous sec ### Apple II -On Unix/Linux the default emulator for the apple2 system is [LinApple](http://linapple.sourceforge.net) and on Windows it's [AppleWin](https://github.com/AppleWin/AppleWin). Additionally the alternative emulators [Mednafen](https://mednafen.github.io) and [MAME](https://www.mamedev.org) standalone are supported. On macOS there is a port of AppleWin available named [Mariani](https://github.com/sh95014/AppleWin) but it appears broken at the moment as it does not accept any command line parameters. So instead only Mednafen and MAME are supported on macOS. +On Linux the default emulator for the apple2 system is [LinApple](http://linapple.sourceforge.net) and on Windows it's [AppleWin](https://github.com/AppleWin/AppleWin). Additionally the alternative emulators [Mednafen](https://mednafen.github.io) and [MAME](https://www.mamedev.org) standalone are supported. On macOS there is a port of AppleWin available named [Mariani](https://github.com/sh95014/AppleWin) but it appears broken at the moment as it does not accept any command line parameters. So instead only Mednafen and MAME are supported on macOS. -Depending on which Unix/Linux operating system you're using, LinApple may not be readily available and you may have to build it from source code or obtain a binary from somewhere on the Internet. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where it needs to be installed. If you're using an OS with access to the AUR, such as Arch or Manjaro, then LinApple is available there. Note that you need to use the _linapple-git_ package as the regular _linapple_ package does not work correctly. +Depending on which Linux operating system you're using, LinApple may not be readily available and you may have to build it from source code or obtain a binary from somewhere on the Internet. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where it needs to be installed. If you're using an OS with access to the AUR, such as Arch or Manjaro, then LinApple is available there. Note that you need to use the _linapple-git_ package as the regular _linapple_ package does not work correctly. Once the LinApple or AppleWin emulator is installed no additional configuration is required, just drop your games into the ~/ROMs/apple2 folder and launch them from inside ES-DE. @@ -1219,7 +1224,7 @@ The EMULATOR.INI file is found in the _Model 2 Emulator_ installation directory. Note that Model 2 Emulator is a bit broken and on Windows most GPU drivers it will only work correctly if ES-DE keeps running in the background while the game is launched. However, for some GPU drivers the opposite is true and the emulator will only work if ES-DE is suspended. To use the latter setup, switch to the alternative emulator entry _Model 2 Emulator [Suspend ES-DE] (Standalone)_. -To run Model 2 Emulator on Linux you need Wine or Proton, how to setup this is covered in the [Running Windows emulators on Linux using Wine or Proton](USERGUIDE-DEV.md#running-windows-emulators-on-linux-using-wine-or-proton) section. +To run Model 2 Emulator on Linux you need Wine or Proton, how to setup this is covered in the [Running Windows emulators on Linux using Wine or Proton](USERGUIDE.md#running-windows-emulators-on-linux-using-wine-or-proton) section. After Wine or Proton has been installed, unpack the emulator files into the `~/Applications/m2emulator/` directory. @@ -1272,7 +1277,7 @@ ln -s /usr/local/Cellar/mame/0.248/share/mame/hash ~/.mame/ # on x86/Int These systems are generally straightforward to setup. For regular Atari Jaguar games you'll have a single ROM or zip archive per game that you place in the root of the `~/ROMs/atarijaguar` system directory. For Atari Jaguar CD games it's recommended to go for the .cdi format and you place these directly in the root of the `~/ROMs/atarijaguarcd` directory. -The only emulator that can run Atari Jaguar CD games is [BigPEmu](https://www.richwhitehouse.com/jaguar/) and while it's officially only available for the Windows operating system it's still possible to run it on Linux. To accomplish this you need to run it via the Wine (or Proton) translation layer. +The only emulator that can run Atari Jaguar CD games is [BigPEmL](https://www.richwhitehouse.com/jaguar/) and while it's officially only available for the Windows operating system it's still possible to run it on Linux. To accomplish this you need to run it via the Wine (or Proton) translation layer. How to setup Wine is covered in the [Running Windows emulators on Linux using Wine or Proton](USERGUIDE.md#running-windows-emulators-on-linux-using-wine-or-proton) section. @@ -1471,9 +1476,9 @@ Regardless of game setup method, per-game settings can be applied. If using the These computers as well as the Dragon 64 are slight varations of the Tandy Color Computer and as these machines are largely compatible with each other they're all emulated using the [XRoar](http://www.6809.org.uk/xroar) emulator. -This emulator is available for Unix/Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. +This emulator is available for Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. -In order to emulate the Dragon 32 you need the ROM file `d32.rom` and to emulate the Dragon 64 or Tano Dragon you need the `d64rom1.rom` and `d64rom2.rom` files. It's unclear whether `ddos10.rom` will also be needed for some games and applications. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Unix/Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. +In order to emulate the Dragon 32 you need the ROM file `d32.rom` and to emulate the Dragon 64 or Tano Dragon you need the `d64rom1.rom` and `d64rom2.rom` files. It's unclear whether `ddos10.rom` will also be needed for some games and applications. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. Following this setup there is not much to it, launching a cartridge or cassette image file will automatically run the game. @@ -1727,7 +1732,7 @@ You could optionally create a .commands file as well to specify some additional The next step is to modify the _\.singe_ file to point to the exact game directory. -So for example on Unix, modify the file `~/ROMs/laserdisc/mononoke.singe/mononoke.singe` by changing the following line: +So for example on Linux, modify the file `~/ROMs/laserdisc/mononoke.singe/mononoke.singe` by changing the following line: ``` MYDIR = "singe/mononoke/" ``` @@ -1755,11 +1760,13 @@ There are two ways to play these games, either via emulation or via simulation. **Method 1, emulation** -Proper emulation is done via the MAME standalone emulator. The games need to be in the MAME format and follow the MAME software list naming conventions, i.e. it will not be possible to run .mgw games with this emulator. The example game _Donkey Kong_ would have the filename `gnw_dkong.zip` and you'll place this file in the `gameandwatch` or `lcdgames` directory. +Proper emulation is done via the MAME - Current RetroArch core or the MAME standalone emulator. The games need to be in the MAME format and follow the MAME software list naming conventions, i.e. it will not be possible to run .mgw games with this emulator. The example game _Donkey Kong_ would have the filename `gnw_dkong.zip` and you'll place this file in the `gameandwatch` or `lcdgames` directory. However the game is only half of what's needed to properly emulate these games as you'll also need the artwork to see an image of the actual physical device when running the game. The artwork would also come in a .zip file with the same name as the game itself, e.g. `gnw_dkong.zip` and it must be located in the MAME artwork directory so it can be found by MAME. -For the artwork location there are two options available in the form of two separate MAME emulator entries, either the default _MAME Local Artwork (Standalone)_ entry or _MAME (Standalone)_. The former will require the artwork files to be placed in a directory inside the `gameandwatch` or `lcdgames` folder, which can be quite convenient as it's then bundled with the game files. Simply create an `artwork` subdirectory and place the files there. The second emulator entry will require the artwork files to be placed in the default MAME artwork directory. This location differs between operating systems and distributions so refer to the MAME documentation on where to find this folder. Here's an example of what _Donkey Kong_ would look like when going for the default option using the `gameandwatch` system: +For the RetroArch core this means it has to be placed in the system directory, specifically in `system/mame/artwork/` + +For MAME standalone there are two options available for the artwork location in the form of two separate MAME emulator entries, either the default _MAME Local Artwork (Standalone)_ entry or _MAME (Standalone)_. The former will require the artwork files to be placed in a directory inside the `gameandwatch` or `lcdgames` folder, which can be quite convenient as it's then bundled with the game files. Simply create an `artwork` subdirectory and place the files there. The second emulator entry will require the artwork files to be placed in the default MAME artwork directory. This location differs between operating systems and distributions so refer to the MAME documentation on where to find this folder. Here's an example of what _Donkey Kong_ would look like when going for the default option using the `gameandwatch` system: ``` ~/ROMs/gameandwatch/gnw_dkong.zip @@ -1768,7 +1775,7 @@ For the artwork location there are two options available in the form of two sepa As the artwork files also come with the .zip file extension they will show up inside ES-DE as if they were game files. So it's recommended to hide the entire artwork directory using the _Hidden_ option in the metadata editor, or alternatively exclude them from the multi-scraper using the _Exclude from multi-scraper_ option. -Be aware that neither ScreenScraper nor TheGamesDB currently support the MAME software list names natively so you'll need to refine the searches or the scraper services are unlikely to return any results at all (or very inaccurate results at best). +Be aware that neither ScreenScraper nor TheGamesDB currently support the MAME software list names natively so you'll need to refine the searches or the scraper services are unlikely to return any results at all (or very inaccurate results at best). However, if you have game files that match the MD5 hashes in the ScreenScraper database, then the games will scrape correctly regardless of their names. **Method 2, simulation** @@ -2132,10 +2139,21 @@ Starting ES-DE should now show the _Super Mario 3D World_ entry for the Wii U sy ### OpenBOR -The Open Beats of Rage (OpenBOR) game engine is available on Windows and Linux. Unfortunately the macOS ports seems to have been abandoned. +The Open Beats of Rage (OpenBOR) game engine is available on Android, Windows and Linux. Unfortunately the macOS port seems to have been abandoned. These games are often but not always distributed together with the game engine as specific engine versions may be required for some games. The setup is slightly different between Windows and Linux so they are described separately here. +**Android** + +Unfortunately there does not seem to be a way to launch individual OpenBOR games from ES-DE on Android, instead the OpenBOR user interface will open on game launch and you need to manually start your game from there. This means games need to be installed upfront in OpenBOR and .openbor dummy files should be added to the `ROMs/openbor` directory. These will then appear as individual games inside ES-DE and you can add metadata to them, scrape them etc. Refer to the OpenBOR documentation on how to add your game PAKs. + +Here's an example setup: + +``` +/storage/emulated/0/ROMs/openbor/D&D - K&D - The Endless Quest LNS.openbor +/storage/emulated/0/ROMs/openbor/He-Man.openbor +``` + **Windows:** There are two different OpenBOR setup methods supported on Windows, either to place the game directories directly inside the ROMs\openbor directory or to place the games somewhere else on the filesystems and create .lnk shortcuts and place these inside the ROMs\openbor directory. @@ -2208,6 +2226,8 @@ Doing this will make the game show up as if it was a single file inside ES-DE an PICO-8 Fantasy Console is a game engine developed by [Lexaloffle Games](https://www.lexaloffle.com/pico-8.php) that you need to buy a license to use. Doing so will provide you with download links to releases for Linux, macOS and Windows. Make sure to use the 64-bit release as the 32-bit release reportedly has some technical issues. On macOS and Windows the installation is straightforward, but on Linux you need to place PICO-8 in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. +On Android it's recommended to use the Fake-08 RetroArch core, although this needs to be manually downloaded. How that is done is covered briefly in the [ANDROID.md](ANDROID.md#fake-08) document. + After the emulator has been installed you are ready to add some games. There are two ways to play games using PICO-8, either to add them to ES-DE as for any other system, or using the built-in Splore tool to explore and run games all through the PICO-8 user interface. For the first approach you can download games from the [PICO-8 forum](https://www.lexaloffle.com/bbs/?cat=7) and these are quite uniquely distributed as .png images. You just download these and place them inside the ~/ROMs/pico8 directory, for example: @@ -2227,16 +2247,17 @@ This is what the complete setup could look like: ~/ROMs/pico8/xzero-3.p8.png ``` -**Using the Retro8 RetroArch core** +**Using the Fake-08 and Retro8 RetroArch cores** + +On Android the Fake-08 core provides a good alternative to the official PICO-8 engine which is not available on this operating system. ES-DE also includes support for the Retro8 RetroArch core across all platforms, but it's borderline unusable and does not seem to be actively developed any longer. + +Neither Fake-08 nor Retro8 support the .png file extension, so in order to use these cores you need to remove that extension from your game files and only keep the .p8 extension, such as this: -ES-DE also includes support for the Retro8 RetroArch core but it's borderline unusable and does not seem to be actively developed any longer. If you still want to use it, then you first need to rename your game files by removing _.png_ from the end of the filenames, like this: ``` ~/ROMs/pico8/c_e_l_e_s_t_e-0.p8 ~/ROMs/pico8/xzero-3.p8 ``` -Following this just select the _Retro8_ alternative emulator and the games will (somehow) work. - ### Ports and desktop applications _The emulators system is essentially a clone of the desktop system so it's not discussed specifically in this section._ @@ -2252,7 +2273,7 @@ For the _desktop_ system specifically, you can choose to suspend ES-DE while an Shortcuts are very easy to setup, on Windows you can simply copy any .lnk file from the Start Menu into the `ports` or `desktop` system folders and then you can launch them directly from inside ES-DE. You can also create shortcuts manually to any file by right clicking on it in Explorer and selecting _Create shortcut_. -Likewise on Unix you can copy any .desktop shortcut into these system directories and they can then be launched by ES-DE. +Likewise on Linux you can copy any .desktop shortcut into these system directories and they can then be launched by ES-DE. Here's an example on Windows: ``` @@ -2260,7 +2281,7 @@ Here's an example on Windows: ~\ROMs\ports\openxcom.lnk ``` -And here's an example on Unix: +And here's an example on Linux: ``` ~/ROMs/desktop/org.libretro.RetroArch.desktop ~/ROMs/desktop/spotify.desktop @@ -2276,7 +2297,7 @@ Here's an example using alias files on macOS: **Method 2, scripts** -For more advanced setups you may want to use scripts. While it's possible to add these files directly to the root of the system directories it's instead generally recommended to setup a separate directory per game as there may be more than a single file required. For instance you may have multiple game variants or mods or you may want to keep game data files within the ROM directory tree. Only examples for Unix are provided here, but it's the same process for Windows and macOS except that in Windows .bat batch files are used instead of shell scripts. +For more advanced setups you may want to use scripts. While it's possible to add these files directly to the root of the system directories it's instead generally recommended to setup a separate directory per game as there may be more than a single file required. For instance you may have multiple game variants or mods or you may want to keep game data files within the ROM directory tree. Only examples for Linux are provided here, but it's the same process for Windows and macOS except that in Windows .bat batch files are used instead of shell scripts. Here's a setup of GZDoom and vkQuake: ``` @@ -2357,7 +2378,7 @@ Apart from this you need to install the PS3 system firmware to use the emulator, **Method 1, shortcuts** -First install your games inside RPCS3, then right click on each entry and select _Create Shortcut_ followed by _Create Desktop Shortcut_. On Windows this will create shortcuts with the .lnk extension, on macOS they will have the .app extension and on Unix/Linux they will have the .desktop extension. +First install your games inside RPCS3, then right click on each entry and select _Create Shortcut_ followed by _Create Desktop Shortcut_. On Windows this will create shortcuts with the .lnk extension, on macOS they will have the .app extension and on Linux they will have the .desktop extension. Then simply move these files from your desktop to your ~/ROMs/ps3 directory and you're done. Here's an example of what this could look like on Linux: ``` @@ -2396,7 +2417,7 @@ When using this setup method you need to set the alternative emulator to _RPCS3 Support for the PS Vita is currently experimental due to the early stages of development for the Vita3K emulator. While there's a growing list of games that are playable, integration with ES-DE is a bit rough at the moment. Hopefully this will improve as Vita3K evolves. -On Windows the Vita3K installation is straightforward, but on Linux you may need to place the emulator in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. If using a Linux distribution that provides Vita3K via the repository (such as the AUR on Arch/Manjaro) then you can skip this step and install the emulator using your OS package manager. +On Android and Windows the Vita3K installation is straightforward, but on Linux you may need to place the emulator in a location recognized by ES-DE. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details. If using a Linux distribution that provides Vita3K via the repository (such as the AUR on Arch/Manjaro) then you can skip this step and install the emulator using your OS package manager. Although a macOS release of Vita3K seems to be in the works this does not seem to be readily available for download so there is currently no macOS support for this system in ES-DE. @@ -2426,7 +2447,7 @@ Simply copy the Start Menu entries for your Steam games into the ~\ROMs\steam di ~\ROMs\steam\Undertale.url ``` -**Unix/Linux** +**Linux** Copy the .desktop shortcuts for your games into the ~/ROMs/steam directory. If your desktop environment does not allow you to copy them directly from the application menu then you may need to navigate to `~/.local/share/applications` using your file manager and copy the .desktop files from there. Alternatively you can also create shortcuts from inside Steam by right clicking on a game, selecting _Manage_ and then _Add desktop shortcut_. These file can then be moved from your desktop to your ~/ROMs/steam directory. This is an example of what you could end up with: @@ -2450,6 +2471,19 @@ On macOS the shortcuts come with the .app extension and are actually directories As the Nokia N-Gage was running Symbian it may seem like the _ngage_ and _symbian_ systems would be identical. There is however a difference in that N-Gage games were shipped on MMC memory cards while regular Symbian games were packaged as _Software Installation Script_ files with the .sis or .sisx extension. Although the EKA2L1 emulator is used for both systems the setup is quite different, as detailed below. +**Android** + +Unfortunately there does not seem to be a way to launch individual games from ES-DE on Android specifically, so instead the EKA2L1 user interface will open on game launch and you need to manually start your game from inside the emulator. As games need to be installed upfront in the emulator as described below it's probably a good idea to just setup dummy game files with the .symbian or .ngage file extensions inside the ES-DE ROMs directory tree. These will then appear as indvidual games inside ES-DE and you can add metadata to them, scrape them etc. + +Here's an example setup: +``` +/storage/emulated/0/ROMs/ngage/Asphalt 2.ngage +/storage/emulated/0/ROMs/ngage/Bomberman.ngage +/storage/emulated/0/ROMs/ngage/CallofDuty.ngage +/storage/emulated/0/ROMs/symbian/Animal Farm.symbian +/storage/emulated/0/ROMs/symbian/AnotherWorld.symbian +``` + **General setup** The EKA2L1 installation should be fairly straightforward, for Linux there is an official AppImage, for macOS there is a DMG installer and for Windows a zip archive release. Just be aware that the AppImage has the very generic name `ubuntu-latest.AppImage` and needs to be renamed and moved to `~/Applications/EKA2L1.AppImage` in order for ES-DE to find it. @@ -2537,9 +2571,9 @@ Finally there's an emulator entry named _EKA2L1 [Custom device] (Standalone)_ wh This computer (which is confusingly also known as _TRS-80 Color Computer_ even though it's a completely different machine than the _TRS-80_) is emulated using the [XRoar](http://www.6809.org.uk/xroar) emulator. -This emulator is available for Unix/Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. +This emulator is available for Linux, macOS and Windows, although on Linux you may need to build it from source code depending on which distribution you're using. Refer to the XRoar website for more information. If you manually download or build the emulator yourself then see the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where you need to install it. -In order for XRoar to work correctly you need the ROM files `bas13.rom`, `disk11.rom` and `extbas11.rom`. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Unix/Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. +In order for XRoar to work correctly you need the ROM files `bas13.rom`, `disk11.rom` and `extbas11.rom`. Even without these files the emulator will probably start, but you will likely see random character on screen and few if any games will run correctly. On Linux these files need to be placed into the `~/.xroar/roms` directory and on macOS you need to place them in `~/Library/XRoar/roms`. Note that neither of these directories are automatically created by the emulator so you need to create them yourself. On Windows you simply place the ROM files into the emulator installation directory next to the xroar.exe binary. Following this setup there is not much to it, launching a cartridge or cassette image file will automatically run the game. If launching a diskette image you will probably need to manually run the game file from inside the emulated operating system. Such commands are beyond the scope of this document, but the following [quick reference PDF](https://colorcomputerarchive.com/repo/Documents/Manuals/Hardware/Color%20Computer%20Disk%20System%20-%20Quick%20Reference%20Guide%20(Tandy).pdf) provides a good command overview. @@ -2551,7 +2585,7 @@ Two emulator entries are available for this system, _XRoar CoCo 2 NTSC (Standalo Tandy Corporation made the somewhat dumb decision of naming several unrelated computers as TRS-80 which has caused decades of confusion. The _Tandy TRS-80_ system in ES-DE emulates the original black-and-white TRS-80 Model I. If you want to emulate the TRS-80 Color Computer then you'll want to use the _Tandy Color Computer_ system instead. -The TRS-80 is emulated using [sdl2trs](https://gitlab.com/jengun/sdltrs) which is available for Unix/Linux and Windows, seemingly there is no macOS port. If you use a Debian-based Linux distribution there is a .deb package made by the developers and if you're using an Arch-based distribution you can install it using the AUR. For other distributions you may have to build from source code or download a pre-built binary from some other location. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where sdl2trs will need to be installed in that case. +The TRS-80 is emulated using [sdl2trs](https://gitlab.com/jengun/sdltrs) which is available for Linux and Windows, seemingly there is no macOS port. If you use a Debian-based Linux distribution there is a .deb package made by the developers and if you're using an Arch-based distribution you can install it using the AUR. For other distributions you may have to build from source code or download a pre-built binary from some other location. See the [Using manually downloaded emulators on Linux](USERGUIDE.md#using-manually-downloaded-emulators-on-linux) section of this guide for more details on where sdl2trs will need to be installed in that case. On Windows only the 64-bit release of the emulator is supported, with the filename `sdl2trs64.exe`. @@ -2584,11 +2618,11 @@ Here's what a complete setup could look like: ### Tangerine Computer Systems Oric -These games are executed using the Oricutron emulator which is readily available on Windows but quite problematic to get hold on for Unix and macOS. +These games are executed using the Oricutron emulator which is readily available on Windows but quite problematic to get hold on for Linux and macOS. Although there is a macOS build available at the Oricutron [download page](http://www.petergordon.org.uk/oricutron/) this seems to not work properly, or it's unclear how it should be used. As such this system is unsupported on macOS, but the configuration entries still exist in the bundled es_find_rules.xml and es_systems.xml files so if you manage to get the emulator to run, ES-DE should work with these games. -Likewise on Unix there seems to be no binaries available for download so you need to build the emulator yourself. As multiple files like images and roms are needed to run this emulator, it's easiest to download and extract the Windows version which contains all this data and then build from source code and simply copy over the `Oricutron` binary (example below using Ubuntu): +Likewise on Linux there seems to be no binaries available for download so you need to build the emulator yourself. As multiple files like images and roms are needed to run this emulator, it's easiest to download and extract the Windows version which contains all this data and then build from source code and simply copy over the `Oricutron` binary (example below using Ubuntu): ``` mkdir -p ~/Applications/oricutron @@ -2618,6 +2652,76 @@ https://docs.mamedev.org/usingmame/defaultkeys.html Scraping can also be a bit challenging as MAME software list names are used and neither ScreenScraper nor TheGamesDB can parse these names. So it's recommended to run the scraper in interactive mode and refine the searches for all games that are not properly identified. +### Visual Pinball + +The pinball simulator Visual Pinball can be a bit tricky to setup as it supports a wide range of tables. Some of these require [PinMAME](https://github.com/vpinball/pinmame) and some don't. Some simulated tables are older electromechnical design and some are of more modern solid state designs. Some are recreations of real physical games and some are purely virtual and don't exist in physical form. In many cases there is not a definitive release for a table and you may need to assemble various files to get to a fully working game. + +As pinball games is a complex topic it will only be covered briefly here, refer to the official Visual Pinball [documentation](https://github.com/vpinball/vpinball/blob/standalone/standalone/README.md) for more details. + +The Windows release of Visual Pinball can be downloaded here (make sure to get the GL version):\ +https://github.com/vpinball/vpinball/releases + +Apart from this the Windows-specific setup is not covered in this document, but you should be able to find a lot of resources online on this topic. + +The Linux and macOS releases need to be downloaded from the GitHub Actions page for the time being:\ +https://github.com/vpinball/vpinball/actions + +On Linux simply unpack the archive into `~/Applications/VPinballX` and make sure to give the binary executable permissions: +``` +cd ~/Applications/VPinballX +chmod +x VPinballX_GL +``` + +On macOS there is a DMG package that you simply install. + +Once you've installed Visual Pinball start it once outside ES-DE and its .ini configuration file will be created. On Linux and macOS this is `~/.vpinball/VPinballX.ini` + +Set the following entries in this file: +``` +VPRegPath = ./ +PinMAMEPath = ./ +PinMAMEIniPath = ./ +``` + +If you don't do this the table may still start but won't work properly and you'll not be able to actually start a game. + +ES-DE launches .vpx and .vpt files for the vpinball system, but most tables come shipped with multiple additional files that are needed for the table to work, for example: +``` +~/ROMs/vpinball/fh/pinmame/ +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +``` + +Assembling the necessary files to run a table is beyond the scope of this guide but there are various resources available online for this. + +This specific table requires PinMAME to run, and the _fh_ directory name is an example of the abbreviations commonly used in the pinball community. You can for instance find these names in the [Internet Pinball Database](https://www.ipdb.org/) where they are referred to as _Common Abbreviations_. + +If you don't need to retain these abbreviations then you can simply setup your games using the _directories interpreted as files_ functionality: +``` +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/pinmame/ +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +``` + +If you however insist on retaining the abbreviations then you could use folder links to launch the .vpx or .vpt file inside the fh directory by editing the folder in the metadata editor and selecting the game file via the _Folder link_ entry. + +A final option would be to use the _folder flattening_ functionality, although this has many negative side effects that you need to be aware of. If going for this approach make sure to thoroughly read the [Folder flattening](USERGUIDE.md#folder-flattening) section of this document. + +``` +~/ROMs/vpinball/fh/pinmame/ +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.directb2s +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.ini +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vbs +~/ROMs/vpinball/fh/Funhouse (Williams 1990)_Bigus(MOD)1.6.vpx +~/ROMs/vpinball/flatten.txt +``` + +With folder flattening in place the .vpx and .vpt files will show up as file entries directly in the root of the gamelist. + ## Scraping Scraping means downloading metadata and game media files (images and videos) for the games in your collection. @@ -2687,33 +2791,33 @@ Apart from this, hopefully the scraping process should be self-explanatory. If you already have a library of game media (images, videos and PDF manuals) you can manually copy these files into ES-DE. The same procedure applies if you want to add media for individual games, for instance when the scraper did not return any results or if you didn't like the media it provided. -The default media directory is `~/.emulationstation/downloaded_media//` +The default media directory is `~/ES-DE/downloaded_media//` This directory can however be changed using the _Game media directory_ setting in the _Other settings_ menu so make sure to check this setting before attempting to follow the instructions below. If the setting is blank, then the default directory is in use. See the [Supported game systems](USERGUIDE.md#supported-game-systems) table at the bottom of this guide for a list of all system names. -An example on Unix: +An example on Linux: ``` -/home/myusername/.emulationstation/downloaded_media/c64/screenshots/ +/home/myusername/ES-DE/downloaded_media/c64/screenshots/ ``` An example on macOS: ``` -/Users/myusername/.emulationstation/downloaded_media/c64/screenshots/ +/Users/myusername/ES-DE/downloaded_media/c64/screenshots/ ``` An example on Windows (installer release): ``` -C:\Users\Myusername\.emulationstation\downloaded_media\c64\screenshots\ +C:\Users\Myusername\ES-DE\downloaded_media\c64\screenshots\ ``` An example on Windows (portable release): ``` -EmulationStation-DE\.emulationstation\downloaded_media\c64\screenshots\ +ES-DE\ES-DE\downloaded_media\c64\screenshots\ ``` The media directories per game system are: @@ -2744,8 +2848,8 @@ The media files must correspond exactly to the game files. Take for example this For this example, the filename structure needs to look like the following: ``` -~/.emulationstation/downloaded_media/c64/screenshots/Multidisk/Last Ninja 2/Last Ninja 2.jpg -~/.emulationstation/downloaded_media/c64/videos/Multidisk/Last Ninja 2/Last Ninja 2.mp4 +~/ES-DE/downloaded_media/c64/screenshots/Multidisk/Last Ninja 2/Last Ninja 2.jpg +~/ES-DE/downloaded_media/c64/videos/Multidisk/Last Ninja 2/Last Ninja 2.mp4 ``` Note that there is seemingly an exception to this logic if the _Directories interpreted as files_ functionality has been used, in which case the "file extension" added to the directory is also included in the game media filenames. Take for example the following ScummVM game: @@ -2756,15 +2860,15 @@ Note that there is seemingly an exception to this logic if the _Directories inte The media files for this directory which is interpreted as a file will be: ``` -~/.emulationstation/downloaded_media/scummvm/screenshots/dig.scummvm.png -~/.emulationstation/downloaded_media/scummvm/videos/dig.scummvm.mp4 +~/ES-DE/downloaded_media/scummvm/screenshots/dig.scummvm.png +~/ES-DE/downloaded_media/scummvm/videos/dig.scummvm.mp4 ``` This is not a bug as these are not really file extensions after all, it's just a directory with a dot in the filename that happens to look like a file extension because that's how the _Directories interpreted as files_ logic works. For images .jpg and .png file extensions are supported and for videos .avi, .mkv, .mov, .mp4 and .wmv are supported. -Remember that on Unix filenames are case sensitive, and as well the file extensions must be in lower case, such as .png instead of .PNG or .Png or the file won't be found. +Remember that on Linux filenames are case sensitive, and as well the file extensions must be in lower case, such as .png instead of .PNG or .Png or the file won't be found. It's possible to change the game media directory location from within ES-DE, for this see the option _Game media directory_ in the _Other settings_ menu. @@ -2975,10 +3079,6 @@ If file hash searching is enabled, then this specifies the maximum allowed file Affects both overwriting of metadata as well as actual game media files on the filesystem. Even with this option disabled, metadata entries which are set to their default values will be populated by the scraper. In other words, this option only affects overwriting of previously scraped data, or data manually entered via the metadata editor. Game names are considered as set to their default values if either corresponding to the physical game file on disk minus the extension (e.g. the entry _Commando_ if the file is named _Commando.zip_), or for arcade games if corresponding to the MAME names as defined in the bundled mamenames.xml. Note that this setting does not affect generated miximages, that is instead controlled by the setting _Overwrite miximages (scraper/offline generator)_ found in the miximage settings menu. -**Halt on invalid media files** - -With this setting enabled, if any media files returned by the scraper seem to be invalid, the scraping is halted and an error message is presented where it's possible to retry or cancel the scraping of the specific game. In the case of multi-scraping it's also possible to skip the game and proceed to the next one in the queue. With this setting disabled, all media files will always be accepted and saved to disk. The file verification is quite basic and future versions may improve on this by using file checksums or other file integrity checks. There is an exception in place for box back covers when using ScreenScraper. As many of these specific images are broken, there is an automatic filter built in that is always active and which removes blank images and those containing only a few lines of pixels. - **Search using file hashes (non-interactive mode)** _(ScreenScraper only)_ When running the non-interactive scraper it's possible to search using a hash value calculated from the actual game file. Assuming ScreenScraper has a match for your file in their database, this will lead to 100% accuracy as the game name will be completely ignored. If there is no match for the hash value, then a fallback will be made to the game name and the normal search logic applies. The maximum allowed file size to apply this type of search to can be set using the _Hash searches max file size_ slider. Note that file hash searching can increase scraping times significantly if applied to large game files as the entire file needs to be read and processed to calculate its hash value. And obviously file hash searching will not work for directories, scripts, shortcuts, .m3u files and so on which will have no matching entries in the ScreenScraper database. @@ -3039,6 +3139,10 @@ Themes optionally support variants which are a type of theme profiles defined by If the theme author has included multiple color schemes, then these can be selected between using this menu option. +**Theme font size** + +If the theme author has included support for multiple font/text sizes, then these can be selected between using this menu option. Possible choices are _medium, large, small, extra large_ and _extra small_. What layout changes these font size options actually make is completely up to the theme author. + **Theme aspect ratio** Themes could optionally be optimized for different screen aspect ratios. ES-DE supports 16:9, 16:10, 3:2, 4:3, 5:4, 21:9 and 32:9 in both horizontal and vertical orientation, but it's completely up to the theme author which of these are actually supported by the theme. It's normally best to leave this setting at _Automatic_ in which case ES-DE will automatically select the aspect ratio that most closely matches the screen resolution. The _Automatic_ option is however only available if the theme supports at least two aspect ratios. @@ -3057,7 +3161,7 @@ If set to _None_, the system view will be displayed on startup. Any other value **Systems sorting** -The order in which to sort the game systems. The default option is _Full names or custom_ which will sort by full system names, unless there is a ~/.emulationstation/custom_systems/es_systems_sorting.xml file present which will then be used instead. The other options are using the bundled sorting configuration files for _Release year_ or _Manufacturer, release year_ or _HW type, release year_ or _Manufacturer, HW type, release year_. If using any of these bundled sorting files, then any ~/.emulationstation/custom_systems/es_systems_sorting.xml will be ignored. When changing this setting ES-DE will automatically reload. +The order in which to sort the game systems. The default option is _Full names or custom_ which will sort by full system names, unless there is a ~/ES-DE/custom_systems/es_systems_sorting.xml file present which will then be used instead. The other options are using the bundled sorting configuration files for _Release year_ or _Manufacturer, release year_ or _HW type, release year_ or _Manufacturer, HW type, release year_. If using any of these bundled sorting files, then any ~/ES-DE/custom_systems/es_systems_sorting.xml will be ignored. When changing this setting ES-DE will automatically reload. **Game default sort order** @@ -3117,7 +3221,7 @@ With this option enabled, there will be an overlay displayed when quickly scroll **Enable virtual keyboard** -This enables a virtual (on-screen) keyboard that can be used at various places throughout the application to input text and numbers using a controller. The Shift and Alt keys can be toggled individually or combined to access many special characters. The general use of the virtual keyboard should hopefully be self-explanatory. +This enables a virtual (on-screen) keyboard that can be used at various places throughout the application to input text and numbers using a controller. The Shift and Alt keys can be toggled individually or combined to access many special characters. The general use of the virtual keyboard should hopefully be self-explanatory. On Android the virtual keyboard from the operating system will be used if this setting has been disabled. **Enable toggle favorites button** @@ -3213,7 +3317,7 @@ Whether to search the custom image directory recursively. **Custom image directory** -The directory for custom images. The tilde `~` symbol can be used which will expand to the user home directory. It's also possible to use the %ESPATH% and %ROMPATH% variables which will set the directory relative to the ES-DE binary directory or the ROM directory. +The directory for custom images. The tilde `~` symbol can be used which will expand to the user home directory. It's also possible to use the %ESPATH% and %ROMPATH% variables which will set the directory relative to the ES-DE binary directory or the ROM directory. Images in the .jpg, .png, .webp, .svg and unanimated .gif formats are supported. #### Video screensaver settings @@ -3283,13 +3387,33 @@ Settings related to the input devices, i.e. the keyboard and controllers. This setting gives the ability to choose between the controller types _Xbox, Xbox 360, PlayStation 1/2/3, PlayStation 4, PlayStation 5, Switch Pro_ and _SNES_. Doing so alters the help icons and help text as well as the icons and text for the input device configurator. The setting is only cosmetic and does not change the controller behavior or the controller button mappings. +**Touch overlay size** _(Android only)_ + +If the touch input overlay has been enabled, then this setting makes it possible to select between a _medium, large, small_ or _extra small_ overlay size. + +**Touch overlay opacity** _(Android only)_ + +Sets the opacity of the input overlay to _normal, low_ or _very low_. + +**Touch overlay fade-out time** _(Android only)_ + +How long, in seconds, to display the overlay before fading it. Tapping anywhere on the screen will bring back the overlay if it's been faded out. + +**Enable touch overlay** _(Android only)_ + +The touch overlay applies a layer of virtual buttons on top of the ES-DE window. This makes it possible to use the application on devices that lack physical buttons, such as a mobile phone or tablet. Be careful to not accidentally disable this setting as you may lock yourself out of the application. If you do that, you'll need to temporarily plug in a controller or keyboard to enable the setting again, or you could clear the ES-DE storage in the Android App settings which will force the configurator to run on next startup. + **Only accept input from first controller** If enabling this option, only the first controller detected during startup will send its input to ES-DE (the keyboard input is unaffected by this setting and will be enabled regardless). This is a good way to limit potential chaos with multiple persons fighting over which games to play. Note that disconnecting and reconnecting controllers while ES-DE is running may change what is considered the first controller. This setting does not affect the emulators in any way, it's only applied to ES-DE. Another issue is that some wireless controllers have buggy drivers and will register as two devices, meaning all button presses will be registered twice inside ES-DE. Using this option is one solution to the problem, although it's also possible to blacklist the extra controller entry, as described [here](INSTALL.md#adding-custom-controller-profiles). +**Swap the A/B and X/Y buttons** + +When enabling this setting the functions for the A/B and X/Y buttons will be swapped and the helpsystem will be updated accordingly. The primary purpose of this setting is for using controllers like Nintendo Switch Pro and some handhelds which have swapped the physical positions of these buttons. With this setting enabled you'll be able to rely on your muscle memory from using any other controller type with a normal button layout. Note that the button swap does not apply to the keyboard which leads to a slight inconsistency as the helpsystem will only match the controller and not the keyboard. + **Ignore keyboard input** -If this setting is enabled then all keyboard input will be ignored, except the quit shortcut used to shut down the application. The main reason for ignoring keyboard input is if running Steam in parallel to ES-DE and you need to use the Steam Input's _Desktop Layout_ functionality to send keyboard input using the controller. In this case double or conflicting input will be sent to ES-DE as both the controller and keyboard events are read by the application. It's however generally a better idea to disable this functionality altogether in Steam and leave the ES-DE setting untouched. If you accidentally enable this setting when using a keyboard as input device, then you'll either need to plug in a controller to disable it again, or you'll need to modify the _InputIgnoreKeyboard_ entry in the ~/.emulationstation/es_settings.xml configuration file. +If this setting is enabled then all keyboard input will be ignored, except the quit shortcut used to shut down the application. The main reason for ignoring keyboard input is if running Steam in parallel to ES-DE and you need to use the Steam Input's _Desktop Layout_ functionality to send keyboard input using the controller. In this case double or conflicting input will be sent to ES-DE as both the controller and keyboard events are read by the application. It's however generally a better idea to disable this functionality altogether in Steam and leave the ES-DE setting untouched. If you accidentally enable this setting when using a keyboard as input device, then you'll either need to plug in a controller to disable it again, or you'll need to modify the _InputIgnoreKeyboard_ entry in the ~/ES-DE/settings/es_settings.xml configuration file. **Configure keyboard and controllers** @@ -3348,13 +3472,13 @@ _The system-wide alternative emulators interface. An entry in bold and with a ge **Game media directory** -This setting defines the directory for game media, i.e. images, videos and PDF manuals that have normally been downloaded by the scraper. The default location is _~/.emulationstation/downloaded_media_ +This setting defines the directory for game media, i.e. images, videos and PDF manuals that have normally been downloaded by the scraper. The default location is _~/ES-DE/downloaded_media_ **VRAM limit** The amount of video RAM to use for the application. Defaults to 512 MiB (192 MiB on the Raspberry Pi) which works fine most of the time when using moderately demanding themes with medium-sized collections at up to 4K display resolution. For large collections (as in many different systems rather than many games per system) in combination with demanding themes which use lots of full-screen images and similar it's recommended to increase this number to 1024 MiB or possibly higher to avoid stuttering and texture pop-in. Enabling the GPU statistics overlay gives some indications regarding the amount of texture memory currently used, which is helpful to determine a reasonable value for this setting. The allowed range for the settings is 128 to 2048 MiB. If you try to set it lower or higher than this by passing such values as command line parameters or by editing the es_settings.xml file manually, ES-DE will log a warning and automatically adjust to a value within the allowable range. -**Anti-aliasing (MSAA) (requires restart)** +**Anti-aliasing (MSAA) (requires restart)** _(All operating systems except Android)_ Sets the level of anti-aliasing for the application. You can select between _disabled_, _2x_ or _4x_. Note that this is a potentially dangerous option which may prevent the application from starting altogether with some GPU drivers. If you're unable to run the application after changing this option then you can reset it via the `--anti-aliasing 0` command line option. Be aware that enabling anti-aliasing has a slight to moderate performance impact. @@ -3386,7 +3510,7 @@ For platforms and package formats where the previous setting above is available With this setting enabled, the taskbar will be hidden when launching ES-DE, and it will be restored when the application exits. This can make for a more seamless experience as the taskbar could otherwise flash by briefly when launching and returning from games. -**Run in background (while game is launched)** +**Run in background (while game is launched)** _(All operating systems except Android)_ Enabling this option makes ES-DE continue to run while a game is launched. This is normally not recommended as it leads to a slightly strange application behavior and it also removes the ability to capture return codes and log output from the emulators. Generally this option should only be enabled if there are issues with launching games while suspending ES-DE. Note however that some systems like Valve Steam will always keep ES-DE running in the background because they require it for technical reasons (i.e. those systems will override this menu option). @@ -3400,7 +3524,7 @@ If enabled, you will be able to select alternative emulators per game using the **Show hidden files and folders** -If this option is disabled, hidden files and folders within the ROM directory tree are excluded from ES-DE. On Unix and macOS this means those starting with a dot, and on Windows it's those set as hidden by using an NTFS attribute. This setting is only intended for special situations and is not to be confused with the next option below which hides files based on metadata configuration within ES-DE. When changing this setting ES-DE will automatically reload. +If this option is disabled, hidden files and folders within the ROM directory tree are excluded from ES-DE. On Linux and macOS this means those starting with a dot, and on Windows it's those set as hidden by using an NTFS attribute. This setting is only intended for special situations and is not to be confused with the next option below which hides files based on metadata configuration within ES-DE. When changing this setting ES-DE will automatically reload. **Show hidden games** @@ -3418,7 +3542,7 @@ If enabled, only games that have metadata saved to the gamelist.xml files will b MAME software list names for all arcade systems are automatically expanded to their full game names using a bundled MAME name translation file. By default any extra information from this file that is located inside brackets is removed. This includes information like region, version/revision, license, release date and more. By setting this option to disabled that information is retained. Note that this is only applicable for any game names which have not been scraped as the scaper will overwrite the expanded information with whatever value the scraper service returns. It's however possible to disable scraping of game names altogether as covered elsewhere in this guide. -**Disable desktop composition (requires restart)** _(Unix and X11/Xorg only)_ +**Disable desktop composition (requires restart)** _(Linux and X11/Xorg only)_ The window manager desktop composition can adversely affect the framerate of ES-DE, especially on weaker graphics cards and when running at higher resolution. As such the desktop compositor can be disabled when running ES-DE, although the window manager has to be configured to allow applications to do this for the option to have any effect. Note that enabling this setting can cause problems with some graphics drivers so if you experience strange flickering and similar, then make sure to keep this setting disabled. In case of such issues, make sure that the emulator is also not blocking the composition (e.g. RetroArch has a corresponding option). This setting has no effect if using Wayland, it only applies to X11/Xorg. @@ -3434,7 +3558,7 @@ Displays the framerate and VRAM statistics as an overlay. This can be useful to Enabling or disabling the menu when the UI mode is set to _Kid_. Mostly intended for testing purposes as it's not recommended to enable the menu in this restricted mode. -**Show quit menu (reboot and power off entries)** _(All operating systems except macOS)_ +**Show quit menu (reboot and power off entries)** _(All operating systems except macOS and Android)_ With this setting enabled, there is a Quit menu shown as the last entry on the main menu which provides options to quit ES-DE, to reboot the computer or to power off the computer. With this setting disabled, there will simply be an entry to quit the application instead of the complete quit menu. @@ -3454,21 +3578,21 @@ This utility will create all game system directories inside your ROM directory t This utility will rescan the ROM directory for any changes such as added or removed games and systems without having to restart the application. But don't use this utility to reload changes to gamelist.xml files that you have made outside ES-DE as this can lead to data corruption. If you need to manually edit your gamelist.xml files then do this while ES-DE is shut down. -### Quit / Quit EmulationStation +### Quit / Quit ES-DE -The _Quit_ menu or _Quit EmulationStation_ entry as described by the _Show quit menu (reboot and power off entries)_ option above. +The _Quit_ menu or _Quit ES-DE_ entry as described by the _Show quit menu (reboot and power off entries)_ option above. If the menu is enabled, these are its entries: -**Quit EmulationStation** +**Quit ES-DE** -If the option _When to save game metadata_ has been set to _On exit_, the gamelist.xml files will be updated at this point. This applies also if the Quit menu is disabled and replaced by the _Quit EmulationStation_ entry. +If the option _When to save game metadata_ has been set to _On exit_, the gamelist.xml files will be updated at this point. This applies also if the Quit menu is disabled and replaced by the _Quit ES-DE_ entry. -**Reboot system** _(All operating systems except macOS)_ +**Reboot system** _(All operating systems except macOS and Android)_ Self explanatory. -**Power off system** _(All operating systems except macOS)_ +**Power off system** _(All operating systems except macOS and Android)_ Self explanatory. @@ -3770,9 +3894,9 @@ _Example of custom collections, here configured as genres._ _When editing a custom collection and the theme uses a textlist, then a tick symbol will be displayed for any game that is part of the collection._ -The way that custom collections are implemented is very simple. There is a single configuration file per collection inside the folder `~/.emulationstation/collections` +The way that custom collections are implemented is very simple. There is a single configuration file per collection inside the folder `~/ES-DE/collections` -For this example a file will have been created named `~/.emulationstation/collections/custom-Platform.cfg` +For this example a file will have been created named `~/ES-DE/collections/custom-Platform.cfg` The file contents is simply a list of ROM files, such as the following: @@ -3788,7 +3912,7 @@ The file contents is simply a list of ROM files, such as the following: Any changes to custom collections, for example adding or removing a game, will be immediately written to the corresponding collection configuration file. -If you copy or migrate a collection from a previous version of EmulationStation or if you're setting up ES-DE on a new computer, the collection will not be enabled by just copying its configuration file to the `~/.emulationstation/collections` directory. You always need to explicitly enable each collection via the menu. +If you copy or migrate a collection from a previous version of EmulationStation or if you're setting up ES-DE on a new computer, the collection will not be enabled by just copying its configuration file to the `~/ES-DE/collections` directory. You always need to explicitly enable each collection via the menu. If you're migrating from a previous version of EmulationStation that has absolute paths in the collection files, then these will be rewritten with the %ROMPATH% variable the first time you make a change to the collection. @@ -3808,9 +3932,9 @@ The **System name** column corresponds to the directory where you should put you For the **Full name** column, text inside square brackets [] are comments and not part of the actual system name. -The **Default emulator** column lists the primary emulator as configured in es_systems.xml. If this differs between Unix, macOS and Windows then it's specified in square brackets, such as [UW] for Unix and Windows and [M] for macOS. +The **Default emulator** column lists the primary emulator as configured in es_systems.xml. If this differs between Linux, macOS and Windows then it's specified in square brackets, such as [LW] for Linux and Windows and [M] for macOS. -The **Alternative emulators** column lists additional emulators configured in es_systems.xml that can be selected per system and per game. In the same manner as the _Default emulator_ column, differences between Unix, macOS and Windows are marked using square brackets. +The **Alternative emulators** column lists additional emulators configured in es_systems.xml that can be selected per system and per game. In the same manner as the _Default emulator_ column, differences between Linux, macOS and Windows are marked using square brackets. The **Needs BIOS** column indicates if any BIOS/system ROMs are required. Additional details should be covered by the emulator documentation. @@ -3836,7 +3960,7 @@ On Windows the following emulators provide a way to inform ES-DE where they have * Yuzu Default emulator/Alternative emulators columns: \ -**[U]**: Unix/Linux, **[M]**: macOS, **[W]**: Windows +**[L]**: Linux, **[M]**: macOS, **[W]**: Windows All emulators are RetroArch cores unless marked as **(Standalone)**, **(Wine)** or **(Proton)** @@ -3847,190 +3971,190 @@ The **@** symbol indicates that the emulator is _deprecated_ and will be removed | 3do | 3DO Interactive Multiplayer | Opera | | Yes | | | adam | Coleco Adam | MAME [Diskette] **(Standalone)** | MAME [Tape] **(Standalone)**,
MAME [Cartridge] **(Standalone)**,
MAME [Software list] **(Standalone)** | Yes | | | ags | Adventure Game Studio Game Engine | _Shortcut or script_ | | No | | -| amiga | Commodore Amiga | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amiga1200 | Commodore Amiga 1200 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amiga600 | Commodore Amiga 600 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | -| amigacd32 | Commodore Amiga CD32 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga | Commodore Amiga | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga1200 | Commodore Amiga 1200 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amiga600 | Commodore Amiga 600 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| amigacd32 | Commodore Amiga CD32 | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | | amstradcpc | Amstrad CPC | Caprice32 | CrocoDS,
CPCemu **(Standalone)**,
MAME **(Standalone)** | Yes for MAME | Single archive or disk file | | android | Google Android | BlueStacks **(Standalone)** [W] | | No | Shortcut (.lnk) file | -| apple2 | Apple II | LinApple **(Standalone)** [U],
Mednafen **(Standalone)** [M],
AppleWin **(Standalone)** [W] | Mednafen **(Standalone)** [UW],
MAME - Current,
MAME **(Standalone)** | Yes for Mednafen and MAME | See the specific _Apple II_ section elsewhere in this guide | +| apple2 | Apple II | LinApple **(Standalone)** [L],
Mednafen **(Standalone)** [M],
AppleWin **(Standalone)** [W] | Mednafen **(Standalone)** [LW],
MAME - Current,
MAME **(Standalone)** | Yes for Mednafen and MAME | See the specific _Apple II_ section elsewhere in this guide | | apple2gs | Apple IIGS | MAME - Current | MAME **(Standalone)** | Yes | See the specific _Apple IIGS_ section elsewhere in this guide | -| arcade | Arcade | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [UW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| arcade | Arcade | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [LW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | arcadia | Emerson Arcadia 2001 | MAME - Current | MAME **(Standalone)** | No | Single archive or ROM file | | archimedes | Acorn Archimedes | MAME [Model A440/1] **(Standalone)** | MAME [Model A3000] **(Standalone)**,
MAME [Model A310] **(Standalone)**,
MAME [Model A540] **(Standalone)** | Yes | | | arduboy | Arduboy Miniature Game System | Arduous | | No | Single archive or .hex file | | astrocde | Bally Astrocade | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| atari2600 | Atari 2600 | Stella | Stella 2014,
Stella **(Standalone)**,
Gopher2600 **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | +| atari2600 | Atari 2600 | Stella | Stella 2014,
Stella **(Standalone)**,
Gopher2600 **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | atari5200 | Atari 5200 | a5200 | Atari800,
Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | Single archive or ROM file | | atari7800 | Atari 7800 ProSystem | ProSystem | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | atari800 | Atari 800 | Atari800 | Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | | -| atarijaguar | Atari Jaguar | Virtual Jaguar | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [U],
BigPEmu **(Proton)** [U],
MAME **(Standalone)** | Yes for MAME | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | -| atarijaguarcd | Atari Jaguar CD | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [U] | BigPEmu **(Proton)** [U] | No | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | -| atarilynx | Atari Lynx | Handy | Beetle Lynx,
Mednafen **(Standalone)** | | | +| atarijaguar | Atari Jaguar | Virtual Jaguar | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [L],
BigPEmu **(Proton)** [L],
MAME **(Standalone)** | Yes for MAME | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | +| atarijaguarcd | Atari Jaguar CD | BigPEmu **(Standalone)** [W],
BigPEmu **(Wine)** [L] | BigPEmu **(Proton)** [L] | No | See the specific _Atari Jaguar and Atari Jaguar CD_ section elsewhere in this guide | +| atarilynx | Atari Lynx | Handy | Beetle Lynx,
Mednafen **(Standalone)** | No | Single archive or ROM file | | atarist | Atari ST [also STE and Falcon] | Hatari | Hatari **(Standalone)** | Yes | Single archive or image file for single-diskette games, .m3u playlist for multi-diskette games | | atarixe | Atari XE | Atari800 | Atari800 **(Standalone)**,
Altirra **(Standalone)** [W] | Yes except for Altirra | | | atomiswave | Sammy Corporation Atomiswave | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Depends | Single archive file | | bbcmicro | Acorn Computers BBC Micro | MAME **(Standalone)** | | Yes | Single archive or diskette image file | | c64 | Commodore 64 | VICE x64sc Accurate | VICE x64sc Accurate **(Standalone)**,
VICE x64 Fast,
VICE x64 SuperCPU,
VICE x128,
Frodo | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | | cdimono1 | Philips CD-i | SAME CDi | CDi 2015 @,
MAME **(Standalone)** | Yes | Single .bin/.cue pair | -| cdtv | Commodore CDTV | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [UM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | +| cdtv | Commodore CDTV | PUAE | PUAE 2021,
FS-UAE **(Standalone)**,
Amiberry **(Standalone)** [LM] | Yes | See the specific _Commodore Amiga and CDTV_ section elsewhere in this guide | | chailove | ChaiLove Game Engine | ChaiLove | | | | | channelf | Fairchild Channel F | FreeChaF | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | coco | Tandy Color Computer | XRoar CoCo 2 NTSC **(Standalone)** | XRoar CoCo 2 PAL **(Standalone)** | Yes | See the specific _Tandy Color Computer_ section elsewhere in this guide | | colecovision | Coleco ColecoVision | blueMSX | Gearcoleco,
openMSX **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | -| consolearcade | Console Arcade Systems | MAME - Current | MAME **(Standalone)**,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Mednafen [Sega Saturn] **(Standalone)**,
Play! **(Standalone)**,
RPCS3 Shortcut **(Standalone)**,
Triforce **(Standalone)** [UW],
xemu **(Standalone)**,
Cxbx-Reloaded **(Standalone)** [W],
_Shortcut or script_ | Depends | See the specific _Console Arcade Systems_ section elsewhere in this guide | -| cps | Capcom Play System | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps1 | Capcom Play System I | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-1 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps2 | Capcom Play System II | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-2 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| cps3 | Capcom Play System III | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| consolearcade | Console Arcade Systems | MAME - Current | MAME **(Standalone)**,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Mednafen [Sega Saturn] **(Standalone)**,
Play! **(Standalone)**,
RPCS3 Shortcut **(Standalone)**,
Triforce **(Standalone)** [LW],
xemu **(Standalone)**,
Cxbx-Reloaded **(Standalone)** [W],
_Shortcut or script_ | Depends | See the specific _Console Arcade Systems_ section elsewhere in this guide | +| cps | Capcom Play System | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps1 | Capcom Play System I | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-1 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps2 | Capcom Play System II | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-2 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| cps3 | Capcom Play System III | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
FB Alpha 2012 CPS-3 | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | crvision | VTech CreatiVision | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | daphne | Daphne Arcade LaserDisc Emulator | Hypseus [Daphne] **(Standalone)** | Hypseus [Singe] **(Standalone)**,
MAME - Current,
MAME **(Standalone)**,
DirkSimple | Depends | See the specific _LaserDisc Games_ section elsewhere in this guide | -| desktop | Desktop Applications | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | -| doom | Doom | PrBoom | PrBoom+ **(Standalone)**,
Boom 3 [UW],
Boom 3 xp [UW],
_Shortcut or script_ | No | | +| desktop | Desktop Applications | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| doom | Doom | PrBoom | PrBoom+ **(Standalone)**,
Boom 3 [LW],
Boom 3 xp [LW],
_Shortcut or script_ | No | | | dos | DOS (PC) | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN,
DOSBox-X **(Standalone)**,
DOSBox Staging **(Standalone)** | No | See the specific _DOS / PC_ section elsewhere in this guide | | dragon32 | Dragon Data Dragon 32 | XRoar Dragon 32 **(Standalone)** | XRoar Dragon 64 **(Standalone)** | Yes | See the specific _Dragon 32 and Tano Dragon_ section elsewhere in this guide | | dreamcast | Sega Dreamcast | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Redream **(Standalone)**,
Demul **(Standalone)** [W] | No | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | | easyrpg | EasyRPG Game Engine | EasyRPG | EasyRPG Player **(Standalone)** | No | See the specific _EasyRPG Game Engine_ section elsewhere in this guide | | electron | Acorn Electron | MAME [Tape] **(Standalone)** | MAME [Diskette DFS] **(Standalone)**,
MAME [Diskette ADFS] **(Standalone)** | Yes | Single archive, or single tape or diskette image file | -| emulators | Emulators | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| emulators | Emulators | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Ports and desktop applications_ section elsewhere in this guide | | epic | Epic Games Store | Epic Games Store **(Standalone)** | | No | Shortcut (.desktop/.app/.lnk) file | -| famicom | Nintendo Family Computer | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
QuickNES,
puNES **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [U],
3dSen **(Proton)** [U],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For Famicom games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | +| famicom | Nintendo Family Computer | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
QuickNES,
puNES **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [L],
3dSen **(Proton)** [L],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For Famicom games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | | fba | FinalBurn Alpha | FB Alpha 2012 | FB Alpha 2012 Neo Geo,
FB Alpha 2012 CPS-1,
FB Alpha 2012 CPS-2,
FB Alpha 2012 CPS-3 | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| fbneo | FinalBurn Neo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [UW] | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| fds | Nintendo Famicom Disk System | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
Mednafen **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | -| flash | Adobe Flash | Ruffle **(Standalone)** | Lightspark **(Standalone)** [U],
ArcadeFlashWeb **(Standalone)** [W] | No | Single .swf file | +| fbneo | FinalBurn Neo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [LW] | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| fds | Nintendo Famicom Disk System | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
Mednafen **(Standalone)**,
ares **(Standalone)** | Yes | Single archive or ROM file | +| flash | Adobe Flash | Ruffle **(Standalone)** | Lightspark **(Standalone)** [L],
ArcadeFlashWeb **(Standalone)** [W] | No | Single .swf file | | fm7 | Fujitsu FM-7 | MAME [FM-7 Diskette] **(Standalone)** | MAME [FM-7 Tape] **(Standalone)**,
MAME [FM-7 Software list] **(Standalone)**,
MAME [FM77AV Diskette] **(Standalone)**,
MAME [FM77AV Tape] **(Standalone)**,
MAME [FM77AV Software list] **(Standalone)** | Yes | For tape files you need to manually start the cassette player from the MAME menu after the "load" command, as well as entering the "run" command after loading is complete | -| fmtowns | Fujitsu FM Towns | MAME - Current,
MAME **(Standalone)** | Tsugaru **(Standalone)** [UW] | Yes | See the specific _Fujitsu FM Towns_ section elsewhere in this guide | +| fmtowns | Fujitsu FM Towns | MAME - Current,
MAME **(Standalone)** | Tsugaru **(Standalone)** [LW] | Yes | See the specific _Fujitsu FM Towns_ section elsewhere in this guide | | fpinball | Future Pinball | Future Pinball **(Standalone)** [W] | | No | | | gamate | Bit Corporation Gamate | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| gameandwatch | Nintendo Game and Watch | MAME Local Artwork **(Standalone)** | MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | +| gameandwatch | Nintendo Game and Watch | MAME - Current | MAME Local Artwork **(Standalone)**,
MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | | gamecom | Tiger Electronics Game.com | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | -| gamegear | Sega Game Gear | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
SMS Plus GX,
PicoDrive,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| gb | Nintendo Game Boy | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [UW],
TGB Dual,
Mesen-S,
Mesen **(Standalone)** [UW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| gba | Nintendo Game Boy Advance | mGBA | mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
VBA Next,
gpSP,
ares **(Standalone)**,
SkyEmu **(Standalone)** | Yes for ares | Single archive or ROM file | -| gbc | Nintendo Game Boy Color | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [UW],
TGB Dual,
Mesen-S,
Mesen **(Standalone)** [UW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| gc | Nintendo GameCube | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [UW],
Triforce **(Standalone)** [UW] | No | Disc image file for single-disc games, .m3u playlist for multi-disc games | -| genesis | Sega Genesis | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| gamegear | Sega Game Gear | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
SMS Plus GX,
PicoDrive,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| gb | Nintendo Game Boy | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [LW],
TGB Dual,
DoubleCherryGB [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| gba | Nintendo Game Boy Advance | mGBA | mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
VBA Next,
gpSP,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | Yes for ares | Single archive or ROM file | +| gbc | Nintendo Game Boy Color | Gambatte | SameBoy,
SameBoy **(Standalone)**,
Gearboy,
Gearboy **(Standalone)** [LW],
TGB Dual,
DoubleCherryGB [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
bsnes,
mGBA,
mGBA **(Standalone)**,
VBA-M,
VBA-M **(Standalone)**,
Mednafen **(Standalone)**,
ares **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| gc | Nintendo GameCube | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [LW],
Triforce **(Standalone)** [LW] | No | Disc image file for single-disc games, .m3u playlist for multi-disc games | +| genesis | Sega Genesis | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | gmaster | Hartung Game Master | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | gx4000 | Amstrad GX4000 | Caprice32 | CrocoDS,
MAME **(Standalone)** | No | Single archive or ROM file | | intellivision | Mattel Electronics Intellivision | FreeIntv | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | j2me | Java 2 Micro Edition (J2ME) | SquirrelJME | KEmulator **(Standalone)** [W] | No | Single .jar file | | kodi | Kodi Home Theatre Software | Kodi **(Standalone)** | | No | Shortcut (.desktop/.app/.lnk) file | | laserdisc | LaserDisc Games | Hypseus [Daphne] **(Standalone)** | Hypseus [Singe] **(Standalone)**,
MAME - Current,
MAME **(Standalone)**,
DirkSimple | Depends | See the specific _LaserDisc Games_ section elsewhere in this guide | -| lcdgames | LCD Handheld Games | MAME Local Artwork **(Standalone)** | MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | +| lcdgames | LCD Handheld Games | MAME - Current | MAME Local Artwork **(Standalone)**,
MAME **(Standalone)**,
Handheld Electronic (GW) | No | See the specific _LCD handheld games_ section elsewhere in this guide | | lowresnx | LowRes NX Fantasy Console | LowRes NX | | No | Single ROM file | -| lutris | Lutris Open Gaming Platform | Lutris **(Standalone)** [U] | | No | See the specific _Lutris_ section elsewhere in this guide | +| lutris | Lutris Open Gaming Platform | Lutris **(Standalone)** [L] | | No | See the specific _Lutris_ section elsewhere in this guide | | lutro | Lutro Game Engine | Lutro | | | | | macintosh | Apple Macintosh | MAME Mac SE Bootable **(Standalone)** | MAME Mac SE Boot Disk **(Standalone)**,
MAME Mac Plus Bootable **(Standalone)**,
MAME Mac Plus Boot Disk **(Standalone)**,
Basilisk II **(Standalone)**,
SheepShaver **(Standalone)** | Yes | See the specific _Apple Macintosh_ section elsewhere in this guide | -| mame | Multiple Arcade Machine Emulator | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [UW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [UW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [UW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| mame-advmame | AdvanceMAME | AdvanceMAME **(Standalone)** [UW] | | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| mastersystem | Sega Master System | Genesis Plus GX | Genesis Plus GX Wide,
SMS Plus GX,
Gearsystem,
PicoDrive,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| mame | Multiple Arcade Machine Emulator | MAME - Current | MAME 2010,
MAME 2003-Plus,
MAME 2000,
MAME **(Standalone)**,
FinalBurn Neo,
FinalBurn Neo **(Standalone)** [LW],
FB Alpha 2012,
Flycast,
Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Kronos [LW],
Model 2 Emulator **(Standalone)** [W],
Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
Supermodel **(Standalone)** [LW],
_Shortcut or script_ | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| mame-advmame | AdvanceMAME | AdvanceMAME **(Standalone)** [LW] | | Depends | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| mastersystem | Sega Master System | Genesis Plus GX | Genesis Plus GX Wide,
SMS Plus GX,
Gearsystem,
PicoDrive,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | megacd | Sega Mega-CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | | megacdjp | Sega Mega-CD [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | -| megadrive | Sega Mega Drive | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| megadrivejp | Sega Mega Drive [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [U],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| megadrive | Sega Mega Drive | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| megadrivejp | Sega Mega Drive [Japan] | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
BlastEm,
BlastEm **(Standalone)** [L],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | megaduck | Creatronic Mega Duck | SameDuck | MAME - Current,
MAME **(Standalone)** | No | Single archive or ROM file | | mess | Multi Emulator Super System | MESS 2015 | | | | -| model2 | Sega Model 2 | Model 2 Emulator **(Standalone)** [W],
MAME - Current [UM] | Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
MAME - Current [W],
MAME **(Standalone)**,
Model 2 Emulator **(Wine)** [U],
Model 2 Emulator **(Proton)** [U] | Yes for MAME | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| model3 | Sega Model 3 | Supermodel **(Standalone)** [UW] | | No | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| model2 | Sega Model 2 | Model 2 Emulator **(Standalone)** [W],
MAME - Current [LM] | Model 2 Emulator [Suspend ES-DE] **(Standalone)** [W],
MAME - Current [W],
MAME **(Standalone)**,
Model 2 Emulator **(Wine)** [L],
Model 2 Emulator **(Proton)** [L] | Yes for MAME | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| model3 | Sega Model 3 | Supermodel **(Standalone)** [LW] | | No | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | | moto | Thomson MO/TO Series | Theodore | | | | | msx | MSX | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msx1 | MSX1 | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msx2 | MSX2 | blueMSX | fMSX,
openMSX **(Standalone)**,
openMSX No Machine **(Standalone)**,
ares **(Standalone)** | Yes | | | msxturbor | MSX Turbo R | blueMSX | openMSX **(Standalone)**,
openMSX No Machine **(Standalone)** | Yes | | | mugen | M.U.G.E.N Game Engine | Ikemen GO **(Standalone)** | | No | See the specific _M.U.G.E.N Game Engine_ section elsewhere in this guide | -| multivision | Othello Multivision | Gearsystem | | | | +| multivision | Othello Multivision | Gearsystem | Mesen **(Standalone)** [LW] | No | Single archive or ROM file | | naomi | Sega NAOMI | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | | naomi2 | Sega NAOMI 2 | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)**,
Demul **(Standalone)** [W] | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | | naomigd | Sega NAOMI GD-ROM | Flycast | Flycast **(Standalone)**,
Flycast Dojo **(Standalone)** | Yes | Single archive file + .chd file in subdirectory if GD-ROM game | -| n3ds | Nintendo 3DS | Citra [UW],
Citra **(Standalone)** [M] | Citra 2018 [UW],
Citra **(Standalone)** [UW] | No | Single ROM file | -| n64 | Nintendo 64 | Mupen64Plus-Next | Mupen64Plus **(Standalone)**,
ParaLLEl N64,
simple64 **(Standalone)** [UW],
Rosalie's Mupen GUI **(Standalone)** [UW],
Project64 **(Standalone)** [W],
ares **(Standalone)**,
sixtyforce **(Standalone)** [M] | No | Single archive or ROM file | -| n64dd | Nintendo 64DD | ParaLLEl N64 [UW],
Mupen64Plus-Next [M] | Mupen64Plus-Next [UW],
ParaLLEl N64 [M],
Rosalie's Mupen GUI **(Standalone)** [UW],
ares **(Standalone)** | Yes | See the specific _Nintendo 64DD_ section elsewhere in this guide | -| nds | Nintendo DS | DeSmuME | DeSmuME 2015,
DeSmuME **(Standalone)** [U],
melonDS,
melonDS **(Standalone)**,
SkyEmu **(Standalone)** | No | Single archive or ROM file | -| neogeo | SNK Neo Geo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [UW],
MAME **(Standalone)** | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | -| neogeocd | SNK Neo Geo CD | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [U],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | -| neogeocdjp | SNK Neo Geo CD [Japan] | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [U],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | -| nes | Nintendo Entertainment System | Mesen | Mesen **(Standalone)** [UW],
Nestopia UE,
Nestopia UE **(Standalone)** [U],
FCEUmm,
QuickNES,
puNES **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [U],
3dSen **(Proton)** [U],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For NES games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | -| ngage | Nokia N-Gage | EKA2L1 [Mounted] **(Standalone)** | EKA2L1 [Installed] **(Standalone)**,
EKA2L1 [Mounted] **(Wine)** [U],
EKA2L1 [Installed] **(Wine)** [U] | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | -| ngp | SNK Neo Geo Pocket | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | | | -| ngpc | SNK Neo Geo Pocket Color | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | | | +| n3ds | Nintendo 3DS | Citra [LW],
Citra **(Standalone)** [M] | Citra 2018 [LW],
Citra **(Standalone)** [LW] | No | Single ROM file | +| n64 | Nintendo 64 | Mupen64Plus-Next | Mupen64Plus **(Standalone)**,
ParaLLEl N64,
simple64 **(Standalone)** [LW],
Rosalie's Mupen GUI **(Standalone)** [LW],
Project64 **(Standalone)** [W],
ares **(Standalone)**,
sixtyforce **(Standalone)** [M] | No | Single archive or ROM file | +| n64dd | Nintendo 64DD | ParaLLEl N64 [LW],
Mupen64Plus-Next [M] | Mupen64Plus-Next [LW],
ParaLLEl N64 [M],
Rosalie's Mupen GUI **(Standalone)** [LW],
ares **(Standalone)** | Yes | See the specific _Nintendo 64DD_ section elsewhere in this guide | +| nds | Nintendo DS | melonDS DS | melonDS @,
melonDS **(Standalone)**,
DeSmuME,
DeSmuME 2015,
DeSmuME **(Standalone)** [L],
SkyEmu **(Standalone)** | No | Single archive or ROM file | +| neogeo | SNK Neo Geo | FinalBurn Neo | FinalBurn Neo **(Standalone)** [LW],
MAME **(Standalone)** | Yes | See the specific _Arcade and Neo Geo_ section elsewhere in this guide | +| neogeocd | SNK Neo Geo CD | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [L],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | +| neogeocdjp | SNK Neo Geo CD [Japan] | NeoCD | FinalBurn Neo,
FinalBurn Neo **(Standalone)** [L],
MAME **(Standalone)** | Yes | .chd (NeoCD and MAME only) or .cue file | +| nes | Nintendo Entertainment System | Mesen | Mesen **(Standalone)** [LW],
Nestopia UE,
Nestopia UE **(Standalone)** [L],
FCEUmm,
QuickNES,
puNES **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)**,
ares FDS **(Standalone)**,
3dSen **(Wine)** [L],
3dSen **(Proton)** [L],
3dSen **(Standalone)** [W] | No | Single archive or ROM file. For NES games in 3D see the specific _Nintendo NES and Famicom in 3D_ section elsewhere in this guide | +| ngage | Nokia N-Gage | EKA2L1 [Mounted] **(Standalone)** | EKA2L1 [Installed] **(Standalone)**,
EKA2L1 [Mounted] **(Wine)** [L],
EKA2L1 [Installed] **(Wine)** [L] | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | +| ngp | SNK Neo Geo Pocket | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| ngpc | SNK Neo Geo Pocket Color | Beetle NeoPop | RACE,
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | odyssey2 | Magnavox Odyssey 2 | O2EM | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | -| openbor | OpenBOR Game Engine | OpenBOR **(Standalone)** [UW] | | No | See the specific _OpenBOR_ section elsewhere in this guide | -| oric | Tangerine Computer Systems Oric | Oricutron **(Standalone)** [UW] | | | See the specific _Tangerine Computer Systems Oric_ section elsewhere in this guide | +| openbor | OpenBOR Game Engine | OpenBOR **(Standalone)** [LW] | | No | See the specific _OpenBOR_ section elsewhere in this guide | +| oric | Tangerine Computer Systems Oric | Oricutron **(Standalone)** [LW] | | | See the specific _Tangerine Computer Systems Oric_ section elsewhere in this guide | | palm | Palm OS | Mu | | | | | pc | IBM PC | DOSBox-Pure | DOSBox-Core,
DOSBox-SVN,
DOSBox-X **(Standalone)**,
DOSBox Staging **(Standalone)** | No | See the specific _DOS / PC_ section elsewhere in this guide | | pc88 | NEC PC-8800 Series | QUASI88 | QUASI88 **(Standalone)** | Yes | | | pc98 | NEC PC-9800 Series | Neko Project II Kai | Neko Project II | | | -| pcarcade | PC Arcade Systems | Wine **(Standalone)** [U],
_Shortcut or script_ [MW] | Proton **(Standalone)** [U],
_AppImage_ [U],
_Shortcut or script_ [U] | No | | -| pcengine | NEC PC Engine | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | -| pcenginecd | NEC PC Engine CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | Yes | | +| pcarcade | PC Arcade Systems | Wine **(Standalone)** [L],
_Shortcut or script_ [MW] | Proton **(Standalone)** [L],
_AppImage_ [L],
_Shortcut or script_ [L] | No | | +| pcengine | NEC PC Engine | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| pcenginecd | NEC PC Engine CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | Yes | | | pcfx | NEC PC-FX | Beetle PC-FX | Mednafen **(Standalone)** | Yes | | | pico8 | PICO-8 Fantasy Console | PICO-8 **(Standalone)** | PICO-8 Splore **(Standalone)**,
Retro8 | No | See the specific _PICO-8_ section elsewhere in this guide | | plus4 | Commodore Plus/4 | VICE xplus4 | VICE xplus4 **(Standalone)** | No | Single archive or image file for tape, cartridge or single-diskette games, .m3u playlist for multi-diskette games | | pokemini | Nintendo Pokémon Mini | PokeMini | | No | | -| ports | Ports | _Shortcut or script_ | _AppImage_ [U],
ECWolf (Wolfenstein 3D),
NXEngine (Cave Story),
OpenLara (Tomb Raider) [UW],
Super Bros War | Yes for ECWolf | See the specific _Ports and desktop applications_ section elsewhere in this guide | -| ps2 | Sony PlayStation 2 | LRPS2 [UW],
PCSX2 **(Standalone)** [M] | PCSX2 [UW] @,
PCSX2 **(Standalone)** [UW],
PCSX2 Legacy **(Standalone)** @,
Play! **(Standalone)**,
AetherSX2 **(Standalone)** [M] | Yes except for Play! | | +| ports | Ports | _Shortcut or script_ | _AppImage_ [L],
ECWolf (Wolfenstein 3D),
NXEngine (Cave Story),
OpenLara (Tomb Raider) [LW],
Super Bros War | Yes for ECWolf | See the specific _Ports and desktop applications_ section elsewhere in this guide | +| ps2 | Sony PlayStation 2 | LRPS2 [LW],
PCSX2 **(Standalone)** [M] | PCSX2 [LW] @,
PCSX2 **(Standalone)** [LW],
PCSX2 Legacy **(Standalone)** @,
Play! **(Standalone)**,
AetherSX2 **(Standalone)** [M] | Yes except for Play! | | | ps3 | Sony PlayStation 3 | RPCS3 Shortcut **(Standalone)** | RPCS3 Directory **(Standalone)** | Yes | See the specific _Sony PlayStation 3_ section elsewhere in this guide | | ps4 | Sony PlayStation 4 | _Placeholder_ | | | | | psp | Sony PlayStation Portable | PPSSPP | PPSSPP **(Standalone)** | No | Single disc image file | -| psvita | Sony PlayStation Vita | Vita3K **(Standalone)** [UW] | | Yes | See the specific _Sony PlayStation Vita_ section elsewhere in this guide | +| psvita | Sony PlayStation Vita | Vita3K **(Standalone)** [LW] | | Yes | See the specific _Sony PlayStation Vita_ section elsewhere in this guide | | psx | Sony PlayStation | Beetle PSX | Beetle PSX HW,
PCSX ReARMed,
SwanStation,
DuckStation **(Standalone)**,
Mednafen **(Standalone)** | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | | pv1000 | Casio PV-1000 | MAME - Current | MAME **(Standalone)** | No | Single archive or ROM file | -| quake | Quake | TyrQuake | vitaQuake 2,
vitaQuake 2 [Rogue],
vitaQuake 2 [Xatrix],
vitaQuake 2 [Zaero],
vitaQuake 3 [UW],
_Shortcut or script_ | No | | +| quake | Quake | TyrQuake | vitaQuake 2,
vitaQuake 2 [Rogue],
vitaQuake 2 [Xatrix],
vitaQuake 2 [Zaero],
vitaQuake 3 [LW],
_Shortcut or script_ | No | | | samcoupe | MGT SAM Coupé | SimCoupé **(Standalone)** | | No | Single archive or ROM file | -| satellaview | Nintendo Satellaview | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | | | -| saturn | Sega Saturn | Beetle Saturn | Kronos [UW],
YabaSanshiro [UW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | -| saturnjp | Sega Saturn [Japan] | Beetle Saturn | Kronos [UW],
YabaSanshiro [UW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | In separate folder interpreted as a file, with .m3u playlist if multi-disc game | +| satellaview | Nintendo Satellaview | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | | | +| saturn | Sega Saturn | Beetle Saturn | Kronos [LW],
YabaSanshiro [LW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | +| saturnjp | Sega Saturn [Japan] | Beetle Saturn | Kronos [LW],
YabaSanshiro [LW],
Yabause,
Mednafen **(Standalone)**,
SSF **(Standalone)** [W] | Yes | .chd file for single-disc games, .m3u playlist for multi-disc games | | scummvm | ScummVM Game Engine | ScummVM | ScummVM **(Standalone)** | No | See the specific _ScummVM_ section elsewhere in this guide | | scv | Epoch Super Cassette Vision | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | sega32x | Sega Mega Drive 32X | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | sega32xjp | Sega Super 32X [Japan] | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | sega32xna | Sega Genesis 32X [North America] | PicoDrive | ares **(Standalone)** | No | Single archive or ROM file | | segacd | Sega CD | Genesis Plus GX | Genesis Plus GX Wide,
PicoDrive,
ares **(Standalone)** | Yes | | -| sfc | Nintendo SFC (Super Famicom) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| sg-1000 | Sega SG-1000 | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
blueMSX,
ares **(Standalone)** | No | | -| sgb | Nintendo Super Game Boy | Mesen-S | Mesen **(Standalone)** [UW],
SameBoy,
mGBA,
mGBA **(Standalone)** | | Single archive or ROM file | -| snes | Nintendo SNES (Super Nintendo) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | -| snesna | Nintendo SNES (Super Nintendo) [North America] | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
Beetle Supafaust [UW],
Mesen-S,
Mesen **(Standalone)** [UW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| sfc | Nintendo SFC (Super Famicom) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| sg-1000 | Sega SG-1000 | Genesis Plus GX | Genesis Plus GX Wide,
Gearsystem,
blueMSX,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| sgb | Nintendo Super Game Boy | Mesen-S | Mesen **(Standalone)** [LW],
SameBoy,
mGBA,
mGBA **(Standalone)** | | Single archive or ROM file | +| snes | Nintendo SNES (Super Nintendo) | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | +| snesna | Nintendo SNES (Super Nintendo) [North America] | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
Beetle Supafaust [LW],
Mesen-S,
Mesen **(Standalone)** [LW],
Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | solarus | Solarus Game Engine | Solarus **(Standalone)** | | No | Single .solarus game file | | spectravideo | Spectravideo | blueMSX | | | | | steam | Valve Steam | Steam **(Standalone)** | | No | See the specific _Steam_ section elsewhere in this guide | -| stv | Sega Titan Video Game System | Kronos [UW],
MAME - Current [M] | MAME - Current [UW],
MAME **(Standalone)**,
Mednafen **(Standalone)** | Yes | Single archive file | -| sufami | Bandai SuFami Turbo | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [UW],
ares **(Standalone)** | | | -| supergrafx | NEC SuperGrafx | Beetle SuperGrafx | Beetle PCE,
ares **(Standalone)** | | | +| stv | Sega Titan Video Game System | Kronos [LW],
MAME - Current [M] | MAME - Current [LW],
MAME **(Standalone)**,
Mednafen **(Standalone)** | Yes | Single archive file | +| sufami | Bandai SuFami Turbo | Snes9x - Current | Snes9x 2010,
Snes9x **(Standalone)**,
bsnes,
bsnes-hd,
bsnes-mercury Accuracy,
bsnes **(Standalone)** [LW],
ares **(Standalone)** | | | +| supergrafx | NEC SuperGrafx | Beetle SuperGrafx | Beetle PCE,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | | supervision | Watara Supervision | Potator | MAME - Current,
MAME **(Standalone)** | No | Single archive or ROM file | | supracan | Funtech Super A'Can | MAME - Current | MAME **(Standalone)** | Yes/No | Single archive or ROM file. To make MAME start these games create an empty file named internal_68k.bin and zip it into supracan.zip | -| switch | Nintendo Switch | Yuzu **(Standalone)** [UW],
Ryujinx **(Standalone)** [M] | Ryujinx **(Standalone)** [UW] | Yes | | +| switch | Nintendo Switch | Yuzu **(Standalone)** [LW],
Ryujinx **(Standalone)** [M] | Ryujinx **(Standalone)** [LW] | Yes | | | symbian | Symbian | EKA2L1 [Nokia N-Gage] **(Standalone)** | EKA2L1 [Nokia N70] **(Standalone)**,
EKA2L1 [Nokia N97] **(Standalone)**,
EKA2L1 [Custom device] **(Standalone)** | Yes | See the specific _Symbian and Nokia N-Gage_ section elsewhere in this guide | | tanodragon | Tano Dragon | XRoar **(Standalone)** | | Yes | See the specific _Dragon 32 and Tano Dragon_ section elsewhere in this guide | -| tg16 | NEC TurboGrafx-16 | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | No | Single archive or ROM file | -| tg-cd | NEC TurboGrafx-CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [UW],
ares **(Standalone)** | Yes | | +| tg16 | NEC TurboGrafx-16 | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | No | Single archive or ROM file | +| tg-cd | NEC TurboGrafx-CD | Beetle PCE | Beetle PCE FAST,
Mednafen **(Standalone)**,
Mesen **(Standalone)** [LW],
ares **(Standalone)** | Yes | | | ti99 | Texas Instruments TI-99 | MAME **(Standalone)** | | Yes | See the specific _Texas Instruments TI-99_ section elsewhere in this guide | | tic80 | TIC-80 Fantasy Computer | TIC-80 | TIC-80 **(Standalone)** | No | Single .tic file | | to8 | Thomson TO8 | Theodore | | | | -| triforce | Namco-Sega-Nintendo Triforce | Triforce **(Standalone)** [UW] | | No | | -| trs-80 | Tandy TRS-80 | sdl2trs DOS Diskette **(Standalone)** [UW] | sdl2trs Bootable Diskette **(Standalone)** [UW],
sdl2trs CMD File **(Standalone)** [UW] | Yes | See the specific _Tandy TRS-80_ section elsewhere in this guide | -| type-x | Taito Type X | Wine **(Standalone)** [U],
_Shortcut or script_ [MW] | Proton **(Standalone)** [U],
_AppImage_ [U],
_Shortcut or script_ [U] | No | | +| triforce | Namco-Sega-Nintendo Triforce | Triforce **(Standalone)** [LW] | | No | | +| trs-80 | Tandy TRS-80 | sdl2trs DOS Diskette **(Standalone)** [LW] | sdl2trs Bootable Diskette **(Standalone)** [LW],
sdl2trs CMD File **(Standalone)** [LW] | Yes | See the specific _Tandy TRS-80_ section elsewhere in this guide | +| type-x | Taito Type X | Wine **(Standalone)** [L],
_Shortcut or script_ [MW] | Proton **(Standalone)** [L],
_AppImage_ [L],
_Shortcut or script_ [L] | No | | | uzebox | Uzebox Open Source Console | Uzem | | | | | vectrex | GCE Vectrex | vecx | MAME - Current,
MAME **(Standalone)** | Yes for MAME | Single archive or ROM file | | vic20 | Commodore VIC-20 | VICE xvic | VICE xvic **(Standalone)** | No | Single archive or tape, cartridge or diskette image file | | videopac | Philips Videopac G7000 | O2EM | MAME - Current,
MAME **(Standalone)** | Yes | Single archive or ROM file | | | virtualboy | Nintendo Virtual Boy | Beetle VB | Mednafen **(Standalone)** | No | | -| vpinball | Visual Pinball | Visual Pinball **(Standalone)** [UW] | | No | In separate folder interpreted as a file | +| vpinball | Visual Pinball | Visual Pinball **(Standalone)** | | No | See the specific _Visual Pinball_ section elsewhere in this guide | | vsmile | VTech V.Smile | MAME - Current | MAME **(Standalone)** | Yes | Single archive or ROM file | | wasm4 | WASM-4 Fantasy Console | WASM-4 | | No | Single .wasm file | -| wii | Nintendo Wii | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [UW] | No | | +| wii | Nintendo Wii | Dolphin | Dolphin **(Standalone)**,
PrimeHack **(Standalone)** [LW] | No | | | wiiu | Nintendo Wii U | Cemu **(Standalone)** | | No | See the specific _Nintendo Wii U_ section elsewhere in this guide | -| windows | Microsoft Windows | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | Shortcut (.desktop/.app/.lnk) file, script or AppImage | -| windows3x | Microsoft Windows 3.x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | -| windows9x | Microsoft Windows 9x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [U],
_AppImage (Keep ES-DE running)_ [U] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | +| windows | Microsoft Windows | _Suspend ES-DE_ | _Keep ES-DE running_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | Shortcut (.desktop/.app/.lnk) file, script or AppImage | +| windows3x | Microsoft Windows 3.x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | +| windows9x | Microsoft Windows 9x | DOSBox-X **(Standalone)** | DOSBox-Pure,
_Shortcut or script (Suspend ES-DE)_,
_Shortcut or script (Keep ES-DE running)_,
_AppImage (Suspend ES-DE)_ [L],
_AppImage (Keep ES-DE running)_ [L] | No | See the specific _Microsoft Windows 3.x and 9x_ section elsewhere in this guide | | wonderswan | Bandai WonderSwan | Beetle Cygne | Mednafen **(Standalone)**,
ares **(Standalone)**,
ares [Benesse Pocket Challenge V2] **(Standalone)** | No | Single archive or ROM file | | wonderswancolor | Bandai WonderSwan Color | Beetle Cygne | Mednafen **(Standalone)**,
ares **(Standalone)** | No | Single archive or ROM file | | x1 | Sharp X1 | X Millennium | MAME [Diskette] **(Standalone)**,
MAME [Tape] **(Standalone)** | Yes for MAME | Single archive or diskette/tape file | | x68000 | Sharp X68000 | PX68k | MAME **(Standalone)** | Yes | | | xbox | Microsoft Xbox | xemu **(Standalone)** | Cxbx-Reloaded **(Standalone)** [W] | Yes for xemu | Single .iso file for xemu or unpacked .iso directory for Cxbx-Reloaded | -| xbox360 | Microsoft Xbox 360 | xenia **(Standalone)** [W],
xenia **(Wine)** [U] | xenia **(Proton)** [U],
_Shortcut or script_ [U] | No | See the specific _Microsoft Xbox 360_ section elsewhere in this guide | +| xbox360 | Microsoft Xbox 360 | xenia **(Standalone)** [W],
xenia **(Wine)** [L] | xenia **(Proton)** [L],
_Shortcut or script_ [L] | No | See the specific _Microsoft Xbox 360_ section elsewhere in this guide | | zmachine | Infocom Z-machine | Gargoyle **(Standalone)** | | No | | | zx81 | Sinclair ZX81 | EightyOne | | | | -| zxnext | Sinclair ZX Spectrum Next | #CSpect **(Standalone)** [UW],
ZEsarUX **(Standalone)** [M] | ZEsarUX **(Standalone)** [UW] | No | In separate folder interpreted as a file | -| zxspectrum | Sinclair ZX Spectrum | Fuse | Fuse **(Standalone)** | No | | +| zxnext | Sinclair ZX Spectrum Next | #CSpect **(Standalone)** [LW],
ZEsarUX **(Standalone)** [M] | ZEsarUX **(Standalone)** [LW] | No | In separate folder interpreted as a file | +| zxspectrum | Sinclair ZX Spectrum | Fuse | Fuse **(Standalone)** | No | Single archive or ROM file | diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index 99bdfd5ff..13373765c 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -1,18 +1,18 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt (es-app) # # CMake configuration for es-app # Also contains the application packaging configuration. # -project(emulationstation-de) +project(es-de) set(ES_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/ApplicationUpdater.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/ApplicationVersion.h ${CMAKE_CURRENT_SOURCE_DIR}/src/CollectionSystemsManager.h - ${CMAKE_CURRENT_SOURCE_DIR}/src/EmulationStation.h ${CMAKE_CURRENT_SOURCE_DIR}/src/FileData.h ${CMAKE_CURRENT_SOURCE_DIR}/src/FileFilterIndex.h ${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.h @@ -112,7 +112,7 @@ set(ES_SOURCES ) if(WIN32) - LIST(APPEND ES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation.rc) + LIST(APPEND ES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE.rc) endif() #--------------------------------------------------------------------------------------------------- @@ -121,149 +121,79 @@ endif() # Define target. if(APPLE) include_directories(${COMMON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src) - add_executable(EmulationStation ${ES_SOURCES} ${ES_HEADERS}) - target_link_libraries(EmulationStation ${COMMON_LIBRARIES} es-core) - set_target_properties(EmulationStation PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) + add_executable(ES-DE ${ES_SOURCES} ${ES_HEADERS}) + target_link_libraries(ES-DE ${COMMON_LIBRARIES} es-core) + set_target_properties(ES-DE PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) if(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 15.0.0) - target_link_options(EmulationStation PRIVATE LINKER:-no_warn_duplicate_libraries) + target_link_options(ES-DE PRIVATE LINKER:-no_warn_duplicate_libraries) endif() elseif(WIN32) include_directories(${COMMON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src) - add_executable(EmulationStation WIN32 ${ES_SOURCES} ${ES_HEADERS}) - target_link_libraries(EmulationStation ${COMMON_LIBRARIES} es-core) - set_target_properties(EmulationStation PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) + add_executable(ES-DE WIN32 ${ES_SOURCES} ${ES_HEADERS}) + target_link_libraries(ES-DE ${COMMON_LIBRARIES} es-core) + set_target_properties(ES-DE PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) +elseif(ANDROID) + include_directories(${COMMON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src) + add_library(main MODULE ${ES_SOURCES} ${ES_HEADERS}) + target_link_libraries(main PRIVATE ${COMMON_LIBRARIES} ${CMAKE_DL_LIBS} es-core es-pdf-convert) else() include_directories(${COMMON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src) - add_executable(emulationstation ${ES_SOURCES} ${ES_HEADERS}) - target_link_libraries(emulationstation ${COMMON_LIBRARIES} ${CMAKE_DL_LIBS} es-core) - set_target_properties(emulationstation PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) + add_executable(es-de ${ES_SOURCES} ${ES_HEADERS}) + target_link_libraries(es-de ${COMMON_LIBRARIES} ${CMAKE_DL_LIBS} es-core) + set_target_properties(es-de PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) endif() # Setup for installation and package generation. if(WIN32) - install(TARGETS EmulationStation RUNTIME DESTINATION .) + install(TARGETS ES-DE RUNTIME DESTINATION .) install(TARGETS es-pdf-convert RUNTIME DESTINATION es-pdf-converter) - if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) - if(CMAKE_BUILD_TYPE MATCHES Debug) - set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) - endif() - install(FILES ../avcodec-60.dll - ../avfilter-9.dll - ../avformat-60.dll - ../avutil-58.dll - ../postproc-57.dll - ../swresample-4.dll - ../swscale-7.dll - ../FreeImage.dll - ../freetype.dll - ../git2.dll - ../glew32.dll - ../libcrypto-1_1-x64.dll - ../libcurl-x64.dll - ../libssl-1_1-x64.dll - ../lunasvg.dll - ../pugixml.dll - ../rlottie.dll - ../SDL2.dll - ../vcomp140.dll - DESTINATION .) - install(FILES ../es-pdf-converter/charset.dll - ../es-pdf-converter/deflate.dll - ../es-pdf-converter/freetype.dll - ../es-pdf-converter/iconv.dll - ../es-pdf-converter/jpeg8.dll - ../es-pdf-converter/lcms2.dll - ../es-pdf-converter/Lerc.dll - ../es-pdf-converter/libcrypto-3-x64.dll - ../es-pdf-converter/libcurl.dll - ../es-pdf-converter/liblzma.dll - ../es-pdf-converter/libpng16.dll - ../es-pdf-converter/libssh2.dll - ../es-pdf-converter/openjp2.dll - ../es-pdf-converter/poppler.dll - ../es-pdf-converter/poppler-cpp.dll - ../es-pdf-converter/tiff.dll - ../es-pdf-converter/zlib.dll - ../es-pdf-converter/zstd.dll - DESTINATION es-pdf-converter) - else() - install(FILES ../avcodec-60.dll - ../avfilter-9.dll - ../avformat-60.dll - ../avutil-58.dll - ../postproc-57.dll - ../swresample-4.dll - ../swscale-7.dll - ../FreeImage.dll - ../glew32.dll - ../libcrypto-1_1-x64.dll - ../libcurl-x64.dll - ../libfreetype.dll - ../libgit2.dll - ../liblunasvg.dll - ../libpugixml.dll - ../librlottie.dll - ../libssl-1_1-x64.dll - ../SDL2.dll - ../vcomp140.dll - DESTINATION .) - install(FILES ../es-pdf-converter/libbrotlicommon.dll - ../es-pdf-converter/libbrotlidec.dll - ../es-pdf-converter/libbz2-1.dll - ../es-pdf-converter/libcairo-2.dll - ../es-pdf-converter/libcrypto-3-x64.dll - ../es-pdf-converter/libcurl-4.dll - ../es-pdf-converter/libdeflate.dll - ../es-pdf-converter/libexpat-1.dll - ../es-pdf-converter/libffi-8.dll - ../es-pdf-converter/libfontconfig-1.dll - ../es-pdf-converter/libfreetype-6.dll - ../es-pdf-converter/libgcc_s_seh-1.dll - ../es-pdf-converter/libgio-2.0-0.dll - ../es-pdf-converter/libglib-2.0-0.dll - ../es-pdf-converter/libgmodule-2.0-0.dll - ../es-pdf-converter/libgobject-2.0-0.dll - ../es-pdf-converter/libgraphite2.dll - ../es-pdf-converter/libharfbuzz-0.dll - ../es-pdf-converter/libiconv-2.dll - ../es-pdf-converter/libidn2-0.dll - ../es-pdf-converter/libintl-8.dll - ../es-pdf-converter/libjbig-0.dll - ../es-pdf-converter/libjpeg-8.dll - ../es-pdf-converter/liblcms2-2.dll - ../es-pdf-converter/libLerc.dll - ../es-pdf-converter/liblzma-5.dll - ../es-pdf-converter/libnghttp2-14.dll - ../es-pdf-converter/libnspr4.dll - ../es-pdf-converter/libopenjp2-7.dll - ../es-pdf-converter/libpcre2-8-0.dll - ../es-pdf-converter/libpixman-1-0.dll - ../es-pdf-converter/libplc4.dll - ../es-pdf-converter/libplds4.dll - ../es-pdf-converter/libpng16-16.dll - ../es-pdf-converter/libpoppler-129.dll - ../es-pdf-converter/libpoppler-cpp-0.dll - ../es-pdf-converter/libpoppler-glib-8.dll - ../es-pdf-converter/libpsl-5.dll - ../es-pdf-converter/libsharpyuv-0.dll - ../es-pdf-converter/libssh2-1.dll - ../es-pdf-converter/libssl-3-x64.dll - ../es-pdf-converter/libstdc++-6.dll - ../es-pdf-converter/libtiff-6.dll - ../es-pdf-converter/libunistring-5.dll - ../es-pdf-converter/libwebp-7.dll - ../es-pdf-converter/libwinpthread-1.dll - ../es-pdf-converter/libzstd.dll - ../es-pdf-converter/nss3.dll - ../es-pdf-converter/nssutil3.dll - ../es-pdf-converter/smime3.dll - ../es-pdf-converter/zlib1.dll - DESTINATION es-pdf-converter) + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION .) + if(CMAKE_BUILD_TYPE MATCHES Debug) + set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) endif() + install(FILES ../avcodec-60.dll + ../avfilter-9.dll + ../avformat-60.dll + ../avutil-58.dll + ../postproc-57.dll + ../swresample-4.dll + ../swscale-7.dll + ../FreeImage.dll + ../freetype.dll + ../git2.dll + ../glew32.dll + ../libcrypto-1_1-x64.dll + ../libcurl-x64.dll + ../libssl-1_1-x64.dll + ../lunasvg.dll + ../pugixml.dll + ../rlottie.dll + ../SDL2.dll + ../vcomp140.dll + DESTINATION .) + install(FILES ../es-pdf-converter/charset.dll + ../es-pdf-converter/deflate.dll + ../es-pdf-converter/freetype.dll + ../es-pdf-converter/iconv.dll + ../es-pdf-converter/jpeg8.dll + ../es-pdf-converter/lcms2.dll + ../es-pdf-converter/Lerc.dll + ../es-pdf-converter/libcrypto-3-x64.dll + ../es-pdf-converter/libcurl.dll + ../es-pdf-converter/liblzma.dll + ../es-pdf-converter/libpng16.dll + ../es-pdf-converter/libssh2.dll + ../es-pdf-converter/openjp2.dll + ../es-pdf-converter/poppler.dll + ../es-pdf-converter/poppler-cpp.dll + ../es-pdf-converter/tiff.dll + ../es-pdf-converter/zlib.dll + ../es-pdf-converter/zstd.dll + DESTINATION es-pdf-converter) install(FILES ../LICENSE DESTINATION .) install(DIRECTORY ${CMAKE_SOURCE_DIR}/licenses DESTINATION .) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/linear-es-de DESTINATION themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/modern-es-de DESTINATION themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/slate-es-de DESTINATION themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources DESTINATION .) @@ -274,10 +204,10 @@ elseif(APPLE) # So an extra 'Resources' directory was added to the CMAKE_INSTALL_PREFIX variable as well # to compensate for this. It's a bad solution to the problem and there must surely be a # better way to fix this. - install(TARGETS EmulationStation RUNTIME DESTINATION ../MacOS) + install(TARGETS ES-DE RUNTIME DESTINATION ../MacOS) install(TARGETS es-pdf-convert RUNTIME DESTINATION ../MacOS) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE.icns DESTINATION ../Resources) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE_Info.plist DESTINATION .. RENAME Info.plist) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE.icns DESTINATION ../Resources) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE_Info.plist DESTINATION .. RENAME Info.plist) set(APPLE_DYLIB_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE @@ -322,37 +252,40 @@ elseif(APPLE) install(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ../Resources) install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources DESTINATION ../Resources) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/linear-es-de DESTINATION ../Resources/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/modern-es-de DESTINATION ../Resources/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/slate-es-de DESTINATION ../Resources/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/licenses DESTINATION ../Resources) -else() - install(TARGETS emulationstation RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +elseif(NOT ANDROID) + install(TARGETS es-de RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) install(TARGETS es-pdf-convert RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) if(CMAKE_SYSTEM_NAME MATCHES Linux) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/emulationstation.6.gz + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/es-de.6.gz DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man6) else() - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/emulationstation.6.gz + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/es-de.6.gz DESTINATION ${CMAKE_INSTALL_PREFIX}/man/man6) endif() install(FILES ${CMAKE_SOURCE_DIR}/LICENSE - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/emulationstation) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.emulationstation-de.desktop + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.frontend.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.emulationstation-de.svg + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.frontend.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.emulationstation-de.svg + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.frontend.svg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.emulationstation-de.appdata.xml + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/assets/org.es_de.frontend.appdata.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) install(DIRECTORY ${CMAKE_SOURCE_DIR}/licenses - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/emulationstation) + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de) + install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/linear-es-de + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/modern-es-de - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/emulationstation/themes) + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/themes/slate-es-de - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/emulationstation/themes) + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de/themes) install(DIRECTORY ${CMAKE_SOURCE_DIR}/resources - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/emulationstation) + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/es-de) endif() include(InstallRequiredSystemLibraries) @@ -360,17 +293,17 @@ include(InstallRequiredSystemLibraries) #--------------------------------------------------------------------------------------------------- # General CPack settings. -set(CPACK_PACKAGE_NAME emulationstation-de) +set(CPACK_PACKAGE_NAME es-de) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Emulator frontend") -set(CPACK_PACKAGE_DESCRIPTION "EmulationStation Desktop Edition (ES-DE) is a frontend for browsing and launching games from your multi-platform game collection.") +set(CPACK_PACKAGE_DESCRIPTION "ES-DE (EmulationStation Desktop Edition) is a frontend for browsing and launching games from your multi-platform game collection.") set(CPACK_PACKAGE_VERSION ${ES_VERSION}) if(APPLE) # Shorter line length license file to be able to fit inside the drag-and-drop installer window without introducing extra line breaks. - set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE_LICENSE_macOS) + set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE_LICENSE_macOS) elseif(WIN32) # The installer window looks a bit different on Windows so a specific file for this OS is required. - set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE_LICENSE_Windows) + set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE_LICENSE_Windows) else() set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE) endif() @@ -386,40 +319,40 @@ endif() # Settings per operating system and generator type. if(APPLE) set(CPACK_GENERATOR Bundle) - set(CPACK_PACKAGE_FILE_NAME EmulationStation-DE-${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}) - set(CPACK_DMG_VOLUME_NAME "EmulationStation Desktop Edition ${CPACK_PACKAGE_VERSION}") - set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE.icns) - set(CPACK_DMG_DS_STORE ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE_DS_Store) - set(CPACK_BUNDLE_NAME "EmulationStation Desktop Edition") - set(CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE.icns) - set(CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation-DE_Info.plist) + set(CPACK_PACKAGE_FILE_NAME ES-DE_${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}) + set(CPACK_DMG_VOLUME_NAME "ES-DE ${CPACK_PACKAGE_VERSION}") + set(CPACK_PACKAGE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE.icns) + set(CPACK_DMG_DS_STORE ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE_DS_Store) + set(CPACK_BUNDLE_NAME "ES-DE") + set(CPACK_BUNDLE_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE.icns) + set(CPACK_BUNDLE_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE_Info.plist) if(MACOS_CODESIGN_IDENTITY) set(CPACK_BUNDLE_APPLE_CERT_APP "Developer ID Application: ${MACOS_CODESIGN_IDENTITY}") set(CPACK_BUNDLE_APPLE_CODESIGN_PARAMETER "--deep --force --options runtime") endif() elseif(WIN32) set(CPACK_GENERATOR NSIS) - set(CPACK_PACKAGE_FILE_NAME EmulationStation-DE-${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}) - set(CPACK_PACKAGE_INSTALL_DIRECTORY EmulationStation-DE) - set(CPACK_PACKAGE_EXECUTABLES EmulationStation EmulationStation) + set(CPACK_PACKAGE_FILE_NAME ES-DE_${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}) + set(CPACK_PACKAGE_INSTALL_DIRECTORY ES-DE) + set(CPACK_PACKAGE_EXECUTABLES ES-DE ES-DE) set(CPACK_NSIS_INSTALL_ROOT ${PROGRAMFILES64}) set(CPACK_NSIS_EXECUTABLES_DIRECTORY .) - set(CPACK_NSIS_MUI_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/EmulationStation.ico) + set(CPACK_NSIS_MUI_ICON ${CMAKE_CURRENT_SOURCE_DIR}/assets/ES-DE.ico) set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON) - set(CPACK_NSIS_DISPLAY_NAME "EmulationStation Desktop Edition ${CPACK_PACKAGE_VERSION}") - set(CPACK_NSIS_PACKAGE_NAME "EmulationStation Desktop Edition") - set(CPACK_NSIS_INSTALLED_ICON_NAME EmulationStation.exe) - set(CPACK_NSIS_WELCOME_TITLE "EmulationStation Desktop Edition Installer") - set(CPACK_NSIS_FINISH_TITLE "EmulationStation Desktop Edition Installation Completed") + set(CPACK_NSIS_DISPLAY_NAME "ES-DE ${CPACK_PACKAGE_VERSION}") + set(CPACK_NSIS_PACKAGE_NAME "ES-DE") + set(CPACK_NSIS_INSTALLED_ICON_NAME ES-DE.exe) + set(CPACK_NSIS_WELCOME_TITLE "ES-DE Installer") + set(CPACK_NSIS_FINISH_TITLE "ES-DE Installation Completed") set(CPACK_NSIS_MANIFEST_DPI_AWARE ON) - set(CPACK_NSIS_MENU_LINKS "https://es-de.org" "ES-DE Website" "https://es-de.org" "Please Donate") + set(CPACK_NSIS_MENU_LINKS "https://es-de.org" "ES-DE Website") else() - set(CPACK_PACKAGE_INSTALL_DIRECTORY emulationstation_${CMAKE_PACKAGE_VERSION}) - set(CPACK_PACKAGE_EXECUTABLES emulationstation emulationstation) + set(CPACK_PACKAGE_INSTALL_DIRECTORY es-de_${CMAKE_PACKAGE_VERSION}) + set(CPACK_PACKAGE_EXECUTABLES es-de es-de) if(LINUX_CPACK_GENERATOR MATCHES DEB) set(CPACK_GENERATOR DEB) endif() - set(CPACK_DEBIAN_FILE_NAME emulationstation-de-${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}.deb) + set(CPACK_DEBIAN_FILE_NAME es-de_${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}.deb) set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Leon Styhre ") set(CPACK_DEBIAN_PACKAGE_HOMEPAGE https://es-de.org) set(CPACK_DEBIAN_PACKAGE_SECTION games) @@ -428,7 +361,7 @@ else() if(LINUX_CPACK_GENERATOR MATCHES RPM) set(CPACK_GENERATOR RPM) endif() - set(CPACK_RPM_FILE_NAME emulationstation-de-${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}.rpm) + set(CPACK_RPM_FILE_NAME es-de_${CPACK_PACKAGE_VERSION}-${CPU_ARCHITECTURE}.rpm) set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION}) set(CPACK_RPM_PACKAGE_LICENSE MIT) list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION ${CMAKE_INSTALL_PREFIX}) diff --git a/es-app/assets/EmulationStation-DE.icns b/es-app/assets/ES-DE.icns similarity index 100% rename from es-app/assets/EmulationStation-DE.icns rename to es-app/assets/ES-DE.icns diff --git a/es-app/assets/EmulationStation.ico b/es-app/assets/ES-DE.ico similarity index 100% rename from es-app/assets/EmulationStation.ico rename to es-app/assets/ES-DE.ico diff --git a/es-app/assets/EmulationStation.rc b/es-app/assets/ES-DE.rc similarity index 64% rename from es-app/assets/EmulationStation.rc rename to es-app/assets/ES-DE.rc index 1bda4149b..584408efa 100644 --- a/es-app/assets/EmulationStation.rc +++ b/es-app/assets/ES-DE.rc @@ -1,4 +1,4 @@ -#include "EmulationStation.h" +#include "ApplicationVersion.h" #include "windows.h" @@ -21,13 +21,13 @@ BEGIN BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "es-de.org\0" - VALUE "FileDescription", "EmulationStation\0" + VALUE "FileDescription", "ES-DE\0" VALUE "FileVersion", RESOURCE_VERSION_STRING - VALUE "InternalName", "emulationstation.exe\0" - VALUE "LegalCopyright", "Copyright (c) 2020-2023 Leon Styhre\0" + VALUE "InternalName", "ES-DE.exe\0" + VALUE "LegalCopyright", "Copyright (c) 2020-2024 Leon Styhre\0" VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "emulationstation.exe\0" - VALUE "ProductName", "EmulationStation\0" + VALUE "OriginalFilename", "ES-DE.exe\0" + VALUE "ProductName", "ES-DE\0" VALUE "ProductVersion", PROGRAM_VERSION_STRING END END @@ -37,4 +37,4 @@ BEGIN END END -IDI_ES_LOGO ICON DISCARDABLE "EmulationStation.ico" +IDI_ES_LOGO ICON DISCARDABLE "ES-DE.ico" diff --git a/es-app/assets/EmulationStation-DE_DS_Store b/es-app/assets/ES-DE_DS_Store similarity index 90% rename from es-app/assets/EmulationStation-DE_DS_Store rename to es-app/assets/ES-DE_DS_Store index c7dd91e90..b449f2df0 100644 Binary files a/es-app/assets/EmulationStation-DE_DS_Store and b/es-app/assets/ES-DE_DS_Store differ diff --git a/es-app/assets/EmulationStation-DE_Info.plist b/es-app/assets/ES-DE_Info.plist similarity index 70% rename from es-app/assets/EmulationStation-DE_Info.plist rename to es-app/assets/ES-DE_Info.plist index ffcd40a02..ecba4019d 100644 --- a/es-app/assets/EmulationStation-DE_Info.plist +++ b/es-app/assets/ES-DE_Info.plist @@ -3,31 +3,31 @@ CFBundleIdentifier - org.es-de.EmulationStation + 3.0.0 CFBundleDevelopmentRegion English CFBundleDisplayName - EmulationStation Desktop Edition + ES-DE CFBundleExecutable - EmulationStation + ES-DE CFBundleGetInfoString - EmulationStation Desktop Edition 2.2.1 + ES-DE 3.0.0 CFBundleIconFile - EmulationStation-DE.icns + ES-DE.icns CFBundleName - EmulationStation Desktop Edition + ES-DE CFBundlePackageType APPL CFBundleSignature ESDE CFBundleShortVersionString - 2.2.1 + 3.0.0-alpha CFBundleVersion - 2.2.1 + 3.0.0-alpha CFBundleInfoDictionaryVersion 6.0 LSApplicationCategoryType - public.app-category.games + public.app-category.education LSMinimumSystemVersion 10.15.0 LSUIPresentationMode @@ -37,9 +37,9 @@ NSPrincipalClass NSApplication NSMainNibFile - EmulationStation + ES-DE NSHumanReadableCopyright - Copyright (c) 2020-2023 Leon Styhre + Copyright (c) 2020-2024 Leon Styhre Copyright (c) 2014 Alec Lofquist Licensed under the MIT license diff --git a/es-app/assets/EmulationStation-DE_LICENSE_Windows b/es-app/assets/ES-DE_LICENSE_Windows similarity index 96% rename from es-app/assets/EmulationStation-DE_LICENSE_Windows rename to es-app/assets/ES-DE_LICENSE_Windows index 9469ee561..13deba166 100644 --- a/es-app/assets/EmulationStation-DE_LICENSE_Windows +++ b/es-app/assets/ES-DE_LICENSE_Windows @@ -1,4 +1,4 @@ -Copyright (c) 2020-2023 Leon Styhre +Copyright (c) 2020-2024 Leon Styhre Copyright (c) 2014 Alec Lofquist Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/es-app/assets/EmulationStation-DE_LICENSE_macOS b/es-app/assets/ES-DE_LICENSE_macOS similarity index 96% rename from es-app/assets/EmulationStation-DE_LICENSE_macOS rename to es-app/assets/ES-DE_LICENSE_macOS index f81c6fbe7..de376f344 100644 --- a/es-app/assets/EmulationStation-DE_LICENSE_macOS +++ b/es-app/assets/ES-DE_LICENSE_macOS @@ -1,6 +1,6 @@ -Copyright (c) 2020-2023 Leon Styhre +Copyright (c) 2020-2024 Leon Styhre Copyright (c) 2014 Alec Lofquist - + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without @@ -9,10 +9,10 @@ copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A diff --git a/es-app/assets/Windows_Portable_DO_NOT_PLACE_YOUR_THEMES_HERE.txt b/es-app/assets/Windows_Portable_DO_NOT_PLACE_YOUR_THEMES_HERE.txt index eb79d74e2..b07d916c9 100644 --- a/es-app/assets/Windows_Portable_DO_NOT_PLACE_YOUR_THEMES_HERE.txt +++ b/es-app/assets/Windows_Portable_DO_NOT_PLACE_YOUR_THEMES_HERE.txt @@ -1 +1 @@ -Place manually downloaded or modified themes into .emulationstation\themes\ and not into this directory +Place manually downloaded or modified themes into ES-DE\ES-DE\themes\ and not into this directory diff --git a/es-app/assets/Windows_Portable_README.txt b/es-app/assets/Windows_Portable_README.txt index f295a7f0c..55130be90 100644 --- a/es-app/assets/Windows_Portable_README.txt +++ b/es-app/assets/Windows_Portable_README.txt @@ -1,11 +1,10 @@ -EmulationStation Desktop Edition (ES-DE) - Portable installation on Windows +ES-DE (EmulationStation Desktop Edition) - Portable installation on Windows --------------------------------------------------------------------------- ES-DE release: -2.2.1 +3.0.0 The latest version can be downloaded from https://es-de.org -Please also consider donating to the project, links for that can be found on the ES-DE website just mentioned. Instructions: @@ -15,18 +14,18 @@ New installation: 1) The ROMs_ALL directory contains all the systems that ES-DE supports, but to decrease application startup time only copy the folders you need to the ROMs directory 2) Place your games into their respective folders in the ROMs directory tree 3) Place your emulators inside the Emulators directory -4) Start ES-DE using EmulationStation.exe and enjoy some retrogaming! +4) Start ES-DE using ES-DE.exe and enjoy some retrogaming! Upgrading from an older release: -1) Rename your old EmulationStation-DE directory, for example to EmulationStation-DE_OLD -2) Move your games from EmulationStation-DE_OLD\ROMs\ to EmulationStation-DE\ROMs\ -3) Move your emulators from EmulationStation-DE_OLD\Emulators\ to EmulationStation-DE\Emulators\ -4) Move the contents of EmulationStation-DE_OLD\.emulationstation\ to EmulationStation-DE\.emulationstation\ +1) Rename your old ES-DE directory, for example to ES-DE_OLD +2) Move your games from ES-DE_OLD\ROMs\ to ES-DE\ROMs\ +3) Move your emulators from ES-DE_OLD\Emulators\ to ES-DE\Emulators\ +4) Move the contents of ES-DE_OLD\ES-DE\ to ES-DE\ES-DE\ This last step includes your settings, custom collections, custom systems, scraped/downloaded media, gamelist.xml files, scripts and themes 5) Update your themes using the theme downloader to get support for all the latest systems and features -In case of issues, check .emulationstation\es_log.txt for clues as to what went wrong. -Enabling the "Debug mode" setting in the "Other settings" menu or starting EmulationStation.exe with the --debug flag will provide additional details. +In case of issues, check ES-DE\es_log.txt for clues as to what went wrong. +Enabling the "Debug mode" setting in the "Other settings" menu or starting ES-DE.exe with the --debug flag will provide additional details. Refer to the FAQ and user guide for more detailed instructions and documentation: https://gitlab.com/es-de/emulationstation-de/-/blob/master/FAQ.md @@ -128,7 +127,8 @@ Emulators\VICE\xplus4.exe Emulators\VICE\bin\xplus4.exe Emulators\VICE\xvic.exe Emulators\VICE\bin\xvic.exe -Emulators\Visual Pinball\VPinballX.exe +Emulators\VPinballX\VPinballX_GL64.exe +Emulators\VPinballX\VPinballX64.exe Emulators\Vita3K\Vita3K.exe Emulators\xemu\xemu.exe Emulators\xenia\xenia.exe diff --git a/es-app/assets/emulationstation.6.gz b/es-app/assets/emulationstation.6.gz deleted file mode 100644 index f86bcabbb..000000000 Binary files a/es-app/assets/emulationstation.6.gz and /dev/null differ diff --git a/es-app/assets/es-de.6.gz b/es-app/assets/es-de.6.gz new file mode 100644 index 000000000..d730d5313 Binary files /dev/null and b/es-app/assets/es-de.6.gz differ diff --git a/es-app/assets/org.es_de.emulationstation-de.appdata.xml b/es-app/assets/org.es_de.frontend.appdata.xml similarity index 92% rename from es-app/assets/org.es_de.emulationstation-de.appdata.xml rename to es-app/assets/org.es_de.frontend.appdata.xml index e2f20ea64..99e7e381b 100644 --- a/es-app/assets/org.es_de.emulationstation-de.appdata.xml +++ b/es-app/assets/org.es_de.frontend.appdata.xml @@ -1,13 +1,13 @@ - org.es_de.emulationstation-de - EmulationStation Desktop Edition + org.es_de.frontend + ES-DE Emulator frontend -

EmulationStation Desktop Edition (ES-DE) is a frontend for browsing and +

ES-DE (EmulationStation Desktop Edition) is a frontend for browsing and launching games from your multi-platform game collection.

- org.es_de.emulationstation-de.desktop + org.es_de.frontend.desktop Game Emulator @@ -38,6 +38,9 @@ + + https://gitlab.com/es-de/emulationstation-de/-/releases + https://gitlab.com/es-de/emulationstation-de/-/releases diff --git a/es-app/assets/org.es_de.emulationstation-de.desktop b/es-app/assets/org.es_de.frontend.desktop similarity index 67% rename from es-app/assets/org.es_de.emulationstation-de.desktop rename to es-app/assets/org.es_de.frontend.desktop index 287e61bbb..194ac3f3a 100644 --- a/es-app/assets/org.es_de.emulationstation-de.desktop +++ b/es-app/assets/org.es_de.frontend.desktop @@ -1,12 +1,12 @@ [Desktop Entry] Version=1.0 -Exec=emulationstation -Icon=org.es_de.emulationstation-de +Exec=es-de +Icon=org.es_de.frontend Terminal=false Type=Application StartupNotify=true Hidden=false Categories=Game;Emulator; -Name=EmulationStation Desktop Edition +Name=ES-DE GenericName=Emulator Frontend Keywords=emulator;emulation;front-end;frontend; diff --git a/es-app/assets/org.es_de.emulationstation-de.svg b/es-app/assets/org.es_de.frontend.svg similarity index 100% rename from es-app/assets/org.es_de.emulationstation-de.svg rename to es-app/assets/org.es_de.frontend.svg diff --git a/es-app/assets/org.es_de.emulationstation-de.yml b/es-app/assets/org.es_de.frontend.yml similarity index 92% rename from es-app/assets/org.es_de.emulationstation-de.yml rename to es-app/assets/org.es_de.frontend.yml index 721cab5a0..34cd0c60c 100644 --- a/es-app/assets/org.es_de.emulationstation-de.yml +++ b/es-app/assets/org.es_de.frontend.yml @@ -1,16 +1,16 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition -# org.es_de.emulationstation-de.yml +# ES-DE +# org.es_de.frontend.yml # # Flatpak manifest file for use with flatpak-builder. # -app-id: org.es_de.emulationstation-de +app-id: org.es_de.frontend-de sdk: org.freedesktop.Sdk runtime: org.freedesktop.Platform runtime-version: '21.08' -command: emulationstation +command: es-de finish-args: - --share=ipc - --socket=x11 @@ -74,7 +74,7 @@ modules: url: https://github.com/zeux/pugixml/releases/download/v1.11.4/pugixml-1.11.4.tar.gz sha256: 8ddf57b65fb860416979a3f0640c2ad45ddddbbafa82508ef0a0af3ce7061716 - - name: emulationstation + - name: es-de buildsystem: cmake-ninja config-opts: - -DFLATPAK_BUILD=on diff --git a/es-app/src/ApplicationUpdater.cpp b/es-app/src/ApplicationUpdater.cpp index 49e2f77d9..e1f9b20a6 100644 --- a/es-app/src/ApplicationUpdater.cpp +++ b/es-app/src/ApplicationUpdater.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ApplicationUpdater.cpp // // Checks for application updates. @@ -9,7 +9,7 @@ #include "ApplicationUpdater.h" -#include "EmulationStation.h" +#include "ApplicationVersion.h" #include "Log.h" #include "Settings.h" #include "resources/ResourceManager.h" @@ -211,8 +211,8 @@ void ApplicationUpdater::parseFile() #if (LOCAL_TESTING_FILE) LOG(LogWarning) << "ApplicationUpdater: Using local \"latest_release.json\" testing file"; - const std::string localReleaseFile {Utils::FileSystem::getHomePath() + - "/.emulationstation/latest_release.json"}; + const std::string localReleaseFile {Utils::FileSystem::getAppDataDirectory() + + "/latest_release.json"}; if (!Utils::FileSystem::exists(localReleaseFile)) throw std::runtime_error("Local testing file not found"); diff --git a/es-app/src/ApplicationUpdater.h b/es-app/src/ApplicationUpdater.h index 23b1bb48b..17e2ebd8a 100644 --- a/es-app/src/ApplicationUpdater.h +++ b/es-app/src/ApplicationUpdater.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ApplicationUpdater.h // // Checks for application updates. diff --git a/es-app/src/ApplicationVersion.h b/es-app/src/ApplicationVersion.h new file mode 100644 index 000000000..dcb861360 --- /dev/null +++ b/es-app/src/ApplicationVersion.h @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MIT +// +// ES-DE +// ApplicationVersion.h +// + +#ifndef ES_APP_APPLICATION_VERSION_H +#define ES_APP_APPLICATION_VERSION_H + +// These numbers and strings need to be manually updated for a new version. +// Do this version number update as the very last commit for the new release version. +// clang-format off +#define PROGRAM_VERSION_MAJOR 3 +#define PROGRAM_VERSION_MINOR 0 +#define PROGRAM_VERSION_MAINTENANCE 0 +#define PROGRAM_RELEASE_NUMBER 41 +// clang-format on +#define PROGRAM_VERSION_STRING "3.0.0" + +#define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ + +#define RESOURCE_VERSION_STRING "3,0,0\0" +#define RESOURCE_VERSION PROGRAM_VERSION_MAJOR, PROGRAM_VERSION_MINOR, PROGRAM_VERSION_MAINTENANCE + +#endif // ES_APP_APPLICATION_VERSION_H diff --git a/es-app/src/CollectionSystemsManager.cpp b/es-app/src/CollectionSystemsManager.cpp index 0f9491a15..300cd600c 100644 --- a/es-app/src/CollectionSystemsManager.cpp +++ b/es-app/src/CollectionSystemsManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CollectionSystemsManager.cpp // // Manages collections of the following two types: @@ -634,8 +634,31 @@ void CollectionSystemsManager::setEditMode(const std::string& collectionName, bo mEditingCollectionSystemData = sysData; if (showPopup) { + const std::string controllerType { + Settings::getInstance()->getString("InputControllerType")}; + std::string editButton; + + if (controllerType == "ps123" || controllerType == "ps4" || controllerType == "ps5") { +#if defined(_MSC_VER) // MSVC compiler. + if (Settings::getInstance()->getBool("InputSwapButtons")) + editButton = Utils::String::wideStringToString(L"\uF04D"); // Square. + else + editButton = Utils::String::wideStringToString(L"\uF0D8"); // Triangle. +#else + if (Settings::getInstance()->getBool("InputSwapButtons")) + editButton = "\uF04D"; // Square. + else + editButton = "\uF0D8"; // Triangle. +#endif + } + else { + if (Settings::getInstance()->getBool("InputSwapButtons")) + editButton = "'X'"; + else + editButton = "'Y'"; + } mWindow->queueInfoPopup("EDITING '" + Utils::String::toUpper(collectionName) + - "' COLLECTION, ADD/REMOVE GAMES WITH 'Y'", + "' COLLECTION, ADD/REMOVE GAMES WITH " + editButton, 10000); } } @@ -1437,7 +1460,7 @@ std::vector CollectionSystemsManager::getSystemsFromConfig() std::vector configPaths {SystemData::getConfigPath()}; // Here we don't honor the tag which may be present in the custom es_systems.xml - // file under ~/.emulationstation/custom_systems as we really want to include all the themes + // file under /custom_systems as we really want to include all the themes // supported by ES-DE. Otherwise a user may accidentally create a custom collection that // corresponds to a supported theme. for (auto path : configPaths) { @@ -1625,6 +1648,6 @@ std::string CollectionSystemsManager::getCustomCollectionConfigPath( std::string CollectionSystemsManager::getCollectionsFolder() { - return Utils::FileSystem::getGenericPath(Utils::FileSystem::getHomePath() + - "/.emulationstation/collections"); + return Utils::FileSystem::getGenericPath(Utils::FileSystem::getAppDataDirectory() + + "/collections"); } diff --git a/es-app/src/CollectionSystemsManager.h b/es-app/src/CollectionSystemsManager.h index 344fb969b..35162271e 100644 --- a/es-app/src/CollectionSystemsManager.h +++ b/es-app/src/CollectionSystemsManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CollectionSystemsManager.h // // Manages collections of the following two types: diff --git a/es-app/src/EmulationStation.h b/es-app/src/EmulationStation.h deleted file mode 100644 index 1333dc3f6..000000000 --- a/es-app/src/EmulationStation.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// EmulationStation.h -// -// Version and build information. -// - -#ifndef ES_APP_EMULATION_STATION_H -#define ES_APP_EMULATION_STATION_H - -// These numbers and strings need to be manually updated for a new version. -// Do this version number update as the very last commit for the new release version. -// clang-format off -#define PROGRAM_VERSION_MAJOR 2 -#define PROGRAM_VERSION_MINOR 2 -#define PROGRAM_VERSION_MAINTENANCE 1 -#define PROGRAM_RELEASE_NUMBER 40 -// clang-format on -#define PROGRAM_VERSION_STRING "2.2.1" - -#define PROGRAM_BUILT_STRING __DATE__ " - " __TIME__ - -#define RESOURCE_VERSION_STRING "2,2,1\0" -#define RESOURCE_VERSION PROGRAM_VERSION_MAJOR, PROGRAM_VERSION_MINOR, PROGRAM_VERSION_MAINTENANCE - -#endif // ES_APP_EMULATION_STATION_H diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 69eb22899..468489440 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileData.cpp // // Provides game file data structures and functions to access and sort this information. @@ -25,6 +25,10 @@ #include "views/GamelistView.h" #include "views/ViewController.h" +#if defined(__ANDROID__) +#include "utils/PlatformUtilAndroid.h" +#endif + #include #include @@ -148,6 +152,10 @@ const std::vector FileData::getChildrenRecursive() const const std::string FileData::getROMDirectory() { +#if defined(__ANDROID__) + return AndroidVariables::sROMDirectory; +#endif + const std::string& romDirSetting {Settings::getInstance()->getString("ROMDirectory")}; std::string romDirPath; @@ -180,8 +188,8 @@ const std::string FileData::getMediaDirectory() const std::string& mediaDirSetting {Settings::getInstance()->getString("MediaDirectory")}; std::string mediaDirPath; - if (mediaDirSetting == "") { - mediaDirPath = Utils::FileSystem::getHomePath() + "/.emulationstation/downloaded_media/"; + if (mediaDirSetting.empty()) { + mediaDirPath = Utils::FileSystem::getAppDataDirectory() + "/downloaded_media/"; } else { mediaDirPath = mediaDirSetting; @@ -202,7 +210,6 @@ const std::string FileData::getMediaDirectory() const std::string FileData::getMediafilePath(const std::string& subdirectory) const { - const std::vector extList {".png", ".jpg"}; std::string subFolders; // Extract possible subfolders from the path. @@ -214,8 +221,8 @@ const std::string FileData::getMediafilePath(const std::string& subdirectory) co subFolders + "/" + getDisplayName()}; // Look for an image file in the media directory. - for (size_t i {0}; i < extList.size(); ++i) { - std::string mediaPath {tempPath + extList[i]}; + for (auto& extension : sImageExtensions) { + const std::string mediaPath {tempPath + extension}; if (Utils::FileSystem::exists(mediaPath)) return mediaPath; } @@ -307,7 +314,6 @@ const std::string FileData::getCustomImagePath() const const std::string FileData::getVideoPath() const { - const std::vector extList {".avi", ".mkv", ".mov", ".mp4", ".wmv"}; std::string subFolders; // Extract possible subfolders from the path. @@ -319,8 +325,8 @@ const std::string FileData::getVideoPath() const getDisplayName()}; // Look for media in the media directory. - for (size_t i {0}; i < extList.size(); ++i) { - std::string mediaPath {tempPath + extList[i]}; + for (auto& extension : sVideoExtensions) { + const std::string mediaPath {tempPath + extension}; if (Utils::FileSystem::exists(mediaPath)) return mediaPath; } @@ -872,8 +878,13 @@ void FileData::launchGame() } } else { - LOG(LogDebug) << "FileData::launchGame(): Using default emulator \"" - << mEnvData->mLaunchCommands.front().second << "\""; + if (!mEnvData->mLaunchCommands.front().second.empty()) { + LOG(LogDebug) << "FileData::launchGame(): Using default emulator \"" + << mEnvData->mLaunchCommands.front().second << "\""; + } + else { + LOG(LogDebug) << "FileData::launchGame(): Using default emulator"; + } } if (command.empty()) @@ -882,6 +893,7 @@ void FileData::launchGame() std::string commandRaw {command}; std::string romPath {Utils::FileSystem::getEscapedPath(mPath)}; std::string baseName {Utils::FileSystem::getStem(mPath)}; + std::string romRaw {Utils::FileSystem::getPreferredPath(mPath)}; // For the special case where a directory has a supported file extension and is therefore // interpreted as a file, check if there is a matching filename inside the directory. @@ -890,7 +902,11 @@ void FileData::launchGame() for (std::string& file : Utils::FileSystem::getDirContent(mPath)) { if (Utils::FileSystem::getFileName(file) == Utils::FileSystem::getFileName(mPath) && (Utils::FileSystem::isRegularFile(file) || Utils::FileSystem::isSymlink(file))) { +#if defined(__ANDROID__) + romRaw = file; +#else romPath = Utils::FileSystem::getEscapedPath(file); +#endif baseName = baseName.substr(0, baseName.find(".")); break; } @@ -898,8 +914,13 @@ void FileData::launchGame() } const std::string fileName {baseName + Utils::FileSystem::getExtension(romPath)}; - const std::string romRaw {Utils::FileSystem::getPreferredPath(mPath)}; const std::string esPath {Utils::FileSystem::getExePath()}; + +#if defined(__ANDROID__) + // On Android we always run in the background, although the logic is a bit different + // as we don't need to wake up the application manually. + bool runInBackground {true}; +#else bool runInBackground {false}; // In addition to the global RunInBackground setting it's possible to define this flag @@ -918,6 +939,7 @@ void FileData::launchGame() // The global setting always applies. if (Settings::getInstance()->getBool("RunInBackground")) runInBackground = true; +#endif #if !defined(_WIN64) // Whether to parse .desktop files on Unix or open apps or alias files on macOS. @@ -947,6 +969,19 @@ void FileData::launchGame() bool foundCoreFile {false}; std::vector emulatorCorePaths; +#if defined(__ANDROID__) + std::string androidPackage; + std::string androidActivity; + std::string androidAction; + std::string androidCategory; + std::string androidMimeType; + std::string androidData; + std::map androidExtrasString; + std::map androidExtrasStringArray; + std::map androidExtrasBool; + std::vector androidActivityFlags; +#endif + #if defined(_WIN64) bool hideWindow {false}; @@ -997,30 +1032,27 @@ void FileData::launchGame() // Expand home path if ~ is used. command = Utils::FileSystem::expandHomePath(command); - std::string preCommandPath; - // Check for any pre-command entry, and if it exists then expand it using the find rules. if (command.find("%PRECOMMAND_") != std::string::npos) { - preCommandPath = findEmulatorPath(command, true); + const std::pair preCommand { + findEmulator(command, true)}; // Show an error message if there was no matching emulator entry in es_find_rules.xml. - if (preCommandPath.substr(0, 18) == "NO EMULATOR RULE: ") { - const std::string& preCommandEntry { - preCommandPath.substr(18, preCommandPath.size() - 18)}; + if (preCommand.second == FileData::findEmulatorResult::NO_RULES) { LOG(LogError) << "Couldn't launch game, either there is no emulator entry for pre-command \"" - << preCommandEntry << "\" in es_find_rules.xml or there are no rules defined"; + << preCommand.first << "\" in es_find_rules.xml or there are no rules defined"; LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << commandRaw; window->queueInfoPopup("ERROR: MISSING PRE-COMMAND FIND RULES CONFIGURATION FOR '" + - preCommandEntry + "'", + preCommand.first + "'", 6000); window->setAllowTextScrolling(true); window->setAllowFileAnimation(true); return; } - else if (preCommandPath.empty()) { - LOG(LogError) << "Couldn't launch game, pre-command binary not found"; + else if (preCommand.first.empty()) { + LOG(LogError) << "Couldn't launch game, pre-command not found"; LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << commandRaw; @@ -1047,30 +1079,30 @@ void FileData::launchGame() return; } else { - LOG(LogDebug) << "FileData::launchGame(): Pre-command binary set to \"" - << preCommandPath << "\""; + LOG(LogDebug) << "FileData::launchGame(): Pre-command set to \"" << preCommand.first + << "\""; } } - // Check that the emulator binary actually exists, and if so, get its path. - const std::string& binaryPath {findEmulatorPath(command, false)}; + // Check that the emulator actually exists, and if so, get its path. + const std::pair emulator { + findEmulator(command, false)}; // Show an error message if there was no matching emulator entry in es_find_rules.xml. - if (binaryPath.substr(0, 18) == "NO EMULATOR RULE: ") { - const std::string& emulatorEntry {binaryPath.substr(18, binaryPath.size() - 18)}; + if (emulator.second == FileData::findEmulatorResult::NO_RULES) { LOG(LogError) << "Couldn't launch game, either there is no emulator entry for \"" - << emulatorEntry << "\" in es_find_rules.xml or there are no rules defined"; + << emulator.first << "\" in es_find_rules.xml or there are no rules defined"; LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << commandRaw; window->queueInfoPopup( - "ERROR: MISSING EMULATOR FIND RULES CONFIGURATION FOR '" + emulatorEntry + "'", 6000); + "ERROR: MISSING EMULATOR FIND RULES CONFIGURATION FOR '" + emulator.first + "'", 6000); window->setAllowTextScrolling(true); window->setAllowFileAnimation(true); return; } - else if (binaryPath.empty()) { - LOG(LogError) << "Couldn't launch game, emulator binary not found"; + else if (emulator.second == FileData::findEmulatorResult::NOT_FOUND) { + LOG(LogError) << "Couldn't launch game, emulator not found"; LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << commandRaw; @@ -1098,15 +1130,29 @@ void FileData::launchGame() } #if defined(_WIN64) else { - std::string binaryLogPath {Utils::String::replace( - Utils::String::replace(binaryPath, "%ESPATH%", esPath), "/", "\\")}; - if (binaryLogPath.front() != '\"' && binaryLogPath.back() != '\"') - binaryLogPath = "\"" + binaryLogPath + "\""; - LOG(LogDebug) << "FileData::launchGame(): Emulator binary set to " << binaryLogPath; + std::string emulatorLogPath {Utils::String::replace( + Utils::String::replace(emulator.first, "%ESPATH%", esPath), "/", "\\")}; + if (emulatorLogPath.front() != '\"' && emulatorLogPath.back() != '\"') + emulatorLogPath = "\"" + emulatorLogPath + "\""; + LOG(LogDebug) << "FileData::launchGame(): Emulator set to " << emulatorLogPath; #else +#if defined(__ANDROID__) + else if (emulator.second == FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE) { + androidPackage = emulator.first; + size_t separatorPos {androidPackage.find('/')}; + + if (separatorPos != std::string::npos) { + androidActivity = androidPackage.substr(separatorPos + 1); + androidPackage = androidPackage.substr(0, separatorPos); + } + + LOG(LogDebug) << "FileData::launchGame(): Found emulator package \"" << androidPackage + << "\""; + } +#endif else if (!isShortcut) { - LOG(LogDebug) << "FileData::launchGame(): Emulator binary set to \"" - << Utils::String::replace(binaryPath, "%ESPATH%", esPath) << "\""; + LOG(LogDebug) << "FileData::launchGame(): Emulator set to \"" + << Utils::String::replace(emulator.first, "%ESPATH%", esPath) << "\""; #endif } @@ -1127,11 +1173,12 @@ void FileData::launchGame() if (spacePos != std::string::npos) { coreRaw = command.substr(emuPathPos, spacePos - emuPathPos); #if defined(_WIN64) - coreFile = Utils::FileSystem::getParent(Utils::String::replace(binaryPath, "\"", "")) + - command.substr(emuPathPos + 9, spacePos - emuPathPos - 9); + coreFile = + Utils::FileSystem::getParent(Utils::String::replace(emulator.first, "\"", "")) + + command.substr(emuPathPos + 9, spacePos - emuPathPos - 9); coreFile = Utils::String::replace(coreFile, "/", "\\"); #else - coreFile = Utils::FileSystem::getParent(binaryPath) + + coreFile = Utils::FileSystem::getParent(emulator.first) + command.substr(emuPathPos + 9, spacePos - emuPathPos - 9); #endif if (hasQuotationMark) { @@ -1192,7 +1239,7 @@ void FileData::launchGame() // the emulator core using the rules defined in es_find_rules.xml. for (std::string& path : emulatorCorePaths) { // The position of the %CORE_ variable could have changed as there may have been an - // %EMULATOR_ variable that was substituted for the actual emulator binary. + // %EMULATOR_ variable that was substituted for the actual emulator. coreEntryPos = command.find("%CORE_"); coreFilePos = command.find("%", coreEntryPos + 6); @@ -1218,10 +1265,11 @@ void FileData::launchGame() #if defined(_WIN64) coreFile = coreFile.replace( stringPos, 9, - Utils::FileSystem::getParent(Utils::String::replace(binaryPath, "\"", ""))); + Utils::FileSystem::getParent(Utils::String::replace(emulator.first, "\"", ""))); coreFile = Utils::String::replace(coreFile, "/", "\\"); #else - coreFile = coreFile.replace(stringPos, 9, Utils::FileSystem::getParent(binaryPath)); + coreFile = + coreFile.replace(stringPos, 9, Utils::FileSystem::getParent(emulator.first)); #endif } @@ -1325,7 +1373,7 @@ void FileData::launchGame() #if defined(_WIN64) startDirectory = Utils::String::replace( startDirectory, "%EMUDIR%", - Utils::FileSystem::getParent(Utils::String::replace(binaryPath, "\"", ""))); + Utils::FileSystem::getParent(Utils::String::replace(emulator.first, "\"", ""))); startDirectory = Utils::String::replace( startDirectory, "%GAMEDIR%", @@ -1336,7 +1384,7 @@ void FileData::launchGame() #else startDirectory = Utils::String::replace( startDirectory, "%EMUDIR%", - Utils::FileSystem::getParent(Utils::String::replace(binaryPath, "\\", ""))); + Utils::FileSystem::getParent(Utils::String::replace(emulator.first, "\\", ""))); startDirectory = Utils::String::replace( startDirectory, "%GAMEDIR%", @@ -1500,7 +1548,7 @@ void FileData::launchGame() if (Utils::FileSystem::exists(Utils::String::replace(romPath, "\\", ""))) { LOG(LogInfo) << "Opening app or alias file \"" << Utils::String::replace(romPath, "\\", "") << "\""; - command = Utils::String::replace(command, binaryPath, "open -W -a"); + command = Utils::String::replace(command, emulator.first, "open -W -a"); } else { LOG(LogError) << "App or alias file \"" << romPath @@ -1551,7 +1599,7 @@ void FileData::launchGame() } romPath = Utils::String::replace(romPath, "%%", "%"); romPath = Utils::String::trim(romPath); - command = Utils::String::replace(command, binaryPath, ""); + command = Utils::String::replace(command, emulator.first, ""); execEntry = true; break; } @@ -1576,6 +1624,7 @@ void FileData::launchGame() #endif #endif +#if !defined(__ANDROID__) // Replace the remaining variables with their actual values. command = Utils::String::replace(command, "%ROM%", romPath); command = Utils::String::replace(command, "%BASENAME%", baseName); @@ -1583,12 +1632,142 @@ void FileData::launchGame() command = Utils::String::replace(command, "%ROMRAW%", romRaw); command = Utils::String::replace(command, "%ROMPATH%", Utils::FileSystem::getEscapedPath(getROMDirectory())); +#else + command = Utils::String::replace(command, "%ANDROIDPACKAGE%", androidPackage); + + const std::vector androidVariabels { + "%ACTION%=", "%CATEGORY%=", "%MIMETYPE%=", "%DATA%="}; + + for (std::string variable : androidVariabels) { + size_t dataPos {command.find(variable)}; + if (dataPos != std::string::npos) { + bool invalidEntry {false}; + bool isQuoted {(command.length() > dataPos + variable.length() && + command[dataPos + variable.length()] == '\"')}; + std::string value; + + if (isQuoted) { + const size_t closeQuotePos {command.find("\"", dataPos + variable.length() + 1)}; + if (closeQuotePos != std::string::npos) + value = command.substr(dataPos + variable.length() + 1, + closeQuotePos - (dataPos + variable.length() + 1)); + else + invalidEntry = true; + } + else { + const size_t spacePos {command.find(" ", dataPos)}; + if (spacePos != std::string::npos) + value = command.substr(dataPos + variable.length(), + spacePos - (dataPos + variable.length())); + else + value = command.substr(dataPos + variable.length(), + command.size() - dataPos + variable.length()); + } + + if (invalidEntry) { + LOG(LogError) << "Invalid entry in systems configuration file es_systems.xml"; + LOG(LogError) << "Raw emulator launch command:"; + LOG(LogError) << commandRaw; + + window->queueInfoPopup("ERROR: INVALID ENTRY IN SYSTEMS CONFIGURATION FILE", 6000); + window->setAllowTextScrolling(true); + window->setAllowFileAnimation(true); + return; + } + + if (variable == "%ACTION%=") + androidAction = value; + else if (variable == "%DATA%=") + androidData = value; + else if (variable == "%CATEGORY%=") + androidCategory = value; + else if (variable == "%MIMETYPE%=") + androidMimeType = value; + } + } + + std::vector extraVariabels {"%EXTRA_", "%EXTRAARRAY_", "%EXTRABOOL_"}; + + for (std::string variable : extraVariabels) { + size_t extraPos {command.find(variable)}; + while (extraPos != std::string::npos) { + if (extraPos != std::string::npos) { + bool invalidEntry {false}; + bool isQuoted {false}; + std::string extraName; + std::string extraValue; + + size_t equalPos {command.find("=", extraPos)}; + if (equalPos == std::string::npos) + invalidEntry = true; + + if (!invalidEntry && extraPos + variable.length() + 1 >= command.size()) + invalidEntry = true; + + if (!invalidEntry) { + if (command.length() > equalPos && command[equalPos + 1] == '\"') + isQuoted = true; + + extraName = command.substr(extraPos + variable.length(), + equalPos - (extraPos + variable.length() + 1)); + + if (isQuoted) { + const size_t closeQuotePos {command.find("\"", equalPos + 2)}; + if (closeQuotePos != std::string::npos) + extraValue = + command.substr(equalPos + 2, closeQuotePos - (equalPos + 2)); + else + invalidEntry = true; + } + else { + const size_t spacePos {command.find(" ", extraPos)}; + if (spacePos != std::string::npos) + extraValue = command.substr(equalPos + 1, spacePos - (equalPos + 1)); + else + extraValue = command.substr(equalPos + 1, command.size() - equalPos); + } + + if (invalidEntry) { + LOG(LogError) + << "Invalid entry in systems configuration file es_systems.xml"; + LOG(LogError) << "Raw emulator launch command:"; + LOG(LogError) << commandRaw; + + window->queueInfoPopup("ERROR: INVALID ENTRY IN SYSTEMS CONFIGURATION FILE", + 6000); + window->setAllowTextScrolling(true); + window->setAllowFileAnimation(true); + return; + } + + if (extraName != "" && extraValue != "") { + if (variable == "%EXTRA_") + androidExtrasString[extraName] = extraValue; + else if (variable == "%EXTRAARRAY_") + androidExtrasStringArray[extraName] = extraValue; + else if (variable == "%EXTRABOOL_") + androidExtrasBool[extraName] = extraValue; + } + } + } + extraPos = command.find(variable, extraPos + 1); + } + } + + if (command.find("%ACTIVITY_CLEAR_TASK%") != std::string::npos) + androidActivityFlags.emplace_back("%ACTIVITY_CLEAR_TASK%"); + if (command.find("%ACTIVITY_CLEAR_TOP%") != std::string::npos) + androidActivityFlags.emplace_back("%ACTIVITY_CLEAR_TOP%"); + if (command.find("%ACTIVITY_NO_HISTORY%") != std::string::npos) + androidActivityFlags.emplace_back("%ACTIVITY_NO_HISTORY%"); +#endif + #if defined(_WIN64) command = Utils::String::replace( command, "%ESPATH%", Utils::String::replace(Utils::FileSystem::getExePath(), "/", "\\")); command = Utils::String::replace(command, "%EMUDIR%", Utils::FileSystem::getEscapedPath(Utils::FileSystem::getParent( - Utils::String::replace(binaryPath, "\"", "")))); + Utils::String::replace(emulator.first, "\"", "")))); command = Utils::String::replace(command, "%GAMEDIR%", Utils::FileSystem::getEscapedPath(Utils::FileSystem::getParent( Utils::String::replace(romPath, "\"", "")))); @@ -1600,7 +1779,7 @@ void FileData::launchGame() command = Utils::String::replace(command, "%ESPATH%", Utils::FileSystem::getExePath()); command = Utils::String::replace(command, "%EMUDIR%", Utils::FileSystem::getEscapedPath(Utils::FileSystem::getParent( - Utils::String::replace(binaryPath, "\\", "")))); + Utils::String::replace(emulator.first, "\\", "")))); command = Utils::String::replace(command, "%GAMEDIR%", Utils::FileSystem::getEscapedPath(Utils::FileSystem::getParent( Utils::String::replace(romPath, "\\", "")))); @@ -1625,8 +1804,40 @@ void FileData::launchGame() LOG(LogDebug) << "Raw emulator launch command:"; LOG(LogDebug) << commandRaw; +#if defined(__ANDROID__) + LOG(LogInfo) << "Expanded emulator launch arguments:"; + LOG(LogInfo) << "Package: " << androidPackage; + if (androidActivity != "") { + LOG(LogInfo) << "Activity: " << androidActivity; + } + if (androidAction != "") { + LOG(LogInfo) << "Action: " << androidAction; + } + if (androidCategory != "") { + LOG(LogInfo) << "Category: " << androidCategory; + } + if (androidMimeType != "") { + LOG(LogInfo) << "MIME type: " << androidMimeType; + } + if (androidData != "") { + LOG(LogInfo) << "Data: " << androidData; + } + for (auto& extra : androidExtrasString) { + LOG(LogInfo) << "Extra name: " << extra.first; + LOG(LogInfo) << "Extra value: " << extra.second; + } + for (auto& extra : androidExtrasStringArray) { + LOG(LogInfo) << "Extra array name: " << extra.first; + LOG(LogInfo) << "Extra array value: " << extra.second; + } + for (auto& extra : androidExtrasBool) { + LOG(LogInfo) << "Extra bool name: " << extra.first; + LOG(LogInfo) << "Extra bool value: " << extra.second; + } +#else LOG(LogInfo) << "Expanded emulator launch command:"; LOG(LogInfo) << command; +#endif #if defined(FLATPAK_BUILD) // Break out of the sandbox. @@ -1645,12 +1856,17 @@ void FileData::launchGame() returnValue = Utils::Platform::launchGameWindows( Utils::String::stringToWideString(command), Utils::String::stringToWideString(startDirectory), runInBackground, hideWindow); +#elif defined(__ANDROID__) + returnValue = Utils::Platform::Android::launchGame( + androidPackage, androidActivity, androidAction, androidCategory, androidMimeType, + androidData, romRaw, androidExtrasString, androidExtrasStringArray, androidExtrasBool, + androidActivityFlags); #else - returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground); +returnValue = Utils::Platform::launchGameUnix(command, startDirectory, runInBackground); #endif // Notify the user in case of a failed game launch using a popup window. if (returnValue != 0) { - LOG(LogWarning) << "...launch terminated with nonzero return value " << returnValue; + LOG(LogWarning) << "Launch terminated with nonzero return value " << returnValue; window->queueInfoPopup("ERROR LAUNCHING GAME '" + Utils::String::toUpper(metadata.get("name")) + "' (ERROR CODE " + @@ -1692,8 +1908,7 @@ void FileData::launchGame() getSourceFileData()->getSystem()->getFullName()); } else { - std::vector& gameEndParams { - ViewController::getInstance()->getGameEndEventParams()}; + std::vector& gameEndParams {window->getGameEndEventParams()}; gameEndParams.emplace_back("game-end"); gameEndParams.emplace_back(romPath); gameEndParams.emplace_back(getSourceFileData()->metadata.get("name")); @@ -1737,23 +1952,27 @@ void FileData::launchGame() gameToUpdate->mSystem->onMetaDataSavePoint(); } -const std::string FileData::findEmulatorPath(std::string& command, const bool preCommand) +const std::pair FileData::findEmulator( + std::string& command, const bool preCommand) { // Extract the emulator executable from the launch command string. There are two ways // that the emulator can be defined in es_systems.xml, either using the find rules in - // es_find_rules.xml or via the explicit emulator binary name. In the former case, we + // es_find_rules.xml or via the explicit emulator name. In the former case, we // need to process any configured systempath and staticpath rules (and for Windows also // winregistrypath and winregistryvalue rules), and in the latter case we simply search - // for the emulator binary in the system path. + // for the emulator in the system path. std::string emuExecutable; std::string exePath; - // Method 1, emulator binary is defined using find rules: + // Method 1, emulator is defined using find rules: #if defined(_WIN64) std::vector emulatorWinRegistryPaths; std::vector emulatorWinRegistryValues; +#endif +#if defined(__ANDROID__) + std::vector emulatorAndroidPackages; #endif std::vector emulatorSystemPaths; std::vector emulatorStaticPaths; @@ -1782,6 +2001,10 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryPaths; emulatorWinRegistryValues = SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryValues; +#endif +#if defined(__ANDROID__) + emulatorAndroidPackages = + SystemData::sFindRules.get()->mEmulators[emulatorEntry].androidPackages; #endif emulatorSystemPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].systemPaths; @@ -1793,10 +2016,13 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr if (emulatorEntry != "" && emulatorWinRegistryPaths.empty() && emulatorWinRegistryValues.empty() && emulatorSystemPaths.empty() && emulatorStaticPaths.empty()) +#elif defined(__ANDROID__) + if (emulatorEntry != "" && emulatorAndroidPackages.empty() && emulatorSystemPaths.empty() && + emulatorStaticPaths.empty()) #else if (emulatorEntry != "" && emulatorSystemPaths.empty() && emulatorStaticPaths.empty()) #endif - return "NO EMULATOR RULE: " + emulatorEntry; + return std::make_pair(emulatorEntry, FileData::findEmulatorResult::NO_RULES); #if defined(_WIN64) for (std::string& path : emulatorWinRegistryPaths) { @@ -1834,19 +2060,19 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr continue; } - // That a value was found does not guarantee that the emulator binary actually exists, - // so check for that as well. + // That a value was found does not guarantee that the emulator actually exists, so + // check for that as well. if (pathStatus == ERROR_SUCCESS) { if (Utils::FileSystem::isRegularFile(Utils::String::wideStringToString(registryPath)) || Utils::FileSystem::isSymlink(Utils::String::wideStringToString(registryPath))) { - LOG(LogDebug) << "FileData::findEmulatorPath(): " - << (preCommand ? "Pre-command binary" : "Emulator binary") + LOG(LogDebug) << "FileData::findEmulator(): " + << (preCommand ? "Pre-command" : "Emulator") << " found via winregistrypath rule"; exePath = Utils::FileSystem::getEscapedPath( Utils::String::wideStringToString(registryPath)); command.replace(startPos, endPos - startPos + 1, exePath); RegCloseKey(registryKey); - return exePath; + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } } RegCloseKey(registryKey); @@ -1906,25 +2132,47 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr if (!appendString.empty()) path.append(Utils::String::stringToWideString(appendString)); - // That a value was found does not guarantee that the emulator binary actually exists, + // That a value was found does not guarantee that the emulator actually exists, // so check for that as well. if (pathStatus == ERROR_SUCCESS) { if (Utils::FileSystem::isRegularFile(Utils::String::wideStringToString(path)) || Utils::FileSystem::isSymlink(Utils::String::wideStringToString(path))) { - LOG(LogDebug) << "FileData::findEmulatorPath(): " - << (preCommand ? "Pre-command binary" : "Emulator binary") + LOG(LogDebug) << "FileData::findEmulator(): " + << (preCommand ? "Pre-command" : "Emulator") << " found via winregistryvalue rule"; exePath = Utils::FileSystem::getEscapedPath(Utils::String::wideStringToString(path)); command.replace(startPos, endPos - startPos + 1, exePath); RegCloseKey(registryKey); - return exePath; + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } } RegCloseKey(registryKey); } #endif +#if defined(__ANDROID__) + for (std::string& androidpackage : emulatorAndroidPackages) { + // If a forward slash character is present in the androidpackage entry it means an explicit + // Intent activity should be used rather than the default one. The checkEmulatorInstalled() + // Java function will check for the activity as well and if it's not found it flags the + // overall emulator entry as not found. + std::string packageName {androidpackage}; + std::string activity; + size_t separatorPos {packageName.find('/')}; + + if (separatorPos != std::string::npos) { + activity = packageName.substr(separatorPos + 1); + packageName = packageName.substr(0, separatorPos); + } + + if (Utils::Platform::Android::checkEmulatorInstalled(packageName, activity)) { + return std::make_pair(androidpackage, + FileData::findEmulatorResult::FOUND_ANDROID_PACKAGE); + } + } +#endif + for (std::string& path : emulatorSystemPaths) { #if defined(_WIN64) std::wstring pathWide {Utils::String::stringToWideString(path)}; @@ -1945,30 +2193,30 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr } } if (exePath != "") { - LOG(LogDebug) << "FileData::findEmulatorPath(): " - << (preCommand ? "Pre-command binary" : "Emulator binary") + LOG(LogDebug) << "FileData::findEmulator(): " + << (preCommand ? "Pre-command" : "Emulator") << " found via systempath rule"; exePath += "\\" + path; exePath = Utils::FileSystem::getEscapedPath(exePath); command.replace(startPos, endPos - startPos + 1, exePath); - return exePath; + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } #else exePath = Utils::FileSystem::getPathToBinary(path); if (exePath != "") { - LOG(LogDebug) << "FileData::findEmulatorPath(): " - << (preCommand ? "Pre-command binary" : "Emulator binary") + LOG(LogDebug) << "FileData::findEmulator(): " + << (preCommand ? "Pre-command" : "Emulator") << " found via systempath rule"; exePath += "/" + path; command.replace(startPos, endPos - startPos + 1, exePath); - return exePath; + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } #endif } for (std::string& path : emulatorStaticPaths) { // If a pipe character is present in the staticpath entry it means we should substitute - // the emulator binary with whatever is defined after the pipe character. + // the emulator with whatever is defined after the pipe character. std::string replaceCommand; const size_t pipePos {path.find('|')}; @@ -1998,23 +2246,23 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr } if (Utils::FileSystem::isRegularFile(path) || Utils::FileSystem::isSymlink(path)) { - LOG(LogDebug) << "FileData::findEmulatorPath(): " - << (preCommand ? "Pre-command binary" : "Emulator binary") + LOG(LogDebug) << "FileData::findEmulator(): " + << (preCommand ? "Pre-command" : "Emulator") << " found via staticpath rule"; if (replaceCommand == "") { exePath = Utils::FileSystem::getEscapedPath(path); } else { - LOG(LogDebug) << "FileData::findEmulatorPath(): Replacing emulator binary in " + LOG(LogDebug) << "FileData::findEmulator(): Replacing emulator in " "staticpath rule with explicitly defined command"; exePath = replaceCommand; } command.replace(startPos, endPos - startPos + 1, exePath); - return exePath; + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } } - // Method 2, exact emulator binary name: + // Method 2, exact emulator name: // If %ESPATH% is used, then expand it to the binary directory of ES-DE. command = Utils::String::replace(command, "%ESPATH%", Utils::FileSystem::getExePath()); @@ -2052,7 +2300,7 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr exePath = Utils::String::wideStringToString(pathBuffer.data()); } -#else +#elif !defined(__ANDROID__) if (Utils::FileSystem::isRegularFile(emuExecutable) || Utils::FileSystem::isSymlink(emuExecutable)) { exePath = Utils::FileSystem::getEscapedPath(emuExecutable); @@ -2065,7 +2313,10 @@ const std::string FileData::findEmulatorPath(std::string& command, const bool pr } #endif - return exePath; + if (exePath.empty()) + return std::make_pair("", FileData::findEmulatorResult::NOT_FOUND); + else + return std::make_pair(exePath, FileData::findEmulatorResult::FOUND_FILE); } CollectionFileData::CollectionFileData(FileData* file, SystemData* system) diff --git a/es-app/src/FileData.h b/es-app/src/FileData.h index 46aed47e3..a12e5613d 100644 --- a/es-app/src/FileData.h +++ b/es-app/src/FileData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileData.h // // Provides game file data structures and functions to access and sort this information. @@ -40,11 +40,7 @@ public: const std::string& getName() { return metadata.get("name"); } const std::string& getSortName(); // Returns our best guess at the "real" name for this file. - std::string getDisplayName() const - { - const std::string& stem {Utils::FileSystem::getStem(mPath)}; - return stem; - } + std::string getDisplayName() const { return Utils::FileSystem::getStem(mPath); } std::string getCleanName() const { return Utils::String::removeParenthesis(this->getDisplayName()); @@ -112,8 +108,8 @@ public: bool excludeRecursively, bool respectExclusions) const; - void addChild(FileData* file); // Error if mType != FOLDER - void removeChild(FileData* file); // Error if mType != FOLDER + void addChild(FileData* file); + void removeChild(FileData* file); virtual std::string getKey() { return getFileName(); } const bool isArcadeAsset() const; @@ -123,8 +119,16 @@ public: virtual FileData* getSourceFileData() { return this; } const std::string& getSystemName() const { return mSystemName; } + enum class findEmulatorResult { + FOUND_FILE, + FOUND_ANDROID_PACKAGE, + NOT_FOUND, + NO_RULES + }; + void launchGame(); - const std::string findEmulatorPath(std::string& command, const bool preCommand); + const std::pair findEmulator(std::string& command, + const bool preCommand); using ComparisonFunction = bool(const FileData* a, const FileData* b); struct SortType { @@ -167,6 +171,9 @@ private: std::vector mChildrenLastPlayed; std::vector mChildrenMostPlayed; std::function mUpdateListCallback; + static inline std::vector sImageExtensions {".png", ".jpg"}; + static inline std::vector sVideoExtensions {".mp4", ".mkv", ".avi", + ".mp4", ".wmv", ".mov"}; // The pair includes all games, and favorite games. std::pair mGameCount; bool mOnlyFolders; diff --git a/es-app/src/FileFilterIndex.cpp b/es-app/src/FileFilterIndex.cpp index 3c63f03bf..760fb6ef6 100644 --- a/es-app/src/FileFilterIndex.cpp +++ b/es-app/src/FileFilterIndex.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileFilterIndex.cpp // // Gamelist filters. diff --git a/es-app/src/FileFilterIndex.h b/es-app/src/FileFilterIndex.h index a034a361e..10dc6e98f 100644 --- a/es-app/src/FileFilterIndex.h +++ b/es-app/src/FileFilterIndex.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileFilterIndex.h // // Gamelist filters. diff --git a/es-app/src/FileSorts.cpp b/es-app/src/FileSorts.cpp index 7db7f2e64..48b8b057e 100644 --- a/es-app/src/FileSorts.cpp +++ b/es-app/src/FileSorts.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSorts.cpp // // Gamelist sorting functions. diff --git a/es-app/src/FileSorts.h b/es-app/src/FileSorts.h index e7f84346d..d12725d57 100644 --- a/es-app/src/FileSorts.h +++ b/es-app/src/FileSorts.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSorts.h // // Gamelist sorting functions. diff --git a/es-app/src/GamelistFileParser.cpp b/es-app/src/GamelistFileParser.cpp index 35563cf6e..7958637ba 100644 --- a/es-app/src/GamelistFileParser.cpp +++ b/es-app/src/GamelistFileParser.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistFileParser.cpp // // Parses and updates the gamelist.xml files. diff --git a/es-app/src/GamelistFileParser.h b/es-app/src/GamelistFileParser.h index 465c3e462..b53670711 100644 --- a/es-app/src/GamelistFileParser.h +++ b/es-app/src/GamelistFileParser.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistFileParser.h // // Parses and updates the gamelist.xml files. diff --git a/es-app/src/MediaViewer.cpp b/es-app/src/MediaViewer.cpp index a975f7516..a682ce637 100644 --- a/es-app/src/MediaViewer.cpp +++ b/es-app/src/MediaViewer.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MediaViewer.cpp // // Fullscreen game media viewer. diff --git a/es-app/src/MediaViewer.h b/es-app/src/MediaViewer.h index d1a8789ec..fb36559cc 100644 --- a/es-app/src/MediaViewer.h +++ b/es-app/src/MediaViewer.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MediaViewer.h // // Fullscreen game media viewer. diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 79d8a9efd..15072160a 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MetaData.cpp // // Static data for default metadata values as well as functions diff --git a/es-app/src/MetaData.h b/es-app/src/MetaData.h index 4ae9fabe6..2384e165f 100644 --- a/es-app/src/MetaData.h +++ b/es-app/src/MetaData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MetaData.h // // Static data for default metadata values as well as functions diff --git a/es-app/src/MiximageGenerator.cpp b/es-app/src/MiximageGenerator.cpp index 73a39ea0c..a2714643e 100644 --- a/es-app/src/MiximageGenerator.cpp +++ b/es-app/src/MiximageGenerator.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MiximageGenerator.cpp // // Generates miximages from screenshots, marquees, 3D boxes/covers and physical media images. @@ -895,6 +895,17 @@ std::string MiximageGenerator::getSavePath() const if (!Utils::FileSystem::exists(path)) Utils::FileSystem::createDirectory(path); +#if defined(__ANDROID__) + if (!Utils::FileSystem::exists(path + ".nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" << path + ".nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(path + ".nomedia"); + if (!Utils::FileSystem::exists(path + ".nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } +#endif + path += mGame->getSystemName() + "/miximages" + subFolders + "/"; if (!Utils::FileSystem::exists(path)) diff --git a/es-app/src/MiximageGenerator.h b/es-app/src/MiximageGenerator.h index ffc7a7cfa..a1f501bcc 100644 --- a/es-app/src/MiximageGenerator.h +++ b/es-app/src/MiximageGenerator.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MiximageGenerator.h // // Generates miximages from screenshots, marquees, 3D boxes/covers and physical media images. diff --git a/es-app/src/PDFViewer.cpp b/es-app/src/PDFViewer.cpp index 6f59e98f0..81cfb3dad 100644 --- a/es-app/src/PDFViewer.cpp +++ b/es-app/src/PDFViewer.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // PDFViewer.cpp // // Parses and renders pages using the Poppler library via the external es-pdf-convert binary. @@ -20,6 +20,10 @@ #include #endif +#if defined(__ANDROID__) +#include "ConvertPDF.h" +#endif + #define DEBUG_PDF_CONVERSION false #define KEY_REPEAT_START_DELAY 600 @@ -51,6 +55,7 @@ bool PDFViewer::startPDFViewer(FileData* game) { ViewController::getInstance()->pauseViewVideos(); +#if !defined(__ANDROID__) #if defined(_WIN64) const std::string convertBinary {"/es-pdf-converter/es-pdf-convert.exe"}; #else @@ -67,6 +72,7 @@ bool PDFViewer::startPDFViewer(FileData* game) ViewController::getInstance()->startViewVideos(); return false; } +#endif // !__ANDROID__ mGame = game; mManualPath = mGame->getManualPath(); @@ -298,6 +304,9 @@ bool PDFViewer::getDocumentInfo() // Close process and thread handles. CloseHandle(pi.hProcess); CloseHandle(pi.hThread); +#elif defined(__ANDROID__) + if (ConvertPDF::processFile(mManualPath, "-fileinfo", 0, 0, 0, commandOutput) == -1) + return false; #else FILE* commandPipe; std::array buffer {}; @@ -439,6 +448,13 @@ void PDFViewer::convertPage(int pageNum) CloseHandle(childStdoutRead); WaitForSingleObject(pi.hThread, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE); +#elif (__ANDROID__) + ConvertPDF::processFile(mManualPath, "-convert", pageNum, + static_cast(mPages[pageNum].width), + static_cast(mPages[pageNum].height), imageData); + mPages[pageNum].imageData.insert(mPages[pageNum].imageData.end(), + std::make_move_iterator(imageData.begin()), + std::make_move_iterator(imageData.end())); #else FILE* commandPipe; std::array buffer {}; @@ -461,6 +477,8 @@ void PDFViewer::convertPage(int pageNum) #if defined(_WIN64) if (!processReturnValue || (static_cast(imageDataSize) < mPages[pageNum].width * mPages[pageNum].height * 4)) { +#elif defined(__ANDROID__) + if (static_cast(imageDataSize) < mPages[pageNum].width * mPages[pageNum].height * 4) { #else if (returnValue != 0 || (static_cast(imageDataSize) < mPages[pageNum].width * mPages[pageNum].height * 4)) { diff --git a/es-app/src/PDFViewer.h b/es-app/src/PDFViewer.h index 8a1d82eba..735009a17 100644 --- a/es-app/src/PDFViewer.h +++ b/es-app/src/PDFViewer.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // PDFViewer.h // // Parses and renders pages using the Poppler library via the external es-pdf-convert binary. diff --git a/es-app/src/PlatformId.cpp b/es-app/src/PlatformId.cpp index 9b76d08e5..b427bbd78 100644 --- a/es-app/src/PlatformId.cpp +++ b/es-app/src/PlatformId.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // PlatformId.cpp // // Index of all supported systems/platforms. diff --git a/es-app/src/PlatformId.h b/es-app/src/PlatformId.h index dccaf987f..3520a090c 100644 --- a/es-app/src/PlatformId.h +++ b/es-app/src/PlatformId.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // PlatformId.h // // Index of all supported systems/platforms. diff --git a/es-app/src/Screensaver.cpp b/es-app/src/Screensaver.cpp index 3319922a7..be15e5088 100644 --- a/es-app/src/Screensaver.cpp +++ b/es-app/src/Screensaver.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Screensaver.cpp // // Screensaver, supporting the following types: @@ -464,8 +464,11 @@ void Screensaver::generateVideoList() void Screensaver::generateCustomImageList() { - std::string imageDir = Utils::FileSystem::expandHomePath( - Settings::getInstance()->getString("ScreensaverSlideshowImageDir")); + std::string imageDir {Utils::FileSystem::expandHomePath( + Settings::getInstance()->getString("ScreensaverSlideshowCustomDir"))}; + + if (imageDir.empty()) + imageDir = Utils::FileSystem::getAppDataDirectory() + "/screensavers/custom_slideshow"; // This makes it possible to set the custom image directory relative to the ES-DE binary // directory or the ROM directory. @@ -473,19 +476,23 @@ void Screensaver::generateCustomImageList() imageDir = Utils::String::replace(imageDir, "%ROMPATH%", FileData::getROMDirectory()); if (imageDir != "" && Utils::FileSystem::isDirectory(imageDir)) { - std::string imageFilter {".jpg, .JPG, .png, .PNG"}; - Utils::FileSystem::StringList dirContent = Utils::FileSystem::getDirContent( - imageDir, Settings::getInstance()->getBool("ScreensaverSlideshowRecurse")); + const std::vector extList {".jpg", ".JPG", ".png", ".PNG", ".gif", + ".GIF", ".webp", ".WEBP", ".svg", ".SVG"}; + + Utils::FileSystem::StringList dirContent {Utils::FileSystem::getDirContent( + imageDir, Settings::getInstance()->getBool("ScreensaverSlideshowRecurse"))}; for (auto it = dirContent.begin(); it != dirContent.end(); ++it) { if (Utils::FileSystem::isRegularFile(*it)) { - if (imageFilter.find(Utils::FileSystem::getExtension(*it)) != std::string::npos) + if (std::find(extList.cbegin(), extList.cend(), + Utils::FileSystem::getExtension(*it)) != extList.cend()) mImageCustomFiles.push_back(*it); } } } else { - LOG(LogWarning) << "Custom screensaver image directory '" << imageDir << "' does not exist"; + LOG(LogWarning) << "Custom screensaver image directory \"" << imageDir + << "\" does not exist"; } mCustomFilesInventory.insert(mCustomFilesInventory.begin(), mImageCustomFiles.begin(), diff --git a/es-app/src/Screensaver.h b/es-app/src/Screensaver.h index 30d123ba9..62b8134a8 100644 --- a/es-app/src/Screensaver.h +++ b/es-app/src/Screensaver.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Screensaver.h // // Screensaver, supporting the following types: diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index b54e0b487..81c340a17 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemData.cpp // // Provides data structures for the game systems and populates and indexes them based @@ -42,15 +42,20 @@ FindRules::FindRules() void FindRules::loadFindRules() { std::vector paths; - std::string filePath {Utils::FileSystem::getHomePath() + "/.emulationstation/custom_systems" + - "/es_find_rules.xml"}; - + std::string filePath {Utils::FileSystem::getAppDataDirectory() + + "/custom_systems/es_find_rules.xml"}; if (Utils::FileSystem::exists(filePath)) { paths.emplace_back(filePath); LOG(LogInfo) << "Found custom find rules configuration file"; } -#if defined(_WIN64) +#if defined(__ANDROID__) + filePath = ResourceManager::getInstance().getResourcePath(":/systems/android/es_find_rules.xml", + false); +#elif defined(__linux__) + filePath = + ResourceManager::getInstance().getResourcePath(":/systems/linux/es_find_rules.xml", false); +#elif defined(_WIN64) filePath = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_find_rules.xml", false); #elif defined(__APPLE__) @@ -61,12 +66,12 @@ void FindRules::loadFindRules() ResourceManager::getInstance().getResourcePath(":/systems/unix/es_find_rules.xml", false); #endif - if (filePath == "" && paths.empty()) { + if (filePath.empty() && paths.empty()) { LOG(LogWarning) << "No find rules configuration file found"; return; } - if (filePath != "") + if (!filePath.empty()) paths.emplace_back(filePath); for (auto& path : paths) { @@ -84,7 +89,6 @@ void FindRules::loadFindRules() #else const pugi::xml_parse_result& res {doc.load_file(path.c_str())}; #endif - if (!res) { LOG(LogError) << "Couldn't parse es_find_rules.xml: " << res.description(); continue; @@ -126,6 +130,9 @@ void FindRules::loadFindRules() #if defined(_WIN64) if (ruleType != "winregistrypath" && ruleType != "winregistryvalue" && ruleType != "systempath" && ruleType != "staticpath") { +#elif defined(__ANDROID__) + if (ruleType != "androidpackage" && ruleType != "systempath" && + ruleType != "staticpath") { #else if (ruleType != "systempath" && ruleType != "staticpath") { #endif @@ -145,6 +152,9 @@ void FindRules::loadFindRules() emulatorRules.winRegistryPaths.emplace_back(entryValue); else if (ruleType == "winregistryvalue") emulatorRules.winRegistryValues.emplace_back(entryValue); +#elif defined(__ANDROID__) + else if (ruleType == "androidpackage") + emulatorRules.androidPackages.emplace_back(entryValue); #endif } } @@ -154,6 +164,8 @@ void FindRules::loadFindRules() #if defined(_WIN64) emulatorRules.winRegistryPaths.clear(); emulatorRules.winRegistryValues.clear(); +#elif defined(__ANDROID__) + emulatorRules.androidPackages.clear(); #endif } @@ -838,9 +850,8 @@ bool SystemData::loadConfig() void SystemData::loadSortingConfig() { const std::string sortSetting {Settings::getInstance()->getString("SystemsSorting")}; - const std::string customFilePath {Utils::FileSystem::getHomePath() + - "/.emulationstation/custom_systems" + - "/es_systems_sorting.xml"}; + const std::string customFilePath {Utils::FileSystem::getAppDataDirectory() + + "/custom_systems/es_systems_sorting.xml"}; const bool customFileExists {Utils::FileSystem::exists(customFilePath)}; std::string path; @@ -875,7 +886,7 @@ void SystemData::loadSortingConfig() path = customFilePath; } - if (path == "") { + if (path.empty()) { LOG(LogDebug) << "No systems sorting file loaded"; return; } @@ -947,8 +958,8 @@ std::vector SystemData::getConfigPath() { std::vector paths; - const std::string& customSystemsDirectory {Utils::FileSystem::getHomePath() + - "/.emulationstation/custom_systems"}; + const std::string customSystemsDirectory {Utils::FileSystem::getAppDataDirectory() + + "/custom_systems"}; if (!Utils::FileSystem::exists(customSystemsDirectory)) { LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory << "\"..."; @@ -965,7 +976,11 @@ std::vector SystemData::getConfigPath() paths.emplace_back(path); } -#if defined(_WIN64) +#if defined(__ANDROID__) + path = ResourceManager::getInstance().getResourcePath(":/systems/android/es_systems.xml", true); +#elif defined(__linux__) + path = ResourceManager::getInstance().getResourcePath(":/systems/linux/es_systems.xml", true); +#elif defined(_WIN64) path = ResourceManager::getInstance().getResourcePath(":/systems/windows/es_systems.xml", true); #elif defined(__APPLE__) path = ResourceManager::getInstance().getResourcePath(":/systems/macos/es_systems.xml", true); @@ -1107,6 +1122,31 @@ bool SystemData::createSystemDirectories() return (std::isspace(character) || character == ','); }) != platform.cend()}; + if (name.empty()) { + LOG(LogError) + << "A system in the es_systems.xml file has no name defined, skipping entry"; + continue; + } + else if (fullname.empty() || path.empty() || extensions.empty() || commands.empty()) { + LOG(LogError) << "System \"" << name + << "\" is missing the fullname, path, " + "extension, or command tag, skipping entry"; + continue; + } + + if (commands.size() == 1 && + Utils::String::toLower(commands.front()).find("placeholder") != std::string::npos) { + if (Settings::getInstance()->getBool("CreatePlaceholderSystemDirectories")) { + LOG(LogInfo) << "System \"" << name + << "\" is a placeholder but creating directory anyway as " + "CreatePlaceholderSystemDirectories is set to true"; + } + else { + LOG(LogInfo) << "System \"" << name << "\" is a placeholder, skipping entry"; + continue; + } + } + themeFolder = system.child("theme").text().as_string(name.c_str()); // Check that the %ROMPATH% variable is actually used for the path element. @@ -1188,7 +1228,10 @@ bool SystemData::createSystemDirectories() } systemInfoFile << "Platform" << (multiplePlatforms ? "s" : "") << " (for scraping):" << std::endl; - systemInfoFile << platform << std::endl << std::endl; + if (platform.empty()) + systemInfoFile << "None defined" << std::endl << std::endl; + else + systemInfoFile << platform << std::endl << std::endl; systemInfoFile << "Theme folder:" << std::endl; systemInfoFile << themeFolder << std::endl; systemInfoFile.close(); @@ -1296,8 +1339,8 @@ SystemData* SystemData::getPrev() const std::string SystemData::getGamelistPath(bool forWrite) const { std::string filePath {mRootFolder->getPath() + "/gamelist.xml"}; - const std::string gamelistPath {Utils::FileSystem::getHomePath() + - "/.emulationstation/gamelists/" + mName}; + const std::string gamelistPath {Utils::FileSystem::getAppDataDirectory() + "/gamelists/" + + mName}; if (Utils::FileSystem::exists(filePath)) { if (Settings::getInstance()->getBool("LegacyGamelistFileLocation")) { @@ -1307,8 +1350,7 @@ std::string SystemData::getGamelistPath(bool forWrite) const #if defined(_WIN64) LOG(LogWarning) << "Found a gamelist.xml file in \"" << Utils::String::replace(mRootFolder->getPath(), "/", "\\") - << "\\\" which will not get loaded, move it to \"" - << Utils::String::replace(gamelistPath, "/", "\\") + << "\\\" which will not get loaded, move it to \"" << gamelistPath << "\\\" or otherwise delete it"; #else LOG(LogWarning) << "Found a gamelist.xml file in \"" << mRootFolder->getPath() diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index c72889b56..53b636213 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemData.h // // Provides data structures for the game systems and populates and indexes them based @@ -44,6 +44,8 @@ private: #if defined(_WIN64) std::vector winRegistryPaths; std::vector winRegistryValues; +#elif defined(__ANDROID__) + std::vector androidPackages; #endif std::vector systemPaths; std::vector staticPaths; diff --git a/es-app/src/UIModeController.cpp b/es-app/src/UIModeController.cpp index 38af8c110..7ce20065c 100644 --- a/es-app/src/UIModeController.cpp +++ b/es-app/src/UIModeController.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // UIModeController.cpp // // Handling of application user interface modes (full, kiosk and kid). @@ -127,13 +127,13 @@ std::string UIModeController::getFormattedPassKeyStr() std::string symbolX; std::string symbolY; - if (controllerType == "snes") { + if (Settings::getInstance()->getBool("InputSwapButtons") || controllerType == "snes") { symbolA = "B"; symbolB = "A"; symbolX = "Y"; symbolY = "X"; } - else if (controllerType == "ps4" || controllerType == "ps5") { + else if (controllerType == "ps123" || controllerType == "ps4" || controllerType == "ps5") { #if defined(_MSC_VER) // MSVC compiler. // These symbols are far from perfect but you can at least understand what // they are supposed to depict. diff --git a/es-app/src/UIModeController.h b/es-app/src/UIModeController.h index ccb7e78db..22d22133e 100644 --- a/es-app/src/UIModeController.h +++ b/es-app/src/UIModeController.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // UIModeController.h // // Handling of application user interface modes (full, kiosk and kid). diff --git a/es-app/src/VolumeControl.cpp b/es-app/src/VolumeControl.cpp index e3fd447a2..3bf54b914 100644 --- a/es-app/src/VolumeControl.cpp +++ b/es-app/src/VolumeControl.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VolumeControl.cpp // // Controls system audio volume. @@ -15,14 +15,14 @@ #include #endif -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) std::string VolumeControl::mixerName = "Master"; std::string VolumeControl::mixerCard = "default"; #endif VolumeControl::VolumeControl() // clang-format off -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) : mixerIndex {0} , mixerHandle {nullptr} , mixerElem {nullptr} @@ -39,7 +39,7 @@ VolumeControl::VolumeControl() VolumeControl::~VolumeControl() { deinit(); -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) snd_config_update_free_global(); #endif } @@ -48,7 +48,7 @@ void VolumeControl::init() { // Initialize audio mixer interface. -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) // Try to open mixer device. if (mixerHandle == nullptr) { snd_mixer_selem_id_alloca(&mixerSelemId); @@ -139,7 +139,7 @@ void VolumeControl::deinit() { // Deinitialize audio mixer interface. -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) if (mixerHandle != nullptr) { snd_mixer_detach(mixerHandle, mixerCard.c_str()); snd_mixer_free(mixerHandle); @@ -160,7 +160,7 @@ int VolumeControl::getVolume() const { int volume = 0; -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) if (mixerElem != nullptr) { // Get volume range. long minVolume; @@ -204,7 +204,7 @@ void VolumeControl::setVolume(int volume) { volume = glm::clamp(volume, 0, 100); -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) if (mixerElem != nullptr) { // Get volume range. long minVolume; diff --git a/es-app/src/VolumeControl.h b/es-app/src/VolumeControl.h index 8a002e569..e0526c34b 100644 --- a/es-app/src/VolumeControl.h +++ b/es-app/src/VolumeControl.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VolumeControl.h // // Controls system audio volume. @@ -11,7 +11,7 @@ #include -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) #include #include #include @@ -33,7 +33,7 @@ public: int getVolume() const; void setVolume(int volume); -#if defined(__linux__) +#if defined(__linux__) && !defined(__ANDROID__) static std::string mixerName; static std::string mixerCard; int mixerIndex; diff --git a/es-app/src/guis/GuiAlternativeEmulators.cpp b/es-app/src/guis/GuiAlternativeEmulators.cpp index ff504845c..264fd8622 100644 --- a/es-app/src/guis/GuiAlternativeEmulators.cpp +++ b/es-app/src/guis/GuiAlternativeEmulators.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiAlternativeEmulators.cpp // // User interface to select between alternative emulators per system diff --git a/es-app/src/guis/GuiAlternativeEmulators.h b/es-app/src/guis/GuiAlternativeEmulators.h index 9ac0bed92..c4b5c68f0 100644 --- a/es-app/src/guis/GuiAlternativeEmulators.h +++ b/es-app/src/guis/GuiAlternativeEmulators.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiAlternativeEmulators.h // // User interface to select between alternative emulators per system diff --git a/es-app/src/guis/GuiApplicationUpdater.cpp b/es-app/src/guis/GuiApplicationUpdater.cpp index cad6fca54..39a47e489 100644 --- a/es-app/src/guis/GuiApplicationUpdater.cpp +++ b/es-app/src/guis/GuiApplicationUpdater.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiApplicationUpdater.cpp // // Installs application updates. @@ -9,7 +9,7 @@ #include "guis/GuiApplicationUpdater.h" -#include "EmulationStation.h" +#include "ApplicationVersion.h" #include "guis/GuiTextEditKeyboardPopup.h" #include "guis/GuiTextEditPopup.h" #include "utils/PlatformUtil.h" diff --git a/es-app/src/guis/GuiApplicationUpdater.h b/es-app/src/guis/GuiApplicationUpdater.h index ec6dcb82b..f410052b5 100644 --- a/es-app/src/guis/GuiApplicationUpdater.h +++ b/es-app/src/guis/GuiApplicationUpdater.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiApplicationUpdater.h // // Installs application updates. diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.cpp b/es-app/src/guis/GuiCollectionSystemsOptions.cpp index 675ebe266..9c356c97a 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.cpp +++ b/es-app/src/guis/GuiCollectionSystemsOptions.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiCollectionSystemsOptions.cpp // // User interface for the game collection settings. diff --git a/es-app/src/guis/GuiCollectionSystemsOptions.h b/es-app/src/guis/GuiCollectionSystemsOptions.h index 25317ddbf..2cf478989 100644 --- a/es-app/src/guis/GuiCollectionSystemsOptions.h +++ b/es-app/src/guis/GuiCollectionSystemsOptions.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiCollectionSystemsOptions.h // // User interface for the game collection settings. diff --git a/es-app/src/guis/GuiGamelistFilter.cpp b/es-app/src/guis/GuiGamelistFilter.cpp index fad712ec7..3964c36a0 100644 --- a/es-app/src/guis/GuiGamelistFilter.cpp +++ b/es-app/src/guis/GuiGamelistFilter.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiGamelistFilter.cpp // // User interface for the gamelist filters. diff --git a/es-app/src/guis/GuiGamelistFilter.h b/es-app/src/guis/GuiGamelistFilter.h index 4ba3f92a2..5ed1a1bb9 100644 --- a/es-app/src/guis/GuiGamelistFilter.h +++ b/es-app/src/guis/GuiGamelistFilter.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiGamelistFilter.h // // User interface for the gamelist filters. diff --git a/es-app/src/guis/GuiGamelistOptions.cpp b/es-app/src/guis/GuiGamelistOptions.cpp index e901779b4..e7c1e6a1e 100644 --- a/es-app/src/guis/GuiGamelistOptions.cpp +++ b/es-app/src/guis/GuiGamelistOptions.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiGamelistOptions.cpp // // Gamelist options menu for the 'Jump to...' quick selector, diff --git a/es-app/src/guis/GuiGamelistOptions.h b/es-app/src/guis/GuiGamelistOptions.h index a8292d91f..6cc01f9ba 100644 --- a/es-app/src/guis/GuiGamelistOptions.h +++ b/es-app/src/guis/GuiGamelistOptions.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiGamelistOptions.h // // Gamelist options menu for the 'Jump to...' quick selector, diff --git a/es-app/src/guis/GuiLaunchScreen.cpp b/es-app/src/guis/GuiLaunchScreen.cpp index 3c165b539..d9fc11f68 100644 --- a/es-app/src/guis/GuiLaunchScreen.cpp +++ b/es-app/src/guis/GuiLaunchScreen.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiLaunchScreen.cpp // // Screen shown when launching a game. diff --git a/es-app/src/guis/GuiLaunchScreen.h b/es-app/src/guis/GuiLaunchScreen.h index af24f4329..7f6590a50 100644 --- a/es-app/src/guis/GuiLaunchScreen.h +++ b/es-app/src/guis/GuiLaunchScreen.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiLaunchScreen.h // // Screen shown when launching a game. diff --git a/es-app/src/guis/GuiMediaViewerOptions.cpp b/es-app/src/guis/GuiMediaViewerOptions.cpp index 299471ed5..c6ba51c5b 100644 --- a/es-app/src/guis/GuiMediaViewerOptions.cpp +++ b/es-app/src/guis/GuiMediaViewerOptions.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMediaViewerOptions.cpp // // User interface for the media viewer options. diff --git a/es-app/src/guis/GuiMediaViewerOptions.h b/es-app/src/guis/GuiMediaViewerOptions.h index 686c6ea12..dda7c362d 100644 --- a/es-app/src/guis/GuiMediaViewerOptions.h +++ b/es-app/src/guis/GuiMediaViewerOptions.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMediaViewerOptions.h // // User interface for the media viewer options. diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index d73c94e6b..65eb1da6b 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMenu.cpp // // Main menu. @@ -14,8 +14,8 @@ #include #endif +#include "ApplicationVersion.h" #include "CollectionSystemsManager.h" -#include "EmulationStation.h" #include "FileFilterIndex.h" #include "FileSorts.h" #include "Scripting.h" @@ -38,6 +38,10 @@ #include "guis/GuiThemeDownloader.h" #include "utils/PlatformUtil.h" +#if defined(__ANDROID__) +#include "InputOverlay.h" +#endif + #include #include @@ -164,12 +168,12 @@ void GuiMenu::openUIOptions() Scripting::fireEvent("theme-changed", theme->getSelected(), Settings::getInstance()->getString("Theme")); // Handle the situation where the previously selected theme has been deleted - // using the theme downloader. In this case attempt to fall back to slate-es-de + // using the theme downloader. In this case attempt to fall back to linear-es-de // and if this theme doesn't exist then select the first available one. auto themes = ThemeData::getThemes(); if (themes.find(theme->getSelected()) == themes.end()) { - if (themes.find("slate-es-de") != themes.end()) - Settings::getInstance()->setString("Theme", "slate-es-de"); + if (themes.find("linear-es-de") != themes.end()) + Settings::getInstance()->setString("Theme", "linear-es-de"); else Settings::getInstance()->setString("Theme", themes.begin()->first); } @@ -288,6 +292,47 @@ void GuiMenu::openUIOptions() themeColorSchemesFunc(Settings::getInstance()->getString("Theme"), Settings::getInstance()->getString("ThemeColorScheme")); + // Theme font sizes. + auto themeFontSize = std::make_shared>( + getHelpStyle(), "THEME FONT SIZE", false); + s->addWithLabel("THEME FONT SIZE", themeFontSize); + s->addSaveFunc([themeFontSize, s] { + if (themeFontSize->getSelected() != Settings::getInstance()->getString("ThemeFontSize")) { + Settings::getInstance()->setString("ThemeFontSize", themeFontSize->getSelected()); + s->setNeedsSaving(); + s->setNeedsReloading(); + s->setInvalidateCachedBackground(); + } + }); + + auto themeFontSizeFunc = [=](const std::string& selectedTheme, + const std::string& selectedFontSize) { + std::map::const_iterator + currentSet {themes.find(selectedTheme)}; + if (currentSet == themes.cend()) + return; + // We need to recreate the OptionListComponent entries. + themeFontSize->clearEntries(); + if (currentSet->second.capabilities.fontSizes.size() > 0) { + for (auto& fontSize : currentSet->second.capabilities.fontSizes) + themeFontSize->add(ThemeData::getFontSizeLabel(fontSize), fontSize, + fontSize == selectedFontSize); + if (themeFontSize->getSelectedObjects().size() == 0) + themeFontSize->selectEntry(0); + } + else { + themeFontSize->add("None defined", "none", true); + themeFontSize->setEnabled(false); + themeFontSize->setOpacity(DISABLED_OPACITY); + themeFontSize->getParent() + ->getChild(themeFontSize->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + }; + + themeFontSizeFunc(Settings::getInstance()->getString("Theme"), + Settings::getInstance()->getString("ThemeFontSize")); + // Theme aspect ratios. auto themeAspectRatio = std::make_shared>( getHelpStyle(), "THEME ASPECT RATIO", false); @@ -845,6 +890,12 @@ void GuiMenu::openUIOptions() Settings::getInstance()->setBool("VirtualKeyboard", virtualKeyboard->getState()); s->setNeedsSaving(); s->setInvalidateCachedBackground(); +#if defined(__ANDROID__) + if (Settings::getInstance()->getBool("VirtualKeyboard")) + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); + else + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "1"); +#endif } }); @@ -891,6 +942,7 @@ void GuiMenu::openUIOptions() if (!firstRun) { themeVariantsFunc(themeName, themeVariant->getSelected()); themeColorSchemesFunc(themeName, themeColorScheme->getSelected()); + themeFontSizeFunc(themeName, themeFontSize->getSelected()); themeAspectRatiosFunc(themeName, themeAspectRatio->getSelected()); themeTransitionsFunc(themeName, themeTransitions->getSelected()); } @@ -927,6 +979,20 @@ void GuiMenu::openUIOptions() ->getChild(themeColorScheme->getChildIndex() - 1) ->setOpacity(DISABLED_OPACITY); } + if (selectedTheme->second.capabilities.fontSizes.size() > 0) { + themeFontSize->setEnabled(true); + themeFontSize->setOpacity(1.0f); + themeFontSize->getParent() + ->getChild(themeFontSize->getChildIndex() - 1) + ->setOpacity(1.0f); + } + else { + themeFontSize->setEnabled(false); + themeFontSize->setOpacity(DISABLED_OPACITY); + themeFontSize->getParent() + ->getChild(themeFontSize->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } if (selectedTheme->second.capabilities.aspectRatios.size() > 0) { themeAspectRatio->setEnabled(true); themeAspectRatio->setOpacity(1.0f); @@ -954,9 +1020,9 @@ void GuiMenu::openSoundOptions() { auto s = new GuiSettings("SOUND SETTINGS"); -// TODO: Hide the volume slider on macOS and BSD Unix until the volume control logic has been -// implemented for these operating systems. -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +// TODO: Implement system volume support for macOS and Android. +#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(__FreeBSD__) && \ + !defined(__OpenBSD__) && !defined(__NetBSD__) // System volume. // The reason to create the VolumeControl object every time instead of making it a singleton // is that this is the easiest way to detect new default audio devices or changes to the @@ -1090,6 +1156,166 @@ void GuiMenu::openInputDeviceOptions() } }); +#if defined(__ANDROID__) + // Touch overlay size. + auto touchOverlaySize = std::make_shared>( + getHelpStyle(), "TOUCH OVERLAY SIZE", false); + std::string selectedOverlaySize {Settings::getInstance()->getString("InputTouchOverlaySize")}; + touchOverlaySize->add("MEDIUM", "medium", selectedOverlaySize == "medium"); + touchOverlaySize->add("LARGE", "large", selectedOverlaySize == "large"); + touchOverlaySize->add("SMALL", "small", selectedOverlaySize == "small"); + touchOverlaySize->add("EXTRA SMALL", "x-small", selectedOverlaySize == "x-small"); + // If there are no objects returned, then there must be a manually modified entry in the + // configuration file. Simply set the overlay size to "medium" in this case. + if (touchOverlaySize->getSelectedObjects().size() == 0) + touchOverlaySize->selectEntry(0); + s->addWithLabel("TOUCH OVERLAY SIZE", touchOverlaySize); + s->addSaveFunc([touchOverlaySize, s] { + if (touchOverlaySize->getSelected() != + Settings::getInstance()->getString("InputTouchOverlaySize")) { + Settings::getInstance()->setString("InputTouchOverlaySize", + touchOverlaySize->getSelected()); + s->setNeedsSaving(); + InputOverlay::getInstance().createButtons(); + } + }); + + // Touch overlay opacity. + auto touchOverlayOpacity = std::make_shared>( + getHelpStyle(), "TOUCH OVERLAY OPACITY", false); + std::string selectedOverlayOpacity { + Settings::getInstance()->getString("InputTouchOverlayOpacity")}; + touchOverlayOpacity->add("NORMAL", "normal", selectedOverlayOpacity == "normal"); + touchOverlayOpacity->add("LOW", "low", selectedOverlayOpacity == "low"); + touchOverlayOpacity->add("VERY LOW", "verylow", selectedOverlayOpacity == "verylow"); + // If there are no objects returned, then there must be a manually modified entry in the + // configuration file. Simply set the overlay opacity to "normal" in this case. + if (touchOverlayOpacity->getSelectedObjects().size() == 0) + touchOverlayOpacity->selectEntry(0); + s->addWithLabel("TOUCH OVERLAY OPACITY", touchOverlayOpacity); + s->addSaveFunc([touchOverlayOpacity, s] { + if (touchOverlayOpacity->getSelected() != + Settings::getInstance()->getString("InputTouchOverlayOpacity")) { + Settings::getInstance()->setString("InputTouchOverlayOpacity", + touchOverlayOpacity->getSelected()); + s->setNeedsSaving(); + InputOverlay::getInstance().createButtons(); + } + }); + + // Touch overlay fade-out timer. + auto touchOverlayFadeTime = std::make_shared(0.0f, 20.0f, 1.0f, "s"); + touchOverlayFadeTime->setValue( + static_cast(Settings::getInstance()->getInt("InputTouchOverlayFadeTime"))); + s->addWithLabel("TOUCH OVERLAY FADE-OUT TIME", touchOverlayFadeTime); + s->addSaveFunc([touchOverlayFadeTime, s] { + if (touchOverlayFadeTime->getValue() != + static_cast(Settings::getInstance()->getInt("InputTouchOverlayFadeTime"))) { + Settings::getInstance()->setInt("InputTouchOverlayFadeTime", + static_cast(touchOverlayFadeTime->getValue())); + InputOverlay::getInstance().resetFadeTimer(); + s->setNeedsSaving(); + } + }); + + // Whether to enable the touch overlay. + auto inputTouchOverlay = std::make_shared(); + inputTouchOverlay->setState(Settings::getInstance()->getBool("InputTouchOverlay")); + s->addWithLabel("ENABLE TOUCH OVERLAY", inputTouchOverlay); + s->addSaveFunc([inputTouchOverlay, s] { + if (Settings::getInstance()->getBool("InputTouchOverlay") != + inputTouchOverlay->getState()) { + Settings::getInstance()->setBool("InputTouchOverlay", inputTouchOverlay->getState()); + if (Settings::getInstance()->getBool("InputTouchOverlay")) + InputOverlay::getInstance().createButtons(); + else + InputOverlay::getInstance().clearButtons(); + s->setNeedsSaving(); + } + }); + + if (!Settings::getInstance()->getBool("InputTouchOverlay")) { + touchOverlaySize->setEnabled(false); + touchOverlaySize->setOpacity(DISABLED_OPACITY); + touchOverlaySize->getParent() + ->getChild(touchOverlaySize->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + + touchOverlayOpacity->setEnabled(false); + touchOverlayOpacity->setOpacity(DISABLED_OPACITY); + touchOverlayOpacity->getParent() + ->getChild(touchOverlayOpacity->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + + touchOverlayFadeTime->setEnabled(false); + touchOverlayFadeTime->setOpacity(DISABLED_OPACITY); + touchOverlayFadeTime->getParent() + ->getChild(touchOverlayFadeTime->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + + auto inputTouchOverlayCallback = [this, inputTouchOverlay, touchOverlaySize, + touchOverlayOpacity, touchOverlayFadeTime]() { + if (!inputTouchOverlay->getState()) { + const std::string message { + "DON'T DISABLE THE TOUCH OVERLAY UNLESS YOU ARE USING A CONTROLLER OR YOU WILL " + "LOCK YOURSELF OUT OF THE APP. IF THIS HAPPENS YOU WILL NEED TO TEMPORARILY " + "PLUG IN A CONTROLLER OR A KEYBOARD TO ENABLE THIS SETTING AGAIN, OR YOU " + "COULD CLEAR THE ES-DE STORAGE IN THE ANDROID APP SETTINGS TO FORCE THE " + "CONFIGURATOR TO RUN ON NEXT STARTUP"}; + + Window* window {mWindow}; + window->pushGui( + new GuiMsgBox(getHelpStyle(), message, "OK", nullptr, "", nullptr, "", nullptr, + nullptr, true, true, + (mRenderer->getIsVerticalOrientation() ? + 0.84f : + 0.54f * (1.778f / mRenderer->getScreenAspectRatio())))); + } + + if (touchOverlaySize->getEnabled()) { + touchOverlaySize->setEnabled(false); + touchOverlaySize->setOpacity(DISABLED_OPACITY); + touchOverlaySize->getParent() + ->getChild(touchOverlaySize->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + + touchOverlayOpacity->setEnabled(false); + touchOverlayOpacity->setOpacity(DISABLED_OPACITY); + touchOverlayOpacity->getParent() + ->getChild(touchOverlayOpacity->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + + touchOverlayFadeTime->setEnabled(false); + touchOverlayFadeTime->setOpacity(DISABLED_OPACITY); + touchOverlayFadeTime->getParent() + ->getChild(touchOverlayFadeTime->getChildIndex() - 1) + ->setOpacity(DISABLED_OPACITY); + } + else { + touchOverlaySize->setEnabled(true); + touchOverlaySize->setOpacity(1.0f); + touchOverlaySize->getParent() + ->getChild(touchOverlaySize->getChildIndex() - 1) + ->setOpacity(1.0f); + + touchOverlayOpacity->setEnabled(true); + touchOverlayOpacity->setOpacity(1.0f); + touchOverlayOpacity->getParent() + ->getChild(touchOverlayOpacity->getChildIndex() - 1) + ->setOpacity(1.0f); + + touchOverlayFadeTime->setEnabled(true); + touchOverlayFadeTime->setOpacity(1.0f); + touchOverlayFadeTime->getParent() + ->getChild(touchOverlayFadeTime->getChildIndex() - 1) + ->setOpacity(1.0f); + } + }; + + inputTouchOverlay->setCallback(inputTouchOverlayCallback); +#endif + // Whether to only accept input from the first controller. auto inputOnlyFirstController = std::make_shared(); inputOnlyFirstController->setState( @@ -1104,6 +1330,17 @@ void GuiMenu::openInputDeviceOptions() } }); + // Whether to swap the A/B and X/Y buttons. + auto inputSwapButtons = std::make_shared(); + inputSwapButtons->setState(Settings::getInstance()->getBool("InputSwapButtons")); + s->addWithLabel("SWAP THE A/B AND X/Y BUTTONS", inputSwapButtons); + s->addSaveFunc([inputSwapButtons, s] { + if (Settings::getInstance()->getBool("InputSwapButtons") != inputSwapButtons->getState()) { + Settings::getInstance()->setBool("InputSwapButtons", inputSwapButtons->getState()); + s->setNeedsSaving(); + } + }); + // Whether to ignore keyboard input (except the quit shortcut). auto inputIgnoreKeyboard = std::make_shared(); inputIgnoreKeyboard->setState(Settings::getInstance()->getBool("InputIgnoreKeyboard")); @@ -1185,7 +1422,8 @@ void GuiMenu::openOtherOptions() rowMediaDir.addElement(bracketMediaDirectory, false); std::string titleMediaDir {"ENTER GAME MEDIA DIRECTORY"}; std::string mediaDirectoryStaticText {"Default directory:"}; - std::string defaultDirectoryText {"~/.emulationstation/downloaded_media/"}; + std::string defaultDirectoryText {Utils::FileSystem::getAppDataDirectory() + + "/downloaded_media"}; std::string initValueMediaDir {Settings::getInstance()->getString("MediaDirectory")}; bool multiLineMediaDir {false}; auto updateValMediaDir = [this](const std::string& newVal) { @@ -1417,6 +1655,7 @@ void GuiMenu::openOtherOptions() }); #endif +#if !defined(__ANDROID__) // Run ES in the background when a game has been launched. auto runInBackground = std::make_shared(); runInBackground->setState(Settings::getInstance()->getBool("RunInBackground")); @@ -1427,6 +1666,7 @@ void GuiMenu::openOtherOptions() s->setNeedsSaving(); } }); +#endif #if defined(VIDEO_HW_DECODING) // Whether to enable hardware decoding for the FFmpeg video player. @@ -1538,7 +1778,7 @@ void GuiMenu::openOtherOptions() } }); -#if defined(__unix__) +#if defined(__unix__) && !defined(__ANDROID__) // Whether to disable desktop composition. auto disableComposition = std::make_shared(); disableComposition->setState(Settings::getInstance()->getBool("DisableComposition")); @@ -1612,7 +1852,7 @@ void GuiMenu::openOtherOptions() // macOS requires root privileges to reboot and power off so it doesn't make much // sense to enable this setting and menu entry for that operating system. -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__ANDROID__) // Whether to show the quit menu with the options to reboot and shutdown the computer. auto showQuitMenu = std::make_shared(); showQuitMenu->setState(Settings::getInstance()->getBool("ShowQuitMenu")); @@ -1661,12 +1901,23 @@ void GuiMenu::openUtilities() ComponentListRow row; +#if defined(ANDROID_LITE_RELEASE) + auto orphanedDataCleanup = + std::make_shared("ORPHANED DATA CLEANUP (FULL VERSION ONLY)", + Font::get(FONT_SIZE_MEDIUM), mMenuColorPrimary); + orphanedDataCleanup->setOpacity(DISABLED_OPACITY); + row.addElement(orphanedDataCleanup, true); + auto orphanedDataCleanupArrow = mMenu.makeArrow(); + orphanedDataCleanupArrow->setOpacity(DISABLED_OPACITY); + row.addElement(orphanedDataCleanupArrow, false); +#else row.addElement(std::make_shared("ORPHANED DATA CLEANUP", Font::get(FONT_SIZE_MEDIUM), mMenuColorPrimary), true); row.addElement(mMenu.makeArrow(), false); row.makeAcceptInputHandler(std::bind( [this] { mWindow->pushGui(new GuiOrphanedDataCleanup([&]() { close(true); })); })); +#endif s->addRow(row); row.elements.clear(); @@ -1764,7 +2015,11 @@ void GuiMenu::openUtilities() void GuiMenu::openQuitMenu() { +#if defined(__APPLE__) || defined(__ANDROID__) + if (true) { +#else if (!Settings::getInstance()->getBool("ShowQuitMenu")) { +#endif mWindow->pushGui(new GuiMsgBox( this->getHelpStyle(), "REALLY QUIT?", "YES", [this] { @@ -1790,8 +2045,8 @@ void GuiMenu::openQuitMenu() }, "NO", nullptr)); }); - auto quitText = std::make_shared( - "QUIT RETRODECK", Font::get(FONT_SIZE_MEDIUM), mMenuColorPrimary); + auto quitText = std::make_shared("QUIT RETRODECK", Font::get(FONT_SIZE_MEDIUM), + mMenuColorPrimary); quitText->setSelectable(true); row.addElement(quitText, true); s->addRow(row); @@ -1840,11 +2095,17 @@ void GuiMenu::addVersionInfo() mVersion.setFont(Font::get(FONT_SIZE_SMALL)); mVersion.setColor(mMenuColorTertiary); +#if defined(ANDROID_LITE_RELEASE) + const std::string applicationName {"ES-DE LITE"}; +#else + const std::string applicationName {"ES-DE"}; +#endif + #if defined(IS_PRERELEASE) - mVersion.setText("EMULATIONSTATION-DE V" + Utils::String::toUpper(PROGRAM_VERSION_STRING) + + mVersion.setText(applicationName + " V" + Utils::String::toUpper(PROGRAM_VERSION_STRING) + " (Built " + __DATE__ + ")"); #else - mVersion.setText("EMULATIONSTATION-DE V" + Utils::String::toUpper(PROGRAM_VERSION_STRING)); + mVersion.setText(applicationName + " V" + Utils::String::toUpper(PROGRAM_VERSION_STRING)); #endif mVersion.setHorizontalAlignment(ALIGN_CENTER); diff --git a/es-app/src/guis/GuiMenu.h b/es-app/src/guis/GuiMenu.h index e41cd9801..dd9b42d8d 100644 --- a/es-app/src/guis/GuiMenu.h +++ b/es-app/src/guis/GuiMenu.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMenu.h // // Main menu. diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index b302cd9b0..fffbed815 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMetaDataEd.cpp // // Game metadata edit user interface. diff --git a/es-app/src/guis/GuiMetaDataEd.h b/es-app/src/guis/GuiMetaDataEd.h index ca401ba46..f90410f08 100644 --- a/es-app/src/guis/GuiMetaDataEd.h +++ b/es-app/src/guis/GuiMetaDataEd.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMetaDataEd.h // // Game metadata edit user interface. diff --git a/es-app/src/guis/GuiOfflineGenerator.cpp b/es-app/src/guis/GuiOfflineGenerator.cpp index f90cf8f81..98cde683d 100644 --- a/es-app/src/guis/GuiOfflineGenerator.cpp +++ b/es-app/src/guis/GuiOfflineGenerator.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiOfflineGenerator.cpp // // User interface for the miximage offline generator. diff --git a/es-app/src/guis/GuiOfflineGenerator.h b/es-app/src/guis/GuiOfflineGenerator.h index ff65e2dfc..f1dbd4174 100644 --- a/es-app/src/guis/GuiOfflineGenerator.h +++ b/es-app/src/guis/GuiOfflineGenerator.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiOfflineGenerator.h // // User interface for the miximage offline generator. diff --git a/es-app/src/guis/GuiOrphanedDataCleanup.cpp b/es-app/src/guis/GuiOrphanedDataCleanup.cpp index 7279826f9..5281e2ad3 100644 --- a/es-app/src/guis/GuiOrphanedDataCleanup.cpp +++ b/es-app/src/guis/GuiOrphanedDataCleanup.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE Frontend // GuiOrphanedDataCleanup.cpp // // Removes orphaned game media, gamelist.xml entries and custom collections entries. @@ -39,7 +39,7 @@ GuiOrphanedDataCleanup::GuiOrphanedDataCleanup(std::function reloadCallb addChild(&mBackground); addChild(&mGrid); -#if defined(_WIN64) || defined(__APPLE__) +#if defined(_WIN64) || defined(__APPLE__) || defined(__ANDROID__) // Although macOS may have filesystem case-sensitivity enabled it's rare and in worst case // this will just leave some extra media files on the filesystem. mCaseSensitiveFilesystem = false; diff --git a/es-app/src/guis/GuiOrphanedDataCleanup.h b/es-app/src/guis/GuiOrphanedDataCleanup.h index 6523da643..0170868b5 100644 --- a/es-app/src/guis/GuiOrphanedDataCleanup.h +++ b/es-app/src/guis/GuiOrphanedDataCleanup.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE Frontend // GuiOrphanedDataCleanup.h // // Removes orphaned game media, gamelist.xml entries and custom collections entries. diff --git a/es-app/src/guis/GuiScraperMenu.cpp b/es-app/src/guis/GuiScraperMenu.cpp index 2e5dc4036..5d3974bf4 100644 --- a/es-app/src/guis/GuiScraperMenu.cpp +++ b/es-app/src/guis/GuiScraperMenu.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperMenu.cpp // // Game media scraper, including settings as well as the scraping start button. @@ -950,20 +950,6 @@ void GuiScraperMenu::openOtherOptions() } }); - // Halt scraping on invalid media files. - auto scraperHaltOnInvalidMedia = std::make_shared(); - scraperHaltOnInvalidMedia->setState( - Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia")); - s->addWithLabel("HALT ON INVALID MEDIA FILES", scraperHaltOnInvalidMedia); - s->addSaveFunc([scraperHaltOnInvalidMedia, s] { - if (scraperHaltOnInvalidMedia->getState() != - Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia")) { - Settings::getInstance()->setBool("ScraperHaltOnInvalidMedia", - scraperHaltOnInvalidMedia->getState()); - s->setNeedsSaving(); - } - }); - // Search using file hashes for non-interactive mode. auto scraperSearchFileHash = std::make_shared(); scraperSearchFileHash->setState(Settings::getInstance()->getBool("ScraperSearchFileHash")); diff --git a/es-app/src/guis/GuiScraperMenu.h b/es-app/src/guis/GuiScraperMenu.h index 096adffaf..4b2f5d717 100644 --- a/es-app/src/guis/GuiScraperMenu.h +++ b/es-app/src/guis/GuiScraperMenu.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperMenu.h // // Game media scraper, including settings as well as the scraping start button. diff --git a/es-app/src/guis/GuiScraperMulti.cpp b/es-app/src/guis/GuiScraperMulti.cpp index db6aa0aa6..72a42e6e7 100644 --- a/es-app/src/guis/GuiScraperMulti.cpp +++ b/es-app/src/guis/GuiScraperMulti.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperMulti.cpp // // Multiple game scraping user interface. diff --git a/es-app/src/guis/GuiScraperMulti.h b/es-app/src/guis/GuiScraperMulti.h index 1cb8ac4ad..ae0eadf14 100644 --- a/es-app/src/guis/GuiScraperMulti.h +++ b/es-app/src/guis/GuiScraperMulti.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperMulti.h // // Multiple game scraping user interface. diff --git a/es-app/src/guis/GuiScraperSearch.cpp b/es-app/src/guis/GuiScraperSearch.cpp index 694b87f0d..905626eb4 100644 --- a/es-app/src/guis/GuiScraperSearch.cpp +++ b/es-app/src/guis/GuiScraperSearch.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperSearch.cpp // // User interface for the scraper where the user is able to see an overview diff --git a/es-app/src/guis/GuiScraperSearch.h b/es-app/src/guis/GuiScraperSearch.h index 62ecc476d..69675ca46 100644 --- a/es-app/src/guis/GuiScraperSearch.h +++ b/es-app/src/guis/GuiScraperSearch.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperSearch.h // // User interface for the scraper where the user is able to see an overview diff --git a/es-app/src/guis/GuiScraperSingle.cpp b/es-app/src/guis/GuiScraperSingle.cpp index 3675ee75e..00edf0cb6 100644 --- a/es-app/src/guis/GuiScraperSingle.cpp +++ b/es-app/src/guis/GuiScraperSingle.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperSingle.cpp // // Single game scraping user interface. diff --git a/es-app/src/guis/GuiScraperSingle.h b/es-app/src/guis/GuiScraperSingle.h index 293b808e1..6f9b5093c 100644 --- a/es-app/src/guis/GuiScraperSingle.h +++ b/es-app/src/guis/GuiScraperSingle.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScraperSingle.h // // Single game scraping user interface. diff --git a/es-app/src/guis/GuiScreensaverOptions.cpp b/es-app/src/guis/GuiScreensaverOptions.cpp index 30b4b8ead..f97af6e1f 100644 --- a/es-app/src/guis/GuiScreensaverOptions.cpp +++ b/es-app/src/guis/GuiScreensaverOptions.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScreensaverOptions.cpp // // User interface for the screensaver options. @@ -15,6 +15,8 @@ #include "components/SliderComponent.h" #include "components/SwitchComponent.h" #include "guis/GuiMsgBox.h" +#include "guis/GuiTextEditKeyboardPopup.h" +#include "guis/GuiTextEditPopup.h" GuiScreensaverOptions::GuiScreensaverOptions(const std::string& title) : GuiSettings {title} @@ -196,20 +198,45 @@ void GuiScreensaverOptions::openSlideshowScreensaverOptions() }); // Custom image directory. - auto screensaverSlideshowImageDir = std::make_shared( - "", Font::get(FONT_SIZE_SMALL), mMenuColorPrimary, ALIGN_RIGHT); - s->addEditableTextComponent( - "CUSTOM IMAGE DIRECTORY", screensaverSlideshowImageDir, - Settings::getInstance()->getString("ScreensaverSlideshowImageDir"), - Settings::getInstance()->getDefaultString("ScreensaverSlideshowImageDir")); - s->addSaveFunc([screensaverSlideshowImageDir, s] { - if (screensaverSlideshowImageDir->getValue() != - Settings::getInstance()->getString("ScreensaverSlideshowImageDir")) { - Settings::getInstance()->setString("ScreensaverSlideshowImageDir", - screensaverSlideshowImageDir->getValue()); - s->setNeedsSaving(); + ComponentListRow rowCustomImageDir; + auto ScreensaverSlideshowCustomDir = std::make_shared( + "CUSTOM IMAGE DIRECTORY", Font::get(FONT_SIZE_MEDIUM), mMenuColorPrimary); + auto bracketCustomImageDir = std::make_shared(); + bracketCustomImageDir->setResize( + glm::vec2 {0.0f, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight()}); + bracketCustomImageDir->setImage(":/graphics/arrow.svg"); + bracketCustomImageDir->setColorShift(mMenuColorPrimary); + rowCustomImageDir.addElement(ScreensaverSlideshowCustomDir, true); + rowCustomImageDir.addElement(bracketCustomImageDir, false); + const std::string titleCustomImageDir {"CUSTOM IMAGE DIRECTORY"}; + const std::string defaultImageDirStaticText {"Default directory:"}; + const std::string defaultImageDirText {Utils::FileSystem::getAppDataDirectory() + + "/screensavers/custom_slideshow"}; + const std::string initValueMediaDir { + Settings::getInstance()->getString("ScreensaverSlideshowCustomDir")}; + auto updateValMediaDir = [s](const std::string& newVal) { + Settings::getInstance()->setString("ScreensaverSlideshowCustomDir", newVal); + s->setNeedsSaving(); + }; + rowCustomImageDir.makeAcceptInputHandler([this, s, titleCustomImageDir, + defaultImageDirStaticText, defaultImageDirText, + initValueMediaDir, updateValMediaDir] { + if (Settings::getInstance()->getBool("VirtualKeyboard")) { + mWindow->pushGui(new GuiTextEditKeyboardPopup( + getHelpStyle(), s->getMenu().getPosition().y, titleCustomImageDir, + Settings::getInstance()->getString("ScreensaverSlideshowCustomDir"), + updateValMediaDir, false, "SAVE", "SAVE CHANGES?", defaultImageDirStaticText, + defaultImageDirText, "load default directory")); + } + else { + mWindow->pushGui(new GuiTextEditPopup( + getHelpStyle(), titleCustomImageDir, + Settings::getInstance()->getString("ScreensaverSlideshowCustomDir"), + updateValMediaDir, false, "SAVE", "SAVE CHANGES?", defaultImageDirStaticText, + defaultImageDirText, "load default directory")); } }); + s->addRow(rowCustomImageDir); s->setSize(mSize); mWindow->pushGui(s); diff --git a/es-app/src/guis/GuiScreensaverOptions.h b/es-app/src/guis/GuiScreensaverOptions.h index 74f47112f..a14be386e 100644 --- a/es-app/src/guis/GuiScreensaverOptions.h +++ b/es-app/src/guis/GuiScreensaverOptions.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiScreensaverOptions.h // // User interface for the screensaver options. diff --git a/es-app/src/guis/GuiSettings.cpp b/es-app/src/guis/GuiSettings.cpp index f2ae13079..013042cdb 100644 --- a/es-app/src/guis/GuiSettings.cpp +++ b/es-app/src/guis/GuiSettings.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiSettings.cpp // // User interface template for a settings GUI. diff --git a/es-app/src/guis/GuiSettings.h b/es-app/src/guis/GuiSettings.h index f8a24bf84..b27b85a28 100644 --- a/es-app/src/guis/GuiSettings.h +++ b/es-app/src/guis/GuiSettings.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiSettings.h // // User interface template for a settings GUI. diff --git a/es-app/src/guis/GuiThemeDownloader.cpp b/es-app/src/guis/GuiThemeDownloader.cpp index 771ea5aca..1b09f217a 100644 --- a/es-app/src/guis/GuiThemeDownloader.cpp +++ b/es-app/src/guis/GuiThemeDownloader.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiThemeDownloader.cpp // // Theme downloader. @@ -8,7 +8,7 @@ #include "guis/GuiThemeDownloader.h" -#include "EmulationStation.h" +#include "ApplicationVersion.h" #include "ThemeData.h" #include "components/MenuComponent.h" #include "resources/ResourceManager.h" @@ -67,9 +67,9 @@ GuiThemeDownloader::GuiThemeDownloader(std::function updateCallback) std::make_shared("", Font::get(fontSizeSmall), mMenuColorTitle, ALIGN_LEFT); mCenterGrid->setEntry(mAspectRatiosLabel, glm::ivec2 {3, 0}, false, true, glm::ivec2 {1, 1}); - mFutureUseLabel = + mFontSizesLabel = std::make_shared("", Font::get(fontSizeSmall), mMenuColorTitle, ALIGN_LEFT); - mCenterGrid->setEntry(mFutureUseLabel, glm::ivec2 {3, 1}, false, true, glm::ivec2 {1, 1}); + mCenterGrid->setEntry(mFontSizesLabel, glm::ivec2 {3, 1}, false, true, glm::ivec2 {1, 1}); mCenterGrid->setEntry(std::make_shared(), glm::ivec2 {5, 0}, false, false, glm::ivec2 {1, 5}); @@ -86,9 +86,9 @@ GuiThemeDownloader::GuiThemeDownloader(std::function updateCallback) "", Font::get(fontSizeSmall, FONT_PATH_LIGHT), mMenuColorTitle, ALIGN_LEFT); mCenterGrid->setEntry(mAspectRatiosCount, glm::ivec2 {4, 0}, false, true, glm::ivec2 {1, 1}); - mFutureUseCount = std::make_shared("", Font::get(fontSizeSmall, FONT_PATH_LIGHT), + mFontSizesCount = std::make_shared("", Font::get(fontSizeSmall, FONT_PATH_LIGHT), mMenuColorTitle, ALIGN_LEFT); - mCenterGrid->setEntry(mFutureUseCount, glm::ivec2 {4, 1}, false, true, glm::ivec2 {1, 1}); + mCenterGrid->setEntry(mFontSizesCount, glm::ivec2 {4, 1}, false, true, glm::ivec2 {1, 1}); mDownloadStatus = std::make_shared("", Font::get(fontSizeSmall, FONT_PATH_BOLD), mMenuColorTitle, ALIGN_LEFT); @@ -162,20 +162,29 @@ GuiThemeDownloader::GuiThemeDownloader(std::function updateCallback) git_libgit2_init(); +#if defined(__ANDROID__) && defined(USE_BUNDLED_CERTIFICATES) + git_libgit2_opts( + GIT_OPT_SET_SSL_CERT_LOCATIONS, + ResourceManager::getInstance().getResourcePath(":/certificates/curl-ca-bundle.crt").c_str(), + nullptr); +#endif + // The promise/future mechanism is used as signaling for the thread to indicate that // repository fetching has been completed. std::promise().swap(mPromise); mFuture = mPromise.get_future(); - const std::string defaultUserThemeDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes"}; - std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( +#if defined(__ANDROID__) + mThemeDirectory = Utils::FileSystem::getInternalAppDataDirectory() + "/themes"; +#else + const std::string defaultUserThemeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"}; + const std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( Settings::getInstance()->getString("UserThemeDirectory"))}; + #if defined(_WIN64) mThemeDirectory = Utils::String::replace(mThemeDirectory, "\\", "/"); #endif - - if (userThemeDirSetting == "") { + if (userThemeDirSetting.empty()) { mThemeDirectory = defaultUserThemeDir; } else if (Utils::FileSystem::isDirectory(userThemeDirSetting) || @@ -189,6 +198,7 @@ GuiThemeDownloader::GuiThemeDownloader(std::function updateCallback) << defaultUserThemeDir << "\""; mThemeDirectory = defaultUserThemeDir; } +#endif if (mThemeDirectory.back() != '/') mThemeDirectory.append("/"); @@ -470,7 +480,10 @@ void GuiThemeDownloader::resetRepository(git_repository* repository) void GuiThemeDownloader::makeInventory() { + const auto totalInventoryTime {std::chrono::system_clock::now()}; + for (auto& theme : mThemes) { + const auto themeInventoryTime {std::chrono::system_clock::now()}; const std::string path {mThemeDirectory + theme.reponame}; theme.invalidRepository = false; theme.corruptRepository = false; @@ -519,8 +532,25 @@ void GuiThemeDownloader::makeInventory() theme.hasLocalChanges = true; git_repository_free(repository); + + LOG(LogDebug) << "GuiThemeDownloader::makeInventory(): Theme \"" +#if defined(_WIN64) + << Utils::String::replace(path, "/", "\\") + << "\" inventory completed in: " +#else + << path << "\" inventory completed in: " +#endif + << std::chrono::duration_cast( + std::chrono::system_clock::now() - themeInventoryTime) + .count() + << " ms"; } } + LOG(LogDebug) << "GuiThemeDownloader::makeInventory(): Total theme inventory time: " + << std::chrono::duration_cast( + std::chrono::system_clock::now() - totalInventoryTime) + .count() + << " ms"; } bool GuiThemeDownloader::renameDirectory(const std::string& path, const std::string& extension) @@ -561,8 +591,7 @@ void GuiThemeDownloader::parseThemesList() #if (LOCAL_TESTING_FILE) LOG(LogWarning) << "GuiThemeDownloader: Using local \"themes.json\" testing file"; - const std::string themesFile {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes.json"}; + const std::string themesFile {Utils::FileSystem::getAppDataDirectory() + "/themes.json"}; #else const std::string themesFile {mThemeDirectory + "themes-list/themes.json"}; #endif @@ -606,70 +635,92 @@ void GuiThemeDownloader::parseThemesList() } } - if (doc.HasMember("themes") && doc["themes"].IsArray()) { - const rapidjson::Value& themes {doc["themes"]}; - for (int i {0}; i < static_cast(themes.Size()); ++i) { - ThemeEntry themeEntry; - const rapidjson::Value& theme {themes[i]}; +#if defined(__ANDROID__) + const std::vector themeKeys {"themes", "themesAndroid"}; +#else + const std::vector themeKeys {"themes"}; +#endif - if (theme.HasMember("name") && theme["name"].IsString()) - themeEntry.name = theme["name"].GetString(); + for (auto& themeKey : themeKeys) { + if (doc.HasMember(themeKey.c_str()) && doc[themeKey.c_str()].IsArray()) { + const rapidjson::Value& themes {doc[themeKey.c_str()]}; + for (int i {0}; i < static_cast(themes.Size()); ++i) { + ThemeEntry themeEntry; + const rapidjson::Value& theme {themes[i]}; - if (theme.HasMember("reponame") && theme["reponame"].IsString()) - themeEntry.reponame = theme["reponame"].GetString(); + if (theme.HasMember("name") && theme["name"].IsString()) + themeEntry.name = theme["name"].GetString(); - if (theme.HasMember("url") && theme["url"].IsString()) - themeEntry.url = theme["url"].GetString(); + if (theme.HasMember("reponame") && theme["reponame"].IsString()) + themeEntry.reponame = theme["reponame"].GetString(); - if (theme.HasMember("author") && theme["author"].IsString()) - themeEntry.author = theme["author"].GetString(); + if (theme.HasMember("url") && theme["url"].IsString()) + themeEntry.url = theme["url"].GetString(); - if (theme.HasMember("newEntry") && theme["newEntry"].IsBool()) - themeEntry.newEntry = theme["newEntry"].GetBool(); + if (theme.HasMember("author") && theme["author"].IsString()) + themeEntry.author = theme["author"].GetString(); - if (theme.HasMember("variants") && theme["variants"].IsArray()) { - const rapidjson::Value& variants {theme["variants"]}; - for (int i {0}; i < static_cast(variants.Size()); ++i) - themeEntry.variants.emplace_back(variants[i].GetString()); - } + if (theme.HasMember("newEntry") && theme["newEntry"].IsBool()) + themeEntry.newEntry = theme["newEntry"].GetBool(); - if (theme.HasMember("colorSchemes") && theme["colorSchemes"].IsArray()) { - const rapidjson::Value& colorSchemes {theme["colorSchemes"]}; - for (int i {0}; i < static_cast(colorSchemes.Size()); ++i) - themeEntry.colorSchemes.emplace_back(colorSchemes[i].GetString()); - } - - if (theme.HasMember("aspectRatios") && theme["aspectRatios"].IsArray()) { - const rapidjson::Value& aspectRatios {theme["aspectRatios"]}; - for (int i {0}; i < static_cast(aspectRatios.Size()); ++i) - themeEntry.aspectRatios.emplace_back(aspectRatios[i].GetString()); - } - - if (theme.HasMember("transitions") && theme["transitions"].IsArray()) { - const rapidjson::Value& transitions {theme["transitions"]}; - for (int i {0}; i < static_cast(transitions.Size()); ++i) - themeEntry.transitions.emplace_back(transitions[i].GetString()); - } - - if (theme.HasMember("screenshots") && theme["screenshots"].IsArray()) { - const rapidjson::Value& screenshots {theme["screenshots"]}; - for (int i {0}; i < static_cast(screenshots.Size()); ++i) { - Screenshot screenshotEntry; - if (screenshots[i].HasMember("image") && screenshots[i]["image"].IsString()) - screenshotEntry.image = screenshots[i]["image"].GetString(); - - if (screenshots[i].HasMember("caption") && screenshots[i]["caption"].IsString()) - screenshotEntry.caption = screenshots[i]["caption"].GetString(); - - if (screenshotEntry.image != "" && screenshotEntry.caption != "") - themeEntry.screenshots.emplace_back(screenshotEntry); + if (theme.HasMember("variants") && theme["variants"].IsArray()) { + const rapidjson::Value& variants {theme["variants"]}; + for (int i {0}; i < static_cast(variants.Size()); ++i) + themeEntry.variants.emplace_back(variants[i].GetString()); } - } - mThemes.emplace_back(themeEntry); + if (theme.HasMember("colorSchemes") && theme["colorSchemes"].IsArray()) { + const rapidjson::Value& colorSchemes {theme["colorSchemes"]}; + for (int i {0}; i < static_cast(colorSchemes.Size()); ++i) + themeEntry.colorSchemes.emplace_back(colorSchemes[i].GetString()); + } + + if (theme.HasMember("aspectRatios") && theme["aspectRatios"].IsArray()) { + const rapidjson::Value& aspectRatios {theme["aspectRatios"]}; + for (int i {0}; i < static_cast(aspectRatios.Size()); ++i) + themeEntry.aspectRatios.emplace_back(aspectRatios[i].GetString()); + } + + if (theme.HasMember("fontSizes") && theme["fontSizes"].IsArray()) { + const rapidjson::Value& fontSizes {theme["fontSizes"]}; + for (int i {0}; i < static_cast(fontSizes.Size()); ++i) + themeEntry.fontSizes.emplace_back(fontSizes[i].GetString()); + } + + if (theme.HasMember("transitions") && theme["transitions"].IsArray()) { + const rapidjson::Value& transitions {theme["transitions"]}; + for (int i {0}; i < static_cast(transitions.Size()); ++i) + themeEntry.transitions.emplace_back(transitions[i].GetString()); + } + + if (theme.HasMember("screenshots") && theme["screenshots"].IsArray()) { + const rapidjson::Value& screenshots {theme["screenshots"]}; + for (int i {0}; i < static_cast(screenshots.Size()); ++i) { + Screenshot screenshotEntry; + if (screenshots[i].HasMember("image") && screenshots[i]["image"].IsString()) + screenshotEntry.image = screenshots[i]["image"].GetString(); + + if (screenshots[i].HasMember("caption") && + screenshots[i]["caption"].IsString()) + screenshotEntry.caption = screenshots[i]["caption"].GetString(); + + if (screenshotEntry.image != "" && screenshotEntry.caption != "") + themeEntry.screenshots.emplace_back(screenshotEntry); + } + } + + mThemes.emplace_back(themeEntry); + } } } + std::sort(std::begin(mThemes), std::end(mThemes), [](ThemeEntry a, ThemeEntry b) { + if (Utils::String::toUpper(a.name) < Utils::String::toUpper(b.name)) + return true; + else + return false; + }); + LOG(LogDebug) << "GuiThemeDownloader::parseThemesList(): Parsed " << mThemes.size() << " themes"; } @@ -826,6 +877,7 @@ void GuiThemeDownloader::populateGUI() mVariantsLabel->setText("VARIANTS:"); mColorSchemesLabel->setText("COLOR SCHEMES:"); mAspectRatiosLabel->setText("ASPECT RATIOS:"); + mFontSizesLabel->setText("FONT SIZES:"); updateInfoPane(); updateHelpPrompts(); @@ -901,6 +953,7 @@ void GuiThemeDownloader::updateInfoPane() mVariantCount->setText(std::to_string(mThemes[mList->getCursorId()].variants.size())); mColorSchemesCount->setText(std::to_string(mThemes[mList->getCursorId()].colorSchemes.size())); mAspectRatiosCount->setText(std::to_string(mThemes[mList->getCursorId()].aspectRatios.size())); + mFontSizesCount->setText(std::to_string(mThemes[mList->getCursorId()].fontSizes.size())); mAuthor->setText("CREATED BY " + Utils::String::toUpper(mThemes[mList->getCursorId()].author)); } @@ -1158,10 +1211,16 @@ bool GuiThemeDownloader::input(InputConfig* config, Input input) "LOCAL CUSTOMIZATIONS", "PROCEED", [this] { - const std::filesystem::path themeDirectory {mThemeDirectory + - mThemes[mList->getCursorId()].reponame}; - LOG(LogInfo) << "Deleting theme directory \"" << themeDirectory.string() << "\""; - if (!Utils::FileSystem::removeDirectory(themeDirectory.string(), true)) { +#if defined(_WIN64) + const std::string themeDirectory { + Utils::String::replace(mThemeDirectory, "/", "\\") + + mThemes[mList->getCursorId()].reponame}; +#else + const std::string themeDirectory {mThemeDirectory + + mThemes[mList->getCursorId()].reponame}; +#endif + LOG(LogInfo) << "Deleting theme directory \"" << themeDirectory << "\""; + if (!Utils::FileSystem::removeDirectory(themeDirectory, true)) { mWindow->pushGui(new GuiMsgBox( getHelpStyle(), "COULDN'T DELETE THEME, PERMISSION PROBLEMS?", "OK", [] { return; }, "", nullptr, "", nullptr, nullptr, true)); diff --git a/es-app/src/guis/GuiThemeDownloader.h b/es-app/src/guis/GuiThemeDownloader.h index c8bbec35e..2a807756e 100644 --- a/es-app/src/guis/GuiThemeDownloader.h +++ b/es-app/src/guis/GuiThemeDownloader.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiThemeDownloader.h // // Theme downloader. @@ -64,6 +64,7 @@ private: std::vector variants; std::vector colorSchemes; std::vector aspectRatios; + std::vector fontSizes; std::vector transitions; std::vector screenshots; bool newEntry; @@ -165,12 +166,12 @@ private: std::shared_ptr mVariantsLabel; std::shared_ptr mColorSchemesLabel; std::shared_ptr mAspectRatiosLabel; - std::shared_ptr mFutureUseLabel; + std::shared_ptr mFontSizesLabel; std::shared_ptr mAuthor; std::shared_ptr mVariantCount; std::shared_ptr mColorSchemesCount; std::shared_ptr mAspectRatiosCount; - std::shared_ptr mFutureUseCount; + std::shared_ptr mFontSizesCount; }; #endif // ES_APP_GUIS_GUI_THEME_DOWNLOADER_H diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 42dd245ac..e1f7a17d2 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -1,26 +1,21 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition (ES-DE) is a frontend for browsing -// and launching games from your multi-platform game collection. -// -// Originally created by Alec Lofquist. -// Improved and extended by the RetroPie community. -// Desktop Edition fork by Leon Styhre. +// ES-DE is a frontend for browsing and launching games from your multi-platform game collection. // // The column limit is 100 characters. // All ES-DE C++ source code is formatted using clang-format. // // main.cpp // -// Main program loop. Interprets command-line arguments, checks for the -// home folder and es_settings.xml configuration file, sets up the application -// environment and starts listening to SDL events. +// Main program loop. Interprets command-line arguments, checks for the home folder +// and es_settings.xml configuration file, sets up the application environment and +// starts listening to SDL events. // #include "ApplicationUpdater.h" +#include "ApplicationVersion.h" #include "AudioManager.h" #include "CollectionSystemsManager.h" -#include "EmulationStation.h" #include "InputManager.h" #include "Log.h" #include "MameNames.h" @@ -42,6 +37,10 @@ #include #include +#if defined(__ANDROID__) +#include "utils/PlatformUtilAndroid.h" +#endif + #if defined(__EMSCRIPTEN__) #include #endif @@ -63,6 +62,11 @@ namespace Window* window {nullptr}; int lastTime {0}; +#if defined(__ANDROID__) + int inputBlockTime {0}; + bool blockInput {false}; +#endif + #if defined(APPLICATION_UPDATER) bool noUpdateCheck {false}; #endif @@ -244,7 +248,7 @@ bool parseArguments(const std::vector& arguments) const int width {stoi(arguments[i + 1])}; const int height {stoi(arguments[i + 2])}; if (width < 224 || height < 224 || width > 7680 || height > 7680 || - height < width / 4 || width < height / 2) { + height < width / 4 || width < height / 3) { std::cerr << "Error: Unsupported resolution " << width << "x" << height << " supplied\n"; return false; @@ -386,15 +390,15 @@ bool parseArguments(const std::vector& arguments) Log::setReportingLevel(LogDebug); } else if (arguments[i] == "--version" || arguments[i] == "-v") { - std::cout << "EmulationStation Desktop Edition v" << PROGRAM_VERSION_STRING << " (r" - << PROGRAM_RELEASE_NUMBER << ")\n"; + std::cout << "ES-DE v" << PROGRAM_VERSION_STRING << " (r" << PROGRAM_RELEASE_NUMBER + << ")\n"; return false; } else if (arguments[i] == "--help" || arguments[i] == "-h") { std::cout << // clang-format off -"Usage: emulationstation [options]\n" -"EmulationStation Desktop Edition, Emulator Frontend\n\n" +"Usage: es-de [options]\n" +"ES-DE (ES-DE), Emulator Frontend\n\n" "Options:\n" " --display [1 to 4] Display/monitor to use\n" " --resolution [width] [height] Application resolution\n" @@ -429,7 +433,7 @@ bool parseArguments(const std::vector& arguments) else { const std::string argUnknown {arguments[i]}; std::cout << "Unknown option '" << argUnknown << "'.\n"; - std::cout << "Try 'emulationstation --help' for more information.\n"; + std::cout << "Try 'es-de --help' for more information.\n"; return false; } } @@ -442,22 +446,27 @@ bool parseArguments(const std::vector& arguments) return true; } -bool checkApplicationHomeDirectory() +bool checkApplicationDataDirectory() { - // Check that the application home directory exists, otherwise create it. - std::string home {Utils::FileSystem::getHomePath()}; - std::string applicationHome {home + "/.emulationstation"}; - if (!Utils::FileSystem::exists(applicationHome)) { -#if defined(_WIN64) - std::cout << "First startup, creating application home directory \"" - << Utils::String::replace(applicationHome, "/", "\\") << "\"\n"; + // Check that the application data directory exists, otherwise create it. + const std::string applicationData {Utils::FileSystem::getAppDataDirectory()}; + if (!Utils::FileSystem::exists(applicationData)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_APPLICATION_ID, + "First startup, creating application data directory \"%s\"", + applicationData.c_str()); #else - std::cout << "First startup, creating application home directory \"" << applicationHome + std::cout << "First startup, creating application data directory \"" << applicationData << "\"\n"; #endif - Utils::FileSystem::createDirectory(applicationHome); - if (!Utils::FileSystem::exists(applicationHome)) { + Utils::FileSystem::createDirectory(applicationData); + if (!Utils::FileSystem::exists(applicationData)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Couldn't create directory, permission problems?"); +#else std::cerr << "Error: Couldn't create directory, permission problems?\n"; +#endif return false; } } @@ -492,6 +501,18 @@ void applicationLoop() #endif if (SDL_PollEvent(&event)) { do { +#if defined(__ANDROID__) + // Prevent that button presses get registered immediately when entering the + // foreground (which most commonly mean we're returning from a game). + // Also perform some other tasks on resume such as resetting timers. + if (event.type == SDL_APP_WILLENTERFOREGROUND) { + blockInput = true; + inputBlockTime = 0; + window->setBlockInput(true); + Utils::Platform::Android::onResume(); + ViewController::getInstance()->resetViewVideosTimer(); + } +#endif InputManager::getInstance().parseEvent(event); if (event.type == SDL_QUIT) @@ -511,6 +532,16 @@ void applicationLoop() if (deltaTime < 0) deltaTime = 1000; +#if defined(__ANDROID__) + if (blockInput) { + inputBlockTime += deltaTime; + if (inputBlockTime > 300) { + inputBlockTime = 0; + blockInput = false; + window->setBlockInput(false); + } + } +#endif window->update(deltaTime); window->render(); @@ -532,7 +563,7 @@ int main(int argc, char* argv[]) // macOS which forces a restore of the previous window state. The problem is that this // removes the splash screen on startup and it may have other adverse effects as well. std::string saveStateDir {Utils::FileSystem::expandHomePath( - "~/Library/Saved Application State/org.es-de.EmulationStation.savedState")}; + "~/Library/Saved Application State/org.es-de.Frontend.savedState")}; // Deletion of the state files should normally not be required as there shouldn't be any // files to begin with. But maybe the files can still be created for unknown reasons // as macOS really really loves to restore windows. Let's therefore include this deletion @@ -555,6 +586,7 @@ int main(int argc, char* argv[]) outputToConsole(); #endif +#if !defined(__ANDROID__) { std::vector arguments; for (int i {0}; i < argc; ++i) @@ -570,6 +602,27 @@ int main(int argc, char* argv[]) } #endif } +#endif + +#if defined(__ANDROID__) + bool resetTouchOverlay {false}; + + if (Utils::Platform::Android::checkConfigurationNeeded()) { + Utils::Platform::Android::startConfigurator(); + + while (AndroidVariables::sHold) + SDL_Delay(20); + + if (Utils::Platform::Android::checkConfigurationNeeded()) + exit(0); + + // Always enable the touch overlay after running the configurator. + resetTouchOverlay = true; + } + + Utils::Platform::Android::setDataDirectories(); + Utils::Platform::Android::setROMDirectory(); +#endif if (!Settings::getInstance()->getBool("DebugFlag") && Settings::getInstance()->getBool("DebugMode")) { @@ -582,21 +635,59 @@ int main(int argc, char* argv[]) FreeImage_Initialise(); #endif - // If ~/.emulationstation doesn't exist and cannot be created, bail. - if (!checkApplicationHomeDirectory()) + // If the application data directory doesn't exist and can't be created, then exit. + if (!checkApplicationDataDirectory()) return 1; + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the logs folder in the application data directory. + const std::string logsDir {Utils::FileSystem::getAppDataDirectory() + "/logs"}; + if (!Utils::FileSystem::isDirectory(logsDir)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_APPLICATION_ID, + "Creating logs directory \"%s\"...", logsDir.c_str()); +#else + std::cout << "Creating logs directory \"" << logsDir << "\"..." << std::endl; +#endif + Utils::FileSystem::createDirectory(logsDir); + if (!Utils::FileSystem::isDirectory(logsDir)) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Couldn't create directory, permission problems?"); +#else + std::cerr << "Couldn't create directory, permission problems?" << std::endl; +#endif + } + else { + // Remove any old logs in the root of the directory. + Utils::FileSystem::removeFile(Utils::FileSystem::getAppDataDirectory() + + "/es_log.txt"); + Utils::FileSystem::removeFile(Utils::FileSystem::getAppDataDirectory() + + "/es_log.txt.bak"); + } + } + } + } + // Start the logger. Log::init(); Log::open(); - LOG(LogInfo) << "EmulationStation Desktop Edition v" << PROGRAM_VERSION_STRING << " (r" - << PROGRAM_RELEASE_NUMBER << "), built " << PROGRAM_BUILT_STRING; - if (portableMode) { - LOG(LogInfo) << "Running in portable mode"; - Settings::getInstance()->setBool("PortableMode", true); - } - else { - Settings::getInstance()->setBool("PortableMode", false); + { +#if defined(ANDROID_LITE_RELEASE) + const std::string applicationName {"ES-DE Lite"}; +#else + const std::string applicationName {"ES-DE"}; +#endif + LOG(LogInfo) << applicationName << " v" << PROGRAM_VERSION_STRING << " (r" + << PROGRAM_RELEASE_NUMBER << "), built " << PROGRAM_BUILT_STRING; + if (portableMode) { + LOG(LogInfo) << "Running in portable mode"; + Settings::getInstance()->setBool("PortableMode", true); + } + else { + Settings::getInstance()->setBool("PortableMode", false); + } } // Always close the log on exit. @@ -605,7 +696,7 @@ int main(int argc, char* argv[]) if (createSystemDirectories) { if (!SystemData::createSystemDirectories() && !Settings::getInstance()->getBool("Debug")) std::cout << "System directories successfully created" << std::endl; - LOG(LogInfo) << "EmulationStation cleanly shutting down"; + LOG(LogInfo) << "ES-DE cleanly shutting down"; #if defined(_WIN64) FreeConsole(); #endif @@ -622,93 +713,221 @@ int main(int argc, char* argv[]) Settings::getInstance()->setInt("ScreenHeight", 720); #endif - // Check if the configuration file exists, and if not, create it. - // This should only happen on first application startup. - if (!Utils::FileSystem::exists(Utils::FileSystem::getHomePath() + - "/.emulationstation/es_settings.xml")) { - LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; - Settings::getInstance()->saveFile(); - } - else if (settingsNeedSaving) { - LOG(LogInfo) << "Saving settings that were modified by command line options..."; - Settings::getInstance()->saveFile(); + bool migratedSettings {false}; + + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the settings folder in the application data directory. + const std::string settingsDir {Utils::FileSystem::getAppDataDirectory() + "/settings"}; + if (!Utils::FileSystem::isDirectory(settingsDir)) { + LOG(LogInfo) << "Creating settings directory \"" << settingsDir << "\"..."; + Utils::FileSystem::createDirectory(settingsDir); + if (!Utils::FileSystem::isDirectory(settingsDir)) { + LOG(LogError) << "Couldn't create directory, permission problems?"; + } + } + std::string settingsPathOld; + std::string settingsPathNew; + settingsPathOld = Utils::FileSystem::getAppDataDirectory() + "/es_settings.xml"; + settingsPathNew = + Utils::FileSystem::getAppDataDirectory() + "/settings/es_settings.xml"; + if (!Utils::FileSystem::exists(settingsPathNew) && + Utils::FileSystem::exists(settingsPathOld)) { + Utils::FileSystem::renameFile(settingsPathOld, settingsPathNew, false); + Settings::getInstance()->loadFile(); + migratedSettings = true; + } + settingsPathOld = Utils::FileSystem::getAppDataDirectory() + "/es_input.xml"; + settingsPathNew = Utils::FileSystem::getAppDataDirectory() + "/settings/es_input.xml"; + if (!Utils::FileSystem::exists(settingsPathNew) && + Utils::FileSystem::exists(settingsPathOld)) { + Utils::FileSystem::renameFile(settingsPathOld, settingsPathNew, false); + migratedSettings = true; + } + } } - // Check if the application release number has changed, which would normally mean that the - // user has upgraded to a new version. - int applicationRelease; - if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) != - PROGRAM_RELEASE_NUMBER) { - if (applicationRelease != 0) { - LOG(LogInfo) << "Application release number changed from previous startup, from \"" - << applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\""; + { + // Check if the es_settings.xml file exists, and if not, create it. + std::string settingsPath; + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + settingsPath = Utils::FileSystem::getAppDataDirectory() + "/es_settings.xml"; + else + settingsPath = Utils::FileSystem::getAppDataDirectory() + "/settings/es_settings.xml"; + + if (!Utils::FileSystem::exists(settingsPath)) { + LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; + Settings::getInstance()->saveFile(); } - else { - LOG(LogInfo) << "Application release number setting is blank, changing it to \"" - << PROGRAM_RELEASE_NUMBER << "\""; + else if (settingsNeedSaving) { + LOG(LogInfo) << "Saving settings that were modified by command line options..."; + Settings::getInstance()->saveFile(); } - Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER); - Settings::getInstance()->saveFile(); } - // Create the gamelists directory in the application home folder. - const std::string gamelistsDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/gamelists"}; - if (!Utils::FileSystem::exists(gamelistsDir)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating gamelists directory \"" - << Utils::String::replace(gamelistsDir, "/", "\\") << "\"..."; -#else - LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir << "\"..."; +#if defined(__ANDROID__) + if (resetTouchOverlay) { + Settings::getInstance()->setBool("InputTouchOverlay", true); + Settings::getInstance()->saveFile(); + } #endif - Utils::FileSystem::createDirectory(gamelistsDir); + + { + // Check if the application release number has changed, which would normally mean that the + // user has upgraded to a new version. + int applicationRelease; + if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) != + PROGRAM_RELEASE_NUMBER) { + if (applicationRelease != 0) { + LOG(LogInfo) << "Application release number changed from previous startup, from \"" + << applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\""; + } + else { + LOG(LogInfo) << "Application release number setting is blank, changing it to \"" + << PROGRAM_RELEASE_NUMBER << "\""; + } + Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER); + Settings::getInstance()->saveFile(); + } + } + + { + // Create the gamelists folder in the application data directory. + const std::string gamelistsDir {Utils::FileSystem::getAppDataDirectory() + "/gamelists"}; if (!Utils::FileSystem::exists(gamelistsDir)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; + LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir << "\"..."; + Utils::FileSystem::createDirectory(gamelistsDir); + if (!Utils::FileSystem::exists(gamelistsDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } } } - // Create the themes directory in the application home directory (or elsewhere if the - // UserThemeDirectory setting has been defined). - const std::string defaultUserThemeDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes"}; - std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( - Settings::getInstance()->getString("UserThemeDirectory"))}; -#if defined(_WIN64) - userThemeDirSetting = Utils::String::replace(userThemeDirSetting, "\\", "/"); -#endif - std::string userThemeDirectory; + { +#if defined(__ANDROID__) + const std::string themeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"}; + if (!Utils::FileSystem::exists(themeDir)) { + LOG(LogInfo) << "Creating themes directory \"" << themeDir << "\"..."; - if (userThemeDirSetting == "") - userThemeDirectory = defaultUserThemeDir; - else - userThemeDirectory = userThemeDirSetting; - - if (!Utils::FileSystem::exists(userThemeDirectory)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating user theme directory \"" - << Utils::String::replace(userThemeDirectory, "/", "\\") << "\"..."; + Utils::FileSystem::createDirectory(themeDir); + if (!Utils::FileSystem::exists(themeDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } + if (!Utils::FileSystem::exists(themeDir + "/.nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" << themeDir + "/.nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(themeDir + "/.nomedia"); + if (!Utils::FileSystem::exists(themeDir + "/.nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } #else - LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory << "\"..."; -#endif - Utils::FileSystem::createDirectory(userThemeDirectory); + // Create the themes folder in the application data directory (or elsewhere if the + // UserThemeDirectory setting has been defined). + const std::string defaultUserThemeDir {Utils::FileSystem::getAppDataDirectory() + + "/themes"}; + std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( + Settings::getInstance()->getString("UserThemeDirectory"))}; + std::string userThemeDirectory; + + if (userThemeDirSetting.empty()) + userThemeDirectory = defaultUserThemeDir; + else + userThemeDirectory = userThemeDirSetting; + if (!Utils::FileSystem::exists(userThemeDirectory)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?"; + LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory << "\"..."; + + Utils::FileSystem::createDirectory(userThemeDirectory); + if (!Utils::FileSystem::exists(userThemeDirectory)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } +#endif + } + + { +#if defined(__ANDROID__) + const std::string mediaDirectory {FileData::getMediaDirectory()}; + if (Utils::FileSystem::exists(mediaDirectory)) + if (!Utils::FileSystem::exists(mediaDirectory + ".nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" << mediaDirectory + ".nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(mediaDirectory + ".nomedia"); + if (!Utils::FileSystem::exists(mediaDirectory + ".nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } +#endif + } + + { + // Create the scripts folder in the application data directory. This is only required + // for custom event scripts so it's also created as a convenience. + const std::string scriptsDir {Utils::FileSystem::getAppDataDirectory() + "/scripts"}; + if (!Utils::FileSystem::exists(scriptsDir)) { + LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir << "\"..."; + Utils::FileSystem::createDirectory(scriptsDir); + if (!Utils::FileSystem::exists(scriptsDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } } } - // Create the scripts directory in the application home folder. This is only required - // for custom event scripts so it's also created as a convenience. - const std::string scriptsDir {Utils::FileSystem::getHomePath() + "/.emulationstation/scripts"}; - if (!Utils::FileSystem::exists(scriptsDir)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating scripts directory \"" - << Utils::String::replace(scriptsDir, "/", "\\") << "\"..."; -#else - LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir << "\"..."; + { + // Create the screensavers and screensavers/custom_slideshow directories. + const std::string screensaversDir {Utils::FileSystem::getAppDataDirectory() + + "/screensavers"}; + const std::string slideshowDir {Utils::FileSystem::getAppDataDirectory() + + "/screensavers/custom_slideshow"}; + if (!Utils::FileSystem::exists(screensaversDir)) { + LOG(LogInfo) << "Creating screensavers directory \"" << screensaversDir << "\"..."; + Utils::FileSystem::createDirectory(screensaversDir); + if (!Utils::FileSystem::exists(screensaversDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } +#if defined(__ANDROID__) + if (!Utils::FileSystem::exists(screensaversDir + "/.nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" << screensaversDir + "/.nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(screensaversDir + "/.nomedia"); + if (!Utils::FileSystem::exists(screensaversDir + "/.nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } #endif - Utils::FileSystem::createDirectory(scriptsDir); - if (!Utils::FileSystem::exists(scriptsDir)) { - LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; + if (!Utils::FileSystem::exists(slideshowDir)) { + LOG(LogInfo) << "Creating custom_slideshow directory \"" << slideshowDir << "\"..."; + Utils::FileSystem::createDirectory(slideshowDir); + if (!Utils::FileSystem::exists(slideshowDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } + } + + { + if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + // Create the controllers folder in the application data directory. + const std::string controllersDir {Utils::FileSystem::getAppDataDirectory() + + "/controllers"}; + if (!Utils::FileSystem::exists(controllersDir)) { + LOG(LogInfo) << "Creating controllers directory \"" << controllersDir << "\"..."; + Utils::FileSystem::createDirectory(controllersDir); + if (!Utils::FileSystem::exists(controllersDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } + std::string configPathOld {Utils::FileSystem::getAppDataDirectory() + + "/es_controller_mappings.cfg"}; + std::string configPathNew {Utils::FileSystem::getAppDataDirectory() + + "/controllers/es_controller_mappings.cfg"}; + if (!Utils::FileSystem::exists(configPathNew) && + Utils::FileSystem::exists(configPathOld)) { + Utils::FileSystem::renameFile(configPathOld, configPathNew, false); + migratedSettings = true; + } } } @@ -727,6 +946,49 @@ int main(int argc, char* argv[]) return 1; } +#if defined(__ANDROID__) + InputOverlay::getInstance().init(); + + LOG(LogDebug) << "Android API level: " << SDL_GetAndroidSDKVersion(); + Utils::Platform::Android::printDeviceInfo(); + int storageState {SDL_AndroidGetExternalStorageState()}; + if (storageState == 0) { + LOG(LogError) << "Android external storage state: " << SDL_GetError(); + } + else if (storageState == 1) { + LOG(LogWarning) << "Android external storage state: mounted read-only"; + } + else { + LOG(LogDebug) << "Android external storage state: mounted read/write"; + } + LOG(LogDebug) << "Android internal directory: " << AndroidVariables::sInternalDataDirectory; + LOG(LogDebug) << "Android external directory: " << AndroidVariables::sExternalDataDirectory; + + { + std::string buildIdentifier {PROGRAM_VERSION_STRING}; + buildIdentifier.append(" (r") + .append(std::to_string(PROGRAM_RELEASE_NUMBER)) + .append("), built ") + .append(PROGRAM_BUILT_STRING); + if (Utils::Platform::Android::checkNeedResourceCopy(buildIdentifier)) { + LOG(LogInfo) << "Application has been updated or it's a new installation, copying " + "bundled resources and themes to internal storage..."; + if (Settings::getInstance()->getBool("SplashScreen")) + window->renderSplashScreen(Window::SplashScreenState::RESOURCE_COPY, 0.0f); + if (Utils::Platform::Android::setupResources(buildIdentifier)) { + LOG(LogError) << "Copying of resources and themes failed"; + return -1; + } + } + } + + if (Utils::Platform::Android::getCreateSystemDirectories()) { + if (Settings::getInstance()->getBool("SplashScreen")) + window->renderSplashScreen(Window::SplashScreenState::DIR_CREATION, 0.0f); + SystemData::createSystemDirectories(); + } +#endif + #if defined(APPLICATION_UPDATER) if (!noUpdateCheck) ApplicationUpdater::getInstance().checkForUpdates(); @@ -759,12 +1021,19 @@ int main(int argc, char* argv[]) LOG(LogInfo) << "SDL version: " << std::to_string(version.major) << "." << std::to_string(version.minor) << "." << std::to_string(version.patch); +#if defined(__ANDROID__) + if (Settings::getInstance()->getBool("VirtualKeyboard")) + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); + else + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "1"); +#else if (version.major > 2 || (version.major == 2 && version.minor >= 28)) { // This will prevent the popup virtual keyboard of any handheld device from being // automatically displayed on top of the ES-DE virtual keyboard. #define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD" SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); } +#endif MameNames::getInstance(); ThemeData::populateThemes(); @@ -808,6 +1077,18 @@ int main(int argc, char* argv[]) } } +#if defined(__ANDROID__) + if (!Utils::FileSystem::exists(FileData::getROMDirectory() + ".nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" + << FileData::getROMDirectory() + ".nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(FileData::getROMDirectory() + ".nomedia"); + if (!Utils::FileSystem::exists(FileData::getROMDirectory() + ".nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } +#endif + // Generate controller events since we're done loading. SDL_GameControllerEventState(SDL_ENABLE); @@ -843,6 +1124,14 @@ int main(int argc, char* argv[]) } #endif + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + ViewController::getInstance()->legacyAppDataDialog(); + + if (migratedSettings) { + LOG(LogInfo) << "Migrated settings from a legacy application data directory structure"; + ViewController::getInstance()->migratedAppDataFilesDialog(); + } + LOG(LogInfo) << "Application startup time: " << std::chrono::duration_cast( std::chrono::system_clock::now() - applicationStartTime) @@ -891,7 +1180,7 @@ int main(int argc, char* argv[]) Utils::Platform::processQuitMode(); - LOG(LogInfo) << "EmulationStation cleanly shutting down"; + LOG(LogInfo) << "ES-DE cleanly shutting down"; #if defined(_WIN64) FreeConsole(); diff --git a/es-app/src/scrapers/GamesDBJSONScraper.cpp b/es-app/src/scrapers/GamesDBJSONScraper.cpp index 2e6257c51..31525bd3b 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraper.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraper.cpp // // Functions specifically for scraping from thegamesdb.net diff --git a/es-app/src/scrapers/GamesDBJSONScraper.h b/es-app/src/scrapers/GamesDBJSONScraper.h index fedba2ecd..e5c952077 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.h +++ b/es-app/src/scrapers/GamesDBJSONScraper.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraper.h // // Functions specifically for scraping from thegamesdb.net diff --git a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp index 161c30cd9..417749d60 100644 --- a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraperResources.cpp // // Functions specifically for scraping from thegamesdb.net // Called from GamesDBJSONScraper. // -// Downloads these resource files to ~/.emulationstation/scrapers: +// Downloads these resource files to the scrapers folder in the application data directory: // gamesdb_developers.json // gamesdb_genres.json // gamesdb_publishers.json @@ -41,9 +41,9 @@ namespace constexpr int MAX_WAIT_ITER {MAX_WAIT_MS / POLL_TIME_MS}; constexpr char SCRAPER_RESOURCES_DIR[] {"scrapers"}; - constexpr char DEVELOPERS_JSON_FILE[] {"gamesdb_developers.json"}; - constexpr char PUBLISHERS_JSON_FILE[] {"gamesdb_publishers.json"}; - constexpr char GENRES_JSON_FILE[] {"gamesdb_genres.json"}; + constexpr char DEVELOPERS_JSON_FILE[] {"thegamesdb_developers.json"}; + constexpr char PUBLISHERS_JSON_FILE[] {"thegamesdb_publishers.json"}; + constexpr char GENRES_JSON_FILE[] {"thegamesdb_genres.json"}; constexpr char DEVELOPERS_ENDPOINT[] {"/Developers"}; constexpr char PUBLISHERS_ENDPOINT[] {"/Publishers"}; constexpr char GENRES_ENDPOINT[] {"/Genres"}; @@ -64,8 +64,7 @@ namespace std::string getScrapersResouceDir() { - return Utils::FileSystem::getGenericPath(Utils::FileSystem::getHomePath() + - "/.emulationstation/" + SCRAPER_RESOURCES_DIR); + return Utils::FileSystem::getAppDataDirectory() + "/" + SCRAPER_RESOURCES_DIR; } std::string TheGamesDBJSONRequestResources::getApiKey() const { return GamesDBAPIKey; } diff --git a/es-app/src/scrapers/GamesDBJSONScraperResources.h b/es-app/src/scrapers/GamesDBJSONScraperResources.h index 631b85cc6..e567aa364 100644 --- a/es-app/src/scrapers/GamesDBJSONScraperResources.h +++ b/es-app/src/scrapers/GamesDBJSONScraperResources.h @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraperResources.h // // Functions specifically for scraping from thegamesdb.net // Called from GamesDBJSONScraper. // -// Downloads these resource files to ~/.emulationstation/scrapers: +// Downloads these resource files to the scrapers folder in the application data directory: // gamesdb_developers.json // gamesdb_genres.json // gamesdb_publishers.json diff --git a/es-app/src/scrapers/Scraper.cpp b/es-app/src/scrapers/Scraper.cpp index c9c6c20ba..f4c01c993 100644 --- a/es-app/src/scrapers/Scraper.cpp +++ b/es-app/src/scrapers/Scraper.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scraper.cpp // // Main scraper logic. @@ -168,6 +168,13 @@ void ScraperHttpRequest::update() if (status == HttpReq::REQ_IN_PROGRESS) return; + if (status == HttpReq::REQ_RESOURCE_NOT_FOUND) { + LOG(LogDebug) << "ScraperHttpRequest::update(): Server returned HTTP error code 404 " + "(resource not found)"; + setStatus(ASYNC_DONE); + return; + } + // Everything else is some sort of error. LOG(LogError) << "ScraperHttpRequest network error (status: " << status << ") - " << mReq->getErrorMsg(); @@ -308,34 +315,6 @@ MDResolveHandle::MDResolveHandle(const ScraperSearchResult& result, // If the image is cached already as the thumbnail, then we don't need // to download it again, in this case just save it to disk and resize it. if (mResult.thumbnailImageUrl == it->fileURL && mResult.thumbnailImageData.size() > 0) { - // This is just a temporary workaround to avoid saving media files to disk that - // are actually just containing error messages from the scraper service. The - // proper solution is to implement file checksum checks to determine if the - // server response contains valid media. As for the current approach, if the - // file is less than 350 bytes, we check if FreeImage can actually detect a - // valid format, and if not, we present an error message. Black/empty images - // are sometimes returned from the scraper service and these can actually be - // less than 350 bytes in size. - if (Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia") && - mResult.thumbnailImageData.size() < 350) { - - FIMEMORY* memoryStream { - FreeImage_OpenMemory(reinterpret_cast(&mResult.thumbnailImageData.at(0)), - static_cast(mResult.thumbnailImageData.size()))}; - - FREE_IMAGE_FORMAT imageFormat {FreeImage_GetFileTypeFromMemory(memoryStream, 0)}; - FreeImage_CloseMemory(memoryStream); - - if (imageFormat == FIF_UNKNOWN) { - setError( - "The file \"" + Utils::FileSystem::getFileName(filePath) + - "\" returned by the scraper seems to be invalid as it's less than " + - "350 bytes in size", - true); - return; - } - } - // Remove any existing media file before attempting to write a new one. // This avoids the problem where there's already a file for this media type // with a different format/extension (e.g. game.jpg and we're going to write @@ -535,35 +514,6 @@ void MediaDownloadHandle::update() } } - // This is just a temporary workaround to avoid saving media files to disk that are - // actually just containing error messages from the scraper service. The proper solution - // is to implement file checksum checks to determine if the server response contains valid - // media. As for the current approach, if the file is less than 350 bytes, we check if - // FreeImage can actually detect a valid format, and if not, we present an error message. - // Black/empty images are sometimes returned from the scraper service and these can actually - // be less than 350 bytes in size. - if (Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia") && - mReq->getContent().size() < 350) { - - FREE_IMAGE_FORMAT imageFormat {FIF_UNKNOWN}; - - if (mMediaType != "videos") { - std::string imageData {mReq->getContent()}; - FIMEMORY* memoryStream {FreeImage_OpenMemory(reinterpret_cast(&imageData.at(0)), - static_cast(imageData.size()))}; - imageFormat = FreeImage_GetFileTypeFromMemory(memoryStream, 0); - FreeImage_CloseMemory(memoryStream); - } - - if (imageFormat == FIF_UNKNOWN) { - setError("The " + mMediaType + " file \"" + Utils::FileSystem::getFileName(mSavePath) + - "\" returned by the scraper seems to be invalid as it's less than " + - "350 bytes in size", - true); - return; - } - } - // Remove any existing media file before attempting to write a new one. // This avoids the problem where there's already a file for this media type // with a different format/extension (e.g. game.jpg and we're going to write @@ -764,6 +714,17 @@ std::string getSaveAsPath(const ScraperSearchParams& params, if (!Utils::FileSystem::exists(path)) Utils::FileSystem::createDirectory(path); +#if defined(__ANDROID__) + if (!Utils::FileSystem::exists(path + ".nomedia")) { + LOG(LogInfo) << "Creating \"no media\" file \"" << path + ".nomedia" + << "\"..."; + Utils::FileSystem::createEmptyFile(path + ".nomedia"); + if (!Utils::FileSystem::exists(path + ".nomedia")) { + LOG(LogWarning) << "Couldn't create file, permission problems?"; + } + } +#endif + path.append(systemsubdirectory) .append("/") .append(filetypeSubdirectory) diff --git a/es-app/src/scrapers/Scraper.h b/es-app/src/scrapers/Scraper.h index d0e105877..7bbaff637 100644 --- a/es-app/src/scrapers/Scraper.h +++ b/es-app/src/scrapers/Scraper.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scraper.h // // Main scraper logic. @@ -212,8 +212,8 @@ private: bool* mSavedNewMediaPtr; }; -// Downloads to the home directory, using this subdirectory structure: -// ".emulationstation/downloaded_media/[system_name]/[media_type]/[game_name].[file_extension]". +// Downloads media using this subdirectory structure: +// /downloaded_media///. // The subdirectories are automatically created if they do not exist. std::string getSaveAsPath(const ScraperSearchParams& params, const std::string& filetypeSubdirectory, diff --git a/es-app/src/scrapers/ScreenScraper.cpp b/es-app/src/scrapers/ScreenScraper.cpp index 19226591f..49403a01f 100644 --- a/es-app/src/scrapers/ScreenScraper.cpp +++ b/es-app/src/scrapers/ScreenScraper.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ScreenScraper.cpp // // Functions specifically for scraping from screenscraper.fr @@ -26,7 +26,7 @@ using namespace PlatformIds; namespace { // List of systems and their IDs from: - // https://www.screenscraper.fr/api/systemesListe.php?devid=xxx&devpassword=yyy&softname=zzz&output=XML + // https://api.screenscraper.fr/api/systemesListe.php?devid=xxx&devpassword=yyy&softname=zzz&output=XML const std::map screenscraper_platformid_map { {THREEDO, 29}, {ACORN_ELECTRON, 85}, @@ -397,6 +397,7 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, // Translate some HTML character codes to UTF-8 characters for the game name. gameName = Utils::String::replace(gameName, " ", " "); gameName = Utils::String::replace(gameName, "&", "&"); + gameName = Utils::String::replace(gameName, "'", "‘"); // In some very rare cases game names contain newline characters that we need to remove. result.mdl.set("name", Utils::String::replace(gameName, "\n", "")); @@ -453,6 +454,7 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, description = Utils::String::replace(description, """, "\""); description = Utils::String::replace(description, "©", "©"); description = Utils::String::replace(description, "'", "'"); + description = Utils::String::replace(description, "'", "'"); result.mdl.set("desc", description); } @@ -612,7 +614,6 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, // Media super-node. pugi::xml_node media_list {game.child("medias")}; - bool regionFallback {false}; if (media_list) { // 3D box. @@ -628,19 +629,28 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, processMedia(result, media_list, ssConfig.media_fanart, result.fanartUrl, result.fanartFormat, region); // Marquee (wheel). - regionFallback = processMedia(result, media_list, ssConfig.media_marquee, - result.marqueeUrl, result.marqueeFormat, region); - // Marquee HD (wheel-hd) fallback if no regular wheel image was found or if the - // image found was a fallback to another region than the one requested. If it was - // a fallback to another region then it will only get replaced with the wheel-hd - // image if that is matching the requested region. - if (regionFallback || result.marqueeUrl == "") { - std::string marqueeUrlTemp {result.marqueeUrl}; - if (processMedia(result, media_list, ssConfig.media_marquee_hd, result.marqueeUrl, - result.marqueeFormat, region) && - marqueeUrlTemp != "") { - result.marqueeUrl = marqueeUrlTemp; - } + // There are two media types for the marquee named "wheel" and "wheel"-hd that should + // be considered equivalent, i.e. the most closely matching region should be considered + // across both media types. This is a logical error, but as it's caused by an issue on + // the server side this workaround is still required. + int regionPosWheel {0}; + std::string fileURLWheel; + std::string fileFormatWheel; + regionPosWheel = processMedia(result, media_list, ssConfig.media_marquee, fileURLWheel, + fileFormatWheel, region); + int regionPosWheelHD {0}; + std::string fileURLWheelHD; + std::string fileFormatWheelHD; + regionPosWheelHD = processMedia(result, media_list, ssConfig.media_marquee_hd, + fileURLWheelHD, fileFormatWheelHD, region); + if ((regionPosWheelHD != 0 && regionPosWheelHD <= regionPosWheel) || + regionPosWheel == 0) { + result.marqueeUrl = fileURLWheelHD; + result.marqueeFormat = fileFormatWheelHD; + } + else { + result.marqueeUrl = fileURLWheel; + result.marqueeFormat = fileFormatWheel; } // Physical media. processMedia(result, media_list, ssConfig.media_physicalmedia, result.physicalmediaUrl, @@ -671,15 +681,15 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc, } } -bool ScreenScraperRequest::processMedia(ScraperSearchResult& result, - const pugi::xml_node& media_list, - std::string& mediaType, - std::string& fileURL, - std::string& fileFormat, - const std::string& region) +int ScreenScraperRequest::processMedia(ScraperSearchResult& result, + const pugi::xml_node& media_list, + std::string& mediaType, + std::string& fileURL, + std::string& fileFormat, + const std::string& region) { pugi::xml_node art {pugi::xml_node(nullptr)}; - bool regionFallback {false}; + int regionPos {0}; // Do an XPath query for media[type='$media_type'], then filter by region. // We need to do this because any child of 'medias' has the form @@ -710,11 +720,11 @@ bool ScreenScraperRequest::processMedia(ScraperSearchResult& result, if (art) break; + ++regionPos; + for (auto node : results) { if (node.node().attribute("region").value() == regionEntry) { art = node.node(); - if (region != regionEntry) - regionFallback = true; break; } } @@ -738,7 +748,7 @@ bool ScreenScraperRequest::processMedia(ScraperSearchResult& result, << mediaType << "\""; } - return regionFallback; + return regionPos; } std::string ScreenScraperRequest::ScreenScraperConfig::getGameSearchUrl(const std::string& gameName, diff --git a/es-app/src/scrapers/ScreenScraper.h b/es-app/src/scrapers/ScreenScraper.h index dc995cefd..77bdfa3e8 100644 --- a/es-app/src/scrapers/ScreenScraper.h +++ b/es-app/src/scrapers/ScreenScraper.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ScreenScraper.h // // Functions specifically for scraping from screenscraper.fr @@ -10,7 +10,7 @@ #ifndef ES_APP_SCRAPERS_SCREEN_SCRAPER_H #define ES_APP_SCRAPERS_SCREEN_SCRAPER_H -#include "EmulationStation.h" +#include "ApplicationVersion.h" #include "scrapers/Scraper.h" namespace pugi @@ -50,13 +50,15 @@ public: const std::string API_DEV_P = {32, 70, 46, 54, 12, 5, 13, 120, 50, 66, 25}; const std::string API_DEV_KEY = {67, 112, 72, 120, 121, 77, 119, 74, 84, 56, 75, 122, 78, 98, 69, 86, 56, 120, 120, 49}; - const std::string API_URL_BASE = "https://www.screenscraper.fr/api2"; + const std::string API_URL_BASE = "https://api.screenscraper.fr/api2"; #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) const std::string platformIdentifier {" B"}; #elif defined(STEAM_DECK) const std::string platformIdentifier {" S"}; #elif defined(RETRODECK) const std::string platformIdentifier {" R"}; +#elif defined(__ANDROID__) + const std::string platformIdentifier {" G"}; #elif defined(APPIMAGE_BUILD) const std::string platformIdentifier {" A"}; #elif defined(__linux__) && defined(RASPBERRY_PI) @@ -70,9 +72,8 @@ public: #else const std::string platformIdentifier {" O"}; #endif - const std::string API_SOFT_NAME = "EmulationStation-DE " + - static_cast(PROGRAM_VERSION_STRING) + - platformIdentifier; + const std::string API_SOFT_NAME = + "ES-DE " + static_cast(PROGRAM_VERSION_STRING) + platformIdentifier; // Which type of image artwork we need. Possible values (not a comprehensive list): // - ss: in-game screenshot @@ -122,12 +123,12 @@ protected: std::vector& results) override; void processGame(const pugi::xml_document& xmldoc, std::vector& results); - bool processMedia(ScraperSearchResult& result, - const pugi::xml_node& media_list, - std::string& mediaType, - std::string& fileURL, - std::string& fileFormat, - const std::string& region); + int processMedia(ScraperSearchResult& result, + const pugi::xml_node& media_list, + std::string& mediaType, + std::string& fileURL, + std::string& fileFormat, + const std::string& region); bool isGameRequest() { return !mRequestQueue; } std::queue>* mRequestQueue; diff --git a/es-app/src/views/GamelistBase.cpp b/es-app/src/views/GamelistBase.cpp index 980a252f1..caf575399 100644 --- a/es-app/src/views/GamelistBase.cpp +++ b/es-app/src/views/GamelistBase.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistBase.cpp // // Gamelist base class with utility functions and other low-level logic. diff --git a/es-app/src/views/GamelistBase.h b/es-app/src/views/GamelistBase.h index 7453f89fa..be559f6ae 100644 --- a/es-app/src/views/GamelistBase.h +++ b/es-app/src/views/GamelistBase.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistBase.h // // Gamelist base class with utility functions and other low-level logic. diff --git a/es-app/src/views/GamelistView.cpp b/es-app/src/views/GamelistView.cpp index fe7d22ae7..aa39b1ff2 100644 --- a/es-app/src/views/GamelistView.cpp +++ b/es-app/src/views/GamelistView.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistView.cpp // // Main gamelist logic. @@ -416,6 +416,22 @@ void GamelistView::render(const glm::mat4& parentTrans) const ViewController::State viewState {ViewController::getInstance()->getState()}; bool stationaryApplicable {false}; + auto renderChildCondFunc = [this, &viewState](int i, glm::mat4 trans) { + bool renderChild {false}; + if (!ViewController::getInstance()->isCameraMoving()) + renderChild = true; + else if (viewState.previouslyViewed == ViewController::ViewMode::NOTHING) + renderChild = true; + else if (viewState.viewing == viewState.previouslyViewed) + renderChild = true; + else if (static_cast(Settings::getInstance()->getInt( + "TransitionsGamelistToSystem")) != ViewTransitionAnimation::SLIDE && + viewState.viewing == ViewController::ViewMode::SYSTEM_SELECT) + renderChild = true; + if (renderChild) + getChild(i)->render(trans); + }; + // If it's the startup animation, then don't apply stationary properties. if (viewState.previouslyViewed == ViewController::ViewMode::NOTHING) stationaryApplicable = false; @@ -467,11 +483,17 @@ void GamelistView::render(const glm::mat4& parentTrans) if (viewState.getSystem() != mRoot->getSystem()) continue; mRenderer->popClipRect(); - getChild(i)->render(mRenderer->getIdentity()); + if (getChild(i)->getRenderDuringTransitions()) + getChild(i)->render(mRenderer->getIdentity()); + else + renderChildCondFunc(i, mRenderer->getIdentity()); clipRectFunc(); } else { - getChild(i)->render(trans); + if (getChild(i)->getRenderDuringTransitions()) + getChild(i)->render(trans); + else + renderChildCondFunc(i, trans); } } @@ -977,7 +999,7 @@ void GamelistView::updateView(const CursorState& state) file->getPath() == file->getSystem()->getName()) && (metadata == "systemName" || metadata == "systemFullname" || metadata == "sourceSystemName" || metadata == "sourceSystemFullname")) { - text->setValue(""); + text->setValue(text->getDefaultValue()); continue; } diff --git a/es-app/src/views/GamelistView.h b/es-app/src/views/GamelistView.h index 44f28a68d..1d580028d 100644 --- a/es-app/src/views/GamelistView.h +++ b/es-app/src/views/GamelistView.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamelistView.h // // Main gamelist logic. @@ -56,6 +56,13 @@ public: for (auto& video : mStaticVideoComponents) video->muteVideoPlayer(); } + void resetViewVideosTimer() override + { + for (auto& video : mVideoComponents) + video->resetVideoPlayerTimer(); + for (auto& video : mStaticVideoComponents) + video->resetVideoPlayerTimer(); + } void stopGamelistFadeAnimations() override { diff --git a/es-app/src/views/SystemView.cpp b/es-app/src/views/SystemView.cpp index dee557371..52a26ae97 100644 --- a/es-app/src/views/SystemView.cpp +++ b/es-app/src/views/SystemView.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemView.cpp // // Main system view. @@ -839,7 +839,7 @@ void SystemView::updateGameCount(SystemData* system) else { ss << gameCount.first << " Game" << (gameCount.first == 1 ? " " : "s ") << "(" << gameCount.second << " Favorite" << (gameCount.second == 1 ? ")" : "s)"); - ssGames << gameCount.first << " Game" << (gameCount.first == 1 ? " " : "s "); + ssGames << gameCount.first << " Game" << (gameCount.first == 1 ? "" : "s"); ssFavorites << gameCount.second << " Favorite" << (gameCount.second == 1 ? "" : "s"); games = true; } @@ -1434,7 +1434,8 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary) // If it's a gamelist to system transition and these animations are set to slide. if (static_cast(Settings::getInstance()->getInt( "TransitionsGamelistToSystem")) == ViewTransitionAnimation::SLIDE && - viewState.previouslyViewed == ViewController::ViewMode::GAMELIST) + viewState.previouslyViewed == ViewController::ViewMode::GAMELIST && + ViewController::getInstance()->isCameraMoving()) stationaryApplicable = true; for (int i {renderBefore}; i <= renderAfter; ++i) { @@ -1475,10 +1476,26 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary) glm::ivec2 {static_cast(mSize.x), static_cast(mSize.y)}); }; + auto renderChildCondFunc = [&viewState](GuiComponent* child, glm::mat4 trans) { + bool renderChild {false}; + if (!ViewController::getInstance()->isCameraMoving()) + renderChild = true; + else if (viewState.previouslyViewed == ViewController::ViewMode::NOTHING) + renderChild = true; + else if (viewState.viewing == viewState.previouslyViewed) + renderChild = true; + else if (static_cast(Settings::getInstance()->getInt( + "TransitionsSystemToGamelist")) != ViewTransitionAnimation::SLIDE && + viewState.viewing == ViewController::ViewMode::GAMELIST) + renderChild = true; + if (renderChild) + child->render(trans); + }; + clipRectFunc(); if (mSystemElements.size() > static_cast(index)) { - for (auto child : mSystemElements[index].children) { + for (GuiComponent* child : mSystemElements[index].children) { bool renderChild {true}; bool childStationary {false}; if (stationaryApplicable) { @@ -1519,11 +1536,17 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary) if (renderChild) { if (childStationary) { mRenderer->popClipRect(); - child->render(mRenderer->getIdentity()); + if (child->getRenderDuringTransitions()) + child->render(mRenderer->getIdentity()); + else + renderChildCondFunc(child, mRenderer->getIdentity()); clipRectFunc(); } else { - child->render(elementTrans); + if (child->getRenderDuringTransitions()) + child->render(elementTrans); + else + renderChildCondFunc(child, elementTrans); } } } @@ -1533,11 +1556,17 @@ void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary) if (renderChild) { if (childStationary) { mRenderer->popClipRect(); - child->render(mRenderer->getIdentity()); + if (child->getRenderDuringTransitions()) + child->render(mRenderer->getIdentity()); + else + renderChildCondFunc(child, mRenderer->getIdentity()); clipRectFunc(); } else { - child->render(elementTrans); + if (child->getRenderDuringTransitions()) + child->render(elementTrans); + else + renderChildCondFunc(child, elementTrans); } } } diff --git a/es-app/src/views/SystemView.h b/es-app/src/views/SystemView.h index e6331cdbc..9b27f5c91 100644 --- a/es-app/src/views/SystemView.h +++ b/es-app/src/views/SystemView.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemView.h // // Main system view. @@ -94,6 +94,11 @@ public: for (auto& video : mSystemElements[mPrimary->getCursor()].videoComponents) video->muteVideoPlayer(); } + void resetViewVideosTimer() override + { + for (auto& video : mSystemElements[mPrimary->getCursor()].videoComponents) + video->resetVideoPlayerTimer(); + } void onThemeChanged(const std::shared_ptr& theme); diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 68458d7d6..b9829679f 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ViewController.cpp // // Handles overall system navigation including animations and transitions. @@ -137,6 +137,41 @@ void ViewController::setMenuColors() } } +void ViewController::legacyAppDataDialog() +{ + const std::string upgradeMessage { + "AS OF ES-DE 3.0 THE APPLICATION DATA DIRECTORY HAS CHANGED FROM \".emulationstation\" " + "to \"ES-DE\"\nPLEASE RENAME YOUR CURRENT DATA DIRECTORY:\n" + + Utils::FileSystem::getAppDataDirectory() + "\nTO THE FOLLOWING:\n" + + Utils::FileSystem::getParent(Utils::FileSystem::getAppDataDirectory()) + "/ES-DE"}; + + mWindow->pushGui(new GuiMsgBox( + HelpStyle(), upgradeMessage.c_str(), "OK", [] {}, "", nullptr, "", nullptr, nullptr, true, + true, + (mRenderer->getIsVerticalOrientation() ? + 0.85f : + 0.55f * (1.778f / mRenderer->getScreenAspectRatio())))); +} + +void ViewController::migratedAppDataFilesDialog() +{ + const std::string message {"SETTINGS HAVE BEEN MIGRATED FROM A LEGACY APPLICATION DATA " + "DIRECTORY STRUCTURE, YOU NEED TO RESTART ES-DE TO APPLY " + "THE CONFIGURATION"}; + + mWindow->pushGui(new GuiMsgBox( + HelpStyle(), message.c_str(), "QUIT", + [] { + SDL_Event quit {}; + quit.type = SDL_QUIT; + SDL_PushEvent(&quit); + }, + "", nullptr, "", nullptr, nullptr, true, true, + (mRenderer->getIsVerticalOrientation() ? + 0.65f : + 0.55f * (1.778f / mRenderer->getScreenAspectRatio())))); +} + void ViewController::unsafeUpgradeDialog() { const std::string upgradeMessage { @@ -144,8 +179,8 @@ void ViewController::unsafeUpgradeDialog() "UNPACKING THE NEW RELEASE ON TOP OF THE OLD ONE? THIS MAY CAUSE " "VARIOUS PROBLEMS, SOME OF WHICH MAY NOT BE APPARENT IMMEDIATELY. " "MAKE SURE TO ALWAYS FOLLOW THE UPGRADE INSTRUCTIONS IN THE " - "README.TXT FILE THAT CAN BE FOUND IN THE EMULATIONSTATION-DE " - "DIRECTORY."}; + "README.TXT FILE THAT CAN BE FOUND IN THE ES-DE DIRECTORY."}; + mWindow->pushGui(new GuiMsgBox( HelpStyle(), upgradeMessage.c_str(), "OK", [] {}, "", nullptr, "", nullptr, nullptr, true, true, @@ -160,13 +195,13 @@ void ViewController::invalidSystemsFileDialog() "IF YOU HAVE A CUSTOMIZED es_systems.xml FILE, THEN " "SOMETHING IS LIKELY WRONG WITH YOUR XML SYNTAX. " "IF YOU DON'T HAVE A CUSTOM SYSTEMS FILE, THEN THE " - "EMULATIONSTATION INSTALLATION IS BROKEN. SEE THE " - "APPLICATION LOG FILE es_log.txt FOR ADDITIONAL INFO"}; + "ES-DE INSTALLATION IS BROKEN. SEE THE APPLICATION " + "LOG FILE es_log.txt FOR ADDITIONAL INFO"}; mWindow->pushGui(new GuiMsgBox( HelpStyle(), errorMessage.c_str(), "QUIT", [] { - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); }, @@ -178,6 +213,14 @@ void ViewController::invalidSystemsFileDialog() void ViewController::noGamesDialog() { +#if defined(__ANDROID__) + mNoGamesErrorMessage = "NO GAME FILES WERE FOUND, PLEASE PLACE YOUR GAMES IN " + "THE CONFIGURED ROM DIRECTORY. OPTIONALLY THE ROM " + "DIRECTORY STRUCTURE CAN BE GENERATED WHICH WILL " + "CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING SOME " + "INFORMATION SUCH AS THE SUPPORTED FILE EXTENSIONS.\n" + "THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n"; +#else mNoGamesErrorMessage = "NO GAME FILES WERE FOUND. EITHER PLACE YOUR GAMES IN " "THE CURRENTLY CONFIGURED ROM DIRECTORY OR CHANGE " "ITS PATH USING THE BUTTON BELOW. OPTIONALLY THE ROM " @@ -185,6 +228,7 @@ void ViewController::noGamesDialog() "CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING SOME " "INFORMATION SUCH AS THE SUPPORTED FILE EXTENSIONS.\n" "THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n"; +#endif #if defined(_WIN64) mRomDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\"); @@ -192,10 +236,14 @@ void ViewController::noGamesDialog() mRomDirectory = FileData::getROMDirectory(); #endif +#if defined(__ANDROID__) + mNoGamesMessageBox = new GuiMsgBox( + HelpStyle(), mNoGamesErrorMessage + mRomDirectory, +#else mNoGamesMessageBox = new GuiMsgBox( HelpStyle(), mNoGamesErrorMessage + mRomDirectory, "QUIT", [] { - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); }, @@ -203,6 +251,7 @@ void ViewController::noGamesDialog() (mRenderer->getIsVerticalOrientation() ? 0.90f : 0.62f * (1.778f / mRenderer->getScreenAspectRatio()))); +#endif mWindow->pushGui(mNoGamesMessageBox); } @@ -986,7 +1035,10 @@ bool ViewController::input(InputConfig* config, Input input) // If we're in this state and then register some input, it means that the user is back in ES-DE. // Therefore unset the game launch flag and update all the GUI components. This will re-enable // the video player and scrolling of game names and game descriptions as well as letting the - // screensaver start on schedule. + // screensaver start on schedule. On Android the onResume() method will call the native onResume + // function which will perform the same steps as shown below (on Android we always keep running + // when launching games). +#if !defined(__ANDROID__) if (mWindow->getGameLaunchedState()) { mWindow->setAllowTextScrolling(true); mWindow->setAllowFileAnimation(true); @@ -996,13 +1048,14 @@ bool ViewController::input(InputConfig* config, Input input) if (config->isMappedTo("a", input) && input.value != 0) return true; // Trigger the game-end event. - if (mGameEndEventParams.size() == 5) { - Scripting::fireEvent(mGameEndEventParams[0], mGameEndEventParams[1], - mGameEndEventParams[2], mGameEndEventParams[3], - mGameEndEventParams[4]); - mGameEndEventParams.clear(); + auto& eventParams = mWindow->getGameEndEventParams(); + if (eventParams.size() == 5) { + Scripting::fireEvent(eventParams[0], eventParams[1], eventParams[2], eventParams[3], + eventParams[4]); + eventParams.clear(); } } +#endif // Open the main menu. if (!(UIModeController::getInstance()->isUIModeKid() && @@ -1335,7 +1388,7 @@ void ViewController::rescanROMDirectory() SystemData::loadConfig(); if (SystemData::sStartupExitSignal) { - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); return; @@ -1350,7 +1403,7 @@ void ViewController::rescanROMDirectory() else { preload(); if (SystemData::sStartupExitSignal) { - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); return; diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 125ae9ad6..68845b9b7 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ViewController.h // // Handles overall system navigation including animations and transitions. @@ -34,6 +34,8 @@ public: // These functions are called from main(). void setMenuColors(); + void legacyAppDataDialog(); + void migratedAppDataFilesDialog(); void unsafeUpgradeDialog(); void invalidSystemsFileDialog(); void noGamesDialog(); @@ -83,6 +85,8 @@ public: void stopViewVideos() override { mCurrentView->stopViewVideos(); } void pauseViewVideos() override { mCurrentView->pauseViewVideos(); } void muteViewVideos() override { mCurrentView->muteViewVideos(); } + // Needed on Android to reset the static image delay timer on activity resume. + void resetViewVideosTimer() override { mCurrentView->resetViewVideosTimer(); } void onFileChanged(FileData* file, bool reloadGamelist); void triggerGameLaunch(FileData* game) @@ -91,7 +95,6 @@ public: mWindow->setBlockInput(true); }; const bool getGameLaunchTriggered() { return (mGameToLaunch != nullptr); } - std::vector& getGameEndEventParams() { return mGameEndEventParams; } bool input(InputConfig* config, Input input) override; void update(int deltaTime) override; @@ -182,7 +185,6 @@ private: std::shared_ptr mSystemListView; ViewTransitionAnimation mLastTransitionAnim; - std::vector mGameEndEventParams; FileData* mGameToLaunch; State mState; diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 91c91604a..592222d51 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt (es-core) # # CMake configuration for es-core @@ -169,9 +169,26 @@ set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/TimeUtil.cpp ) +if(ANDROID) + set(CORE_HEADERS ${CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/src/InputOverlay.h) + set(CORE_HEADERS ${CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/PlatformUtilAndroid.h) + set(CORE_HEADERS ${CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/src/InputOverlay.cpp) + set(CORE_SOURCES ${CORE_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src/utils/PlatformUtilAndroid.cpp) +endif() + #--------------------------------------------------------------------------------------------------- # Miscellaneous configuration. include_directories(${COMMON_INCLUDE_DIRS}) add_library(es-core STATIC ${CORE_SOURCES} ${CORE_HEADERS}) target_link_libraries(es-core ${COMMON_LIBRARIES}) + +if(ANDROID) + if(ANDROID_LITE_RELEASE) + set_target_properties(es-core PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/../android_lite_${ANDROID_ABI}) + else() + set_target_properties(es-core PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/../android_${ANDROID_ABI}) + endif() +endif() diff --git a/es-core/src/AsyncHandle.h b/es-core/src/AsyncHandle.h index 1b4c57349..e17aa1ce7 100644 --- a/es-core/src/AsyncHandle.h +++ b/es-core/src/AsyncHandle.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AsyncHandle.h // // Asynchronous operations used by GuiScraperSearch and Scraper. diff --git a/es-core/src/AudioManager.cpp b/es-core/src/AudioManager.cpp index bfe69108e..0cf5d023e 100644 --- a/es-core/src/AudioManager.cpp +++ b/es-core/src/AudioManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AudioManager.cpp // // Low-level audio functions (using SDL2). diff --git a/es-core/src/AudioManager.h b/es-core/src/AudioManager.h index d14b3b2a7..d274eb095 100644 --- a/es-core/src/AudioManager.h +++ b/es-core/src/AudioManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AudioManager.h // // Low-level audio functions (using SDL2). diff --git a/es-core/src/CECInput.cpp b/es-core/src/CECInput.cpp index 8a2e2d50a..fc4fdfe8b 100644 --- a/es-core/src/CECInput.cpp +++ b/es-core/src/CECInput.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CECInput.cpp // // CEC (Consumer Electronics Control) input. @@ -48,7 +48,7 @@ static void onKeyPress(void* /*cbParam*/, const CEC::cec_keypress* key) { LOG(LogDebug) << "CECInput::onKeyPress keycode: " << CECInput::getKeyCodeString(key->keycode); - SDL_Event event; + SDL_Event event {}; event.type = (key->duration > 0) ? SDL_USER_CECBUTTONUP : SDL_USER_CECBUTTONDOWN; event.user.code = key->keycode; SDL_PushEvent(&event); diff --git a/es-core/src/CECInput.h b/es-core/src/CECInput.h index fbfaf3e3e..ab9643990 100644 --- a/es-core/src/CECInput.h +++ b/es-core/src/CECInput.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CECInput.h // // CEC (Consumer Electronics Control) input. diff --git a/es-core/src/GuiComponent.cpp b/es-core/src/GuiComponent.cpp index d21707f15..6f36be539 100644 --- a/es-core/src/GuiComponent.cpp +++ b/es-core/src/GuiComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiComponent.cpp // // Basic GUI component handling such as placement, rotation, Z-order, rendering and animation. @@ -31,6 +31,7 @@ GuiComponent::GuiComponent() , mRotationOrigin {0.5f, 0.5f} , mSize {0.0f, 0.0f} , mStationary {Stationary::NEVER} + , mRenderDuringTransitions {true} , mBrightness {0.0f} , mOpacity {1.0f} , mSaturation {1.0f} diff --git a/es-core/src/GuiComponent.h b/es-core/src/GuiComponent.h index 758229c49..26638e0f0 100644 --- a/es-core/src/GuiComponent.h +++ b/es-core/src/GuiComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiComponent.h // // Basic GUI component handling such as placement, rotation, Z-order, rendering and animation. @@ -117,6 +117,7 @@ public: void setRotationOrigin(glm::vec2 origin) { setRotationOrigin(origin.x, origin.y); } const Stationary getStationary() const { return mStationary; } + const bool getRenderDuringTransitions() const { return mRenderDuringTransitions; } virtual glm::vec2 getSize() const { return mSize; } void setSize(const glm::vec2& size) { setSize(size.x, size.y); } @@ -309,6 +310,8 @@ public: virtual void stopViewVideos() {} virtual void pauseViewVideos() {} virtual void muteViewVideos() {} + // Needed on Android to reset the static image delay timer on activity resume. + virtual void resetViewVideosTimer() {} // Used to reset various components like text scrolling, animations etc. virtual void resetComponent() {} @@ -400,6 +403,7 @@ protected: glm::vec2 mRotationOrigin; glm::vec2 mSize; Stationary mStationary; + bool mRenderDuringTransitions; float mBrightness; float mOpacity; diff --git a/es-core/src/HelpPrompt.h b/es-core/src/HelpPrompt.h index d7f3c60b2..8188da2cc 100644 --- a/es-core/src/HelpPrompt.h +++ b/es-core/src/HelpPrompt.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HelpPrompt.h // // Definition of the pair used by help prompts to display an icon and its mapped function. diff --git a/es-core/src/HelpStyle.cpp b/es-core/src/HelpStyle.cpp index 018ada998..eb0cba977 100644 --- a/es-core/src/HelpStyle.cpp +++ b/es-core/src/HelpStyle.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HelpStyle.cpp // // Style (colors, position, icons etc.) for the help system. diff --git a/es-core/src/HelpStyle.h b/es-core/src/HelpStyle.h index 54b8f34b7..39f37a5ee 100644 --- a/es-core/src/HelpStyle.h +++ b/es-core/src/HelpStyle.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HelpStyle.h // // Style (colors, position, icons etc.) for the help system. diff --git a/es-core/src/HttpReq.cpp b/es-core/src/HttpReq.cpp index 53d553f9a..691e640bd 100644 --- a/es-core/src/HttpReq.cpp +++ b/es-core/src/HttpReq.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HttpReq.cpp // // HTTP requests using libcurl. @@ -41,6 +41,7 @@ HttpReq::HttpReq(const std::string& url, bool scraperRequest) , mHandle(nullptr) , mTotalBytes {0} , mDownloadedBytes {0} + , mScraperRequest {scraperRequest} { // The multi-handle is cleaned up via a call from GuiScraperSearch after the scraping // has been completed for a game, meaning the handle is valid for all curl requests @@ -81,7 +82,7 @@ HttpReq::HttpReq(const std::string& url, bool scraperRequest) long connectionTimeout; - if (scraperRequest) { + if (mScraperRequest) { connectionTimeout = static_cast(Settings::getInstance()->getInt("ScraperConnectionTimeout")); @@ -103,7 +104,7 @@ HttpReq::HttpReq(const std::string& url, bool scraperRequest) long transferTimeout; - if (scraperRequest) { + if (mScraperRequest) { transferTimeout = static_cast(Settings::getInstance()->getInt("ScraperTransferTimeout")); @@ -194,6 +195,14 @@ HttpReq::HttpReq(const std::string& url, bool scraperRequest) return; } + // Fail on HTTP status codes >= 400. + err = curl_easy_setopt(mHandle, CURLOPT_FAILONERROR, 1L); + if (err != CURLE_OK) { + mStatus = REQ_IO_ERROR; + onError(curl_easy_strerror(err)); + return; + } + // Add the handle to our multi. CURLMcode merr {curl_multi_add_handle(sMultiHandle, mHandle)}; if (merr != CURLM_OK) { @@ -250,6 +259,20 @@ HttpReq::Status HttpReq::status() req->mStatus = REQ_FAILED_VERIFICATION; req->onError(curl_easy_strerror(msg->data.result)); } + else if (msg->data.result == CURLE_HTTP_RETURNED_ERROR) { + long responseCode; + curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &responseCode); + + if (responseCode == 404 && mScraperRequest && + Settings::getInstance()->getBool("ScraperIgnoreHTTP404Errors")) { + req->mStatus = REQ_RESOURCE_NOT_FOUND; + } + else { + req->onError("Server returned HTTP error code " + + std::to_string(responseCode)); + req->mStatus = REQ_BAD_STATUS_CODE; + } + } else { req->mStatus = REQ_IO_ERROR; req->onError(curl_easy_strerror(msg->data.result)); diff --git a/es-core/src/HttpReq.h b/es-core/src/HttpReq.h index 30adad51c..0de59915a 100644 --- a/es-core/src/HttpReq.h +++ b/es-core/src/HttpReq.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HttpReq.h // // HTTP requests using libcurl. @@ -25,10 +25,11 @@ public: enum Status { // clang-format off REQ_IN_PROGRESS, // Request is in progress. - REQ_SUCCESS, // Request completed successfully, get it with getContent(). - REQ_IO_ERROR, // Some error happened, get it with getErrorMsg(). + REQ_SUCCESS, // Request completed successfully. + REQ_IO_ERROR, // An error occured. REQ_FAILED_VERIFICATION, // Peer's certificate or fingerprint wasn't verified correctly. - REQ_BAD_STATUS_CODE, // Some invalid HTTP response status code happened (non-200). + REQ_BAD_STATUS_CODE, // HTTP error response >= 400. + REQ_RESOURCE_NOT_FOUND, // HTTP error code 404 specifically. REQ_INVALID_RESPONSE, // The HTTP response was invalid. REQ_UNDEFINED_ERROR // clang-format on @@ -69,6 +70,7 @@ private: std::string mErrorMsg; std::atomic mTotalBytes; std::atomic mDownloadedBytes; + bool mScraperRequest; }; #endif // ES_CORE_HTTP_REQ_H diff --git a/es-core/src/ImageIO.cpp b/es-core/src/ImageIO.cpp index aa9ae36f5..6be6e60ca 100644 --- a/es-core/src/ImageIO.cpp +++ b/es-core/src/ImageIO.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ImageIO.cpp // // Image I/O functions. diff --git a/es-core/src/ImageIO.h b/es-core/src/ImageIO.h index 3fd62e267..dc83de247 100644 --- a/es-core/src/ImageIO.h +++ b/es-core/src/ImageIO.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ImageIO.h // // Image I/O functions. diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index 5959162a6..e15523729 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputConfig.cpp // // Input device configuration functions. @@ -9,6 +9,7 @@ #include "InputConfig.h" #include "Log.h" +#include "Settings.h" #include @@ -28,6 +29,8 @@ std::string InputConfig::inputTypeToString(InputType type) return "button"; case TYPE_KEY: return "key"; + case TYPE_TOUCH: + return "touch-button"; case TYPE_CEC_BUTTON: return "cec-button"; default: @@ -43,6 +46,8 @@ InputType InputConfig::stringToInputType(const std::string& type) return TYPE_BUTTON; if (type == "key") return TYPE_KEY; + if (type == "touch-button") + return TYPE_TOUCH; if (type == "cec-button") return TYPE_CEC_BUTTON; return TYPE_COUNT; @@ -50,7 +55,7 @@ InputType InputConfig::stringToInputType(const std::string& type) std::string InputConfig::toLower(std::string str) { - for (unsigned int i = 0; i < str.length(); ++i) + for (unsigned int i {0}; i < str.length(); ++i) str[i] = static_cast(tolower(str[i])); return str; @@ -121,7 +126,7 @@ std::vector InputConfig::getMappedTo(Input input) std::vector maps; for (auto it = mNameMap.cbegin(); it != mNameMap.cend(); ++it) { - Input chk = it->second; + Input chk {it->second}; if (!chk.configured) continue; @@ -141,7 +146,20 @@ std::vector InputConfig::getMappedTo(Input input) bool InputConfig::getInputByName(const std::string& name, Input* result) { - auto it = mNameMap.find(toLower(name)); + std::string nameInput {name}; + + if (Settings::getInstance()->getBool("InputSwapButtons") && mDeviceId != DEVICE_KEYBOARD) { + if (name == "a") + nameInput = "b"; + else if (name == "b") + nameInput = "a"; + else if (name == "x") + nameInput = "y"; + else if (name == "y") + nameInput = "x"; + } + + auto it = mNameMap.find(toLower(nameInput)); if (it != mNameMap.cend()) { *result = it->second; return true; @@ -162,10 +180,10 @@ void InputConfig::loadFromXML(pugi::xml_node& node) { clear(); - for (pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) { - std::string name = input.attribute("name").as_string(); - std::string type = input.attribute("type").as_string(); - InputType typeEnum = stringToInputType(type); + for (pugi::xml_node input {node.child("input")}; input; input = input.next_sibling("input")) { + std::string name {input.attribute("name").as_string()}; + std::string type {input.attribute("type").as_string()}; + InputType typeEnum {stringToInputType(type)}; if (typeEnum == TYPE_COUNT) { LOG(LogError) << "InputConfig load error - input of type \"" << type @@ -173,8 +191,8 @@ void InputConfig::loadFromXML(pugi::xml_node& node) continue; } - int id = input.attribute("id").as_int(); - int value = input.attribute("value").as_int(); + int id {input.attribute("id").as_int()}; + int value {input.attribute("value").as_int()}; if (value == 0) { LOG(LogWarning) << "InputConfig value is 0 for " << type << " " << id << "!\n"; @@ -186,7 +204,7 @@ void InputConfig::loadFromXML(pugi::xml_node& node) void InputConfig::writeToXML(pugi::xml_node& parent) { - pugi::xml_node cfg = parent.append_child("inputConfig"); + pugi::xml_node cfg {parent.append_child("inputConfig")}; if (mDeviceId == DEVICE_KEYBOARD) { cfg.append_attribute("type") = "keyboard"; @@ -207,7 +225,7 @@ void InputConfig::writeToXML(pugi::xml_node& parent) if (!it->second.configured) continue; - pugi::xml_node input = cfg.append_child("input"); + pugi::xml_node input {cfg.append_child("input")}; input.append_attribute("name") = it->first.c_str(); input.append_attribute("type") = inputTypeToString(it->second.type).c_str(); input.append_attribute("id").set_value(it->second.id); diff --git a/es-core/src/InputConfig.h b/es-core/src/InputConfig.h index df34b11dd..10899f246 100644 --- a/es-core/src/InputConfig.h +++ b/es-core/src/InputConfig.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputConfig.h // // Input device configuration functions. @@ -18,11 +18,13 @@ #define DEVICE_KEYBOARD -1 #define DEVICE_CEC -2 +#define DEVICE_TOUCH -3 enum InputType { TYPE_AXIS, TYPE_BUTTON, TYPE_KEY, + TYPE_TOUCH, TYPE_CEC_BUTTON, TYPE_COUNT }; @@ -81,6 +83,10 @@ public: stream << "Key " << SDL_GetKeyName((SDL_Keycode)id); break; } + case TYPE_TOUCH: { + stream << "Button " << id; + break; + } case TYPE_CEC_BUTTON: { stream << "CEC-Button " << getCECButtonName(id); break; diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index ef18b33dc..8a9d947ff 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputManager.cpp // // Low-level input handling. @@ -24,6 +24,10 @@ #define KEYBOARD_GUID_STRING "-1" #define CEC_GUID_STRING "-2" +#if defined(__ANDROID__) +#define TOUCH_GUID_STRING "-3" +#endif + namespace { int SDL_USER_CECBUTTONDOWN {-1}; @@ -32,7 +36,12 @@ namespace InputManager::InputManager() noexcept : mWindow {Window::getInstance()} +#if defined(__ANDROID__) + , mInputOverlay {InputOverlay::getInstance()} +#endif , mKeyboardInputConfig {nullptr} + , mTouchInputConfig {nullptr} + , mCECInputConfig {nullptr} { } @@ -81,13 +90,25 @@ void InputManager::init() LOG(LogInfo) << "Added keyboard with default configuration"; } +#if defined(__ANDROID__) + mTouchInputConfig = std::make_unique(DEVICE_TOUCH, "Touch", TOUCH_GUID_STRING); + loadTouchConfig(); +#endif + // Load optional controller mappings. Normally the supported controllers should be compiled // into SDL as a header file, but if a user has a very rare controller that is not supported, // the bundled mapping is incorrect, or the SDL version is a bit older, it makes sense to be // able to customize this. If a controller GUID is present in the mappings file that is // already present inside SDL, the custom mapping will overwrite the bundled one. - std::string mappingsFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" + - "es_controller_mappings.cfg"}; + std::string mappingsFile; + + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) { + mappingsFile = Utils::FileSystem::getAppDataDirectory() + "/es_controller_mappings.cfg"; + } + else { + mappingsFile = + Utils::FileSystem::getAppDataDirectory() + "/controllers/es_controller_mappings.cfg"; + } if (!Utils::FileSystem::exists(mappingsFile)) mappingsFile = ResourceManager::getInstance().getResourcePath( @@ -103,12 +124,10 @@ void InputManager::init() int numJoysticks {SDL_NumJoysticks()}; // Make sure that every joystick is actually supported by the GameController API. - for (int i {0}; i < numJoysticks; ++i) - if (!SDL_IsGameController(i)) - --numJoysticks; - - for (int i {0}; i < numJoysticks; ++i) - addControllerByDeviceIndex(nullptr, i); + for (int i {0}; i < numJoysticks; ++i) { + if (SDL_IsGameController(i)) + addControllerByDeviceIndex(nullptr, i); + } SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2); SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1; @@ -131,6 +150,7 @@ void InputManager::deinit() mInputConfigs.clear(); mKeyboardInputConfig.reset(); + mTouchInputConfig.reset(); mCECInputConfig.reset(); SDL_GameControllerEventState(SDL_DISABLE); @@ -255,16 +275,18 @@ void InputManager::doOnFinish() std::string InputManager::getConfigPath() { - std::string path {Utils::FileSystem::getHomePath()}; - path.append("/.emulationstation/es_input.xml"); - return path; + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + return Utils::FileSystem::getAppDataDirectory() + "/es_input.xml"; + else + return Utils::FileSystem::getAppDataDirectory() + "/settings/es_input.xml"; } std::string InputManager::getTemporaryConfigPath() { - std::string path {Utils::FileSystem::getHomePath()}; - path.append("/.emulationstation/es_temporaryinput.xml"); - return path; + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + return Utils::FileSystem::getAppDataDirectory() + "/es_temporaryinput.xml"; + else + return Utils::FileSystem::getAppDataDirectory() + "/settings/es_temporaryinput.xml"; } int InputManager::getNumConfiguredDevices() @@ -277,6 +299,11 @@ int InputManager::getNumConfiguredDevices() if (mKeyboardInputConfig->isConfigured()) ++num; +#if defined(__ANDROID__) + if (mTouchInputConfig->isConfigured()) + ++num; +#endif + if (mCECInputConfig->isConfigured()) ++num; @@ -306,8 +333,11 @@ std::string InputManager::getDeviceGUIDString(int deviceId) { if (deviceId == DEVICE_KEYBOARD) return KEYBOARD_GUID_STRING; - - if (deviceId == DEVICE_CEC) +#if defined(__ANDROID__) + else if (deviceId == DEVICE_TOUCH) + return TOUCH_GUID_STRING; +#endif + else if (deviceId == DEVICE_CEC) return CEC_GUID_STRING; auto it = mJoysticks.find(deviceId); @@ -326,6 +356,10 @@ InputConfig* InputManager::getInputConfigByDevice(int device) { if (device == DEVICE_KEYBOARD) return mKeyboardInputConfig.get(); +#if defined(__ANDROID__) + else if (device == DEVICE_TOUCH) + return mTouchInputConfig.get(); +#endif else if (device == DEVICE_CEC) return mCECInputConfig.get(); else @@ -442,17 +476,36 @@ bool InputManager::parseEvent(const SDL_Event& event) if (event.key.repeat) return false; +#if defined(__ANDROID__) + // Quit application if the back button is pressed. + if (event.key.keysym.sym == SDLK_AC_BACK) { + SDL_Event quit {}; + quit.type = SDL_QUIT; + SDL_PushEvent(&quit); + return false; + } +#endif // There is no need to handle the OS-default quit shortcut (Alt + F4 on Windows and // Linux and Command + Q on macOS) as that's taken care of by the window manager. + // The exception is Android as there are are no default quit shortcuts on this OS. std::string quitShortcut {Settings::getInstance()->getString("KeyboardQuitShortcut")}; #if defined(__APPLE__) if (quitShortcut != "CmdQ") { +#elif defined(__ANDROID__) + if (true) { #else if (quitShortcut != "AltF4") { #endif bool quitES {false}; +#if defined(__ANDROID__) + if (quitShortcut == "AltF4" && event.key.keysym.sym == SDLK_F4 && + (event.key.keysym.mod & KMOD_LALT)) + quitES = true; + else if (quitShortcut == "F4" && event.key.keysym.sym == SDLK_F4 && +#else if (quitShortcut == "F4" && event.key.keysym.sym == SDLK_F4 && - !(event.key.keysym.mod & KMOD_LALT)) +#endif + !(event.key.keysym.mod & KMOD_LALT)) quitES = true; else if (quitShortcut == "CtrlQ" && event.key.keysym.sym == SDLK_q && event.key.keysym.mod & KMOD_CTRL) @@ -462,7 +515,7 @@ bool InputManager::parseEvent(const SDL_Event& event) quitES = true; if (quitES) { - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); return false; @@ -484,6 +537,62 @@ bool InputManager::parseEvent(const SDL_Event& event) Input(DEVICE_KEYBOARD, TYPE_KEY, event.key.keysym.sym, 0, false)); return true; } +#if defined(__ANDROID__) + case SDL_FINGERDOWN: { + if (!Settings::getInstance()->getBool("InputTouchOverlay")) + return false; + + const int buttonID {mInputOverlay.getButtonId( + SDL_FINGERDOWN, event.tfinger.fingerId + 1, event.tfinger.x, event.tfinger.y)}; + if (buttonID != -2) { + mWindow->input(getInputConfigByDevice(DEVICE_TOUCH), + Input(DEVICE_TOUCH, TYPE_TOUCH, buttonID, 1, false)); + return true; + } + else { + return false; + } + } + case SDL_FINGERUP: { + if (!Settings::getInstance()->getBool("InputTouchOverlay")) + return false; + + const int buttonID {mInputOverlay.getButtonId(SDL_FINGERUP, event.tfinger.fingerId + 1, + event.tfinger.x, event.tfinger.y)}; + if (buttonID != -2) { + mWindow->input(getInputConfigByDevice(DEVICE_TOUCH), + Input(DEVICE_TOUCH, TYPE_TOUCH, buttonID, 0, false)); + + return true; + } + else { + return false; + } + } + case SDL_FINGERMOTION: { + if (!Settings::getInstance()->getBool("InputTouchOverlay")) + return false; + + bool releasedButton {false}; + const int buttonID { + mInputOverlay.getButtonId(SDL_FINGERMOTION, event.tfinger.fingerId + 1, + event.tfinger.x, event.tfinger.y, &releasedButton)}; + + if (buttonID == -2) + return false; + + if (releasedButton) { + mWindow->input(getInputConfigByDevice(DEVICE_TOUCH), + Input(DEVICE_TOUCH, TYPE_TOUCH, buttonID, 0, false)); + return true; + } + else { + mWindow->input(getInputConfigByDevice(DEVICE_TOUCH), + Input(DEVICE_TOUCH, TYPE_TOUCH, buttonID, 1, false)); + return true; + } + } +#endif case SDL_TEXTINPUT: { mWindow->textInput(event.text.text); break; @@ -620,13 +729,41 @@ void InputManager::loadDefaultControllerConfig(SDL_JoystickID deviceIndex) // clang-format on } +void InputManager::loadTouchConfig() +{ +#if defined(__ANDROID__) + InputConfig* cfg {mTouchInputConfig.get()}; + + if (cfg->isConfigured()) + return; + + // clang-format off + cfg->mapInput("Up", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_DPAD_UP, 1, true)); + cfg->mapInput("Down", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_DPAD_DOWN, 1, true)); + cfg->mapInput("Left", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_DPAD_LEFT, 1, true)); + cfg->mapInput("Right", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, 1, true)); + cfg->mapInput("Start", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_START, 1, true)); + cfg->mapInput("Back", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_BACK, 1, true)); + cfg->mapInput("A", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_A, 1, true)); + cfg->mapInput("B", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_B, 1, true)); + cfg->mapInput("X", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_X, 1, true)); + cfg->mapInput("Y", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_Y, 1, true)); + cfg->mapInput("LeftShoulder", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, 1, true)); + cfg->mapInput("RightShoulder", Input(DEVICE_TOUCH, TYPE_TOUCH, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, 1, true)); + cfg->mapInput("LeftTrigger", Input(DEVICE_TOUCH, TYPE_TOUCH, InputOverlay::TriggerButtons::TRIGGER_LEFT, 1, true)); + cfg->mapInput("RightTrigger", Input(DEVICE_TOUCH, TYPE_TOUCH, InputOverlay::TriggerButtons::TRIGGER_RIGHT, 1, true)); + // clang-format on +#endif +} + void InputManager::addControllerByDeviceIndex(Window* window, int deviceIndex) { // Open joystick and add it to our list. SDL_GameController* controller {SDL_GameControllerOpen(deviceIndex)}; if (controller == nullptr) { - LOG(LogError) << "Couldn't add controller with device index " << deviceIndex; + LOG(LogError) << "Couldn't add controller with device index " << deviceIndex << " (" + << SDL_GetError() << ")"; return; } diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index d68fa0b53..b77667975 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputManager.h // // Low-level input handling. @@ -13,6 +13,10 @@ #include "CECInput.h" +#if defined(__ANDROID__) +#include "InputOverlay.h" +#endif + #include #include @@ -22,7 +26,6 @@ class InputConfig; class Window; -union SDL_Event; class InputManager { @@ -58,12 +61,16 @@ private: bool loadInputConfig(InputConfig* config); void loadDefaultKBConfig(); void loadDefaultControllerConfig(SDL_JoystickID deviceIndex); + void loadTouchConfig(); void addControllerByDeviceIndex(Window* window, int deviceIndex); void removeControllerByJoystickID(Window* window, SDL_JoystickID joyID); Window* mWindow; CECInput mCECInput; +#if defined(__ANDROID__) + InputOverlay& mInputOverlay; +#endif static const int DEADZONE_TRIGGERS = 18000; static const int DEADZONE_THUMBSTICKS = 23000; @@ -74,6 +81,7 @@ private: std::map> mInputConfigs; std::unique_ptr mKeyboardInputConfig; + std::unique_ptr mTouchInputConfig; std::unique_ptr mCECInputConfig; std::map, int> mPrevAxisValues; diff --git a/es-core/src/Log.cpp b/es-core/src/Log.cpp index 4807bd7ee..48d679f7c 100644 --- a/es-core/src/Log.cpp +++ b/es-core/src/Log.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Log.cpp // // Log output. @@ -8,6 +8,7 @@ // #include "Log.h" +#include "Settings.h" #include "utils/StringUtil.h" LogLevel Log::getReportingLevel() @@ -22,16 +23,16 @@ void Log::setReportingLevel(LogLevel level) sReportingLevel = level; } -std::string Log::getLogPath() -{ - return Utils::FileSystem::getHomePath() + "/.emulationstation/es_log.txt"; -} - void Log::init() { - Utils::FileSystem::removeFile(getLogPath() + ".bak"); + if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) + sLogPath = Utils::FileSystem::getAppDataDirectory() + "/es_log.txt"; + else + sLogPath = Utils::FileSystem::getAppDataDirectory() + "/logs/es_log.txt"; + + Utils::FileSystem::removeFile(sLogPath + ".bak"); // Rename the previous log file. - Utils::FileSystem::renameFile(getLogPath(), getLogPath() + ".bak", true); + Utils::FileSystem::renameFile(sLogPath, sLogPath + ".bak", true); return; } @@ -39,9 +40,9 @@ void Log::open() { std::unique_lock lock {sLogMutex}; #if defined(_WIN64) - sFile.open(Utils::String::stringToWideString(getLogPath()).c_str()); + sFile.open(Utils::String::stringToWideString(sLogPath).c_str()); #else - sFile.open(getLogPath().c_str()); + sFile.open(sLogPath.c_str()); #endif } @@ -70,7 +71,9 @@ std::ostringstream& Log::get(LogLevel level) localtime_r(&t, &tm); #endif std::unique_lock lock {sLogMutex}; - mOutStringStream << std::put_time(&tm, "%b %d %H:%M:%S ") << mLogLevelMap[level] << ":\t"; + mOutStringStream << std::put_time(&tm, "%b %d %H:%M:%S ") << mLogLevelMap[level] + << (level == LogLevel::LogInfo || level == LogLevel::LogWarning ? ": " : + ": "); mMessageLevel = level; return mOutStringStream; @@ -83,15 +86,41 @@ Log::~Log() if (!sFile.is_open()) { // Not open yet, print to stdout. +#if defined(__ANDROID__) + __android_log_print( + ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Tried to write to log file before it was open, the following won't be logged:"); + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, "%s", + mOutStringStream.str().c_str()); +#else std::cerr << "Error: Tried to write to log file before it was open, " "the following won't be logged:\n"; std::cerr << mOutStringStream.str(); +#endif return; } sFile << mOutStringStream.str(); +#if defined(__ANDROID__) + if (mMessageLevel == LogError) { + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, "%s", + mOutStringStream.str().c_str()); + } + else if (sReportingLevel >= LogDebug) { + if (mMessageLevel == LogInfo) + __android_log_print(ANDROID_LOG_INFO, ANDROID_APPLICATION_ID, "%s", + mOutStringStream.str().c_str()); + else if (mMessageLevel == LogWarning) + __android_log_print(ANDROID_LOG_WARN, ANDROID_APPLICATION_ID, "%s", + mOutStringStream.str().c_str()); + else + __android_log_print(ANDROID_LOG_DEBUG, ANDROID_APPLICATION_ID, "%s", + mOutStringStream.str().c_str()); + } +#else // If it's an error or the --debug flag has been set, then print to the console as well. if (mMessageLevel == LogError || sReportingLevel >= LogDebug) std::cerr << mOutStringStream.str(); +#endif } diff --git a/es-core/src/Log.h b/es-core/src/Log.h index 0f165cd04..8219db00f 100644 --- a/es-core/src/Log.h +++ b/es-core/src/Log.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Log.h // // Log output. @@ -19,6 +19,10 @@ #include #include +#if defined(__ANDROID__) +#include +#endif + #define LOG(level) \ if (level > Log::getReportingLevel()) \ ; \ @@ -43,7 +47,6 @@ public: static void setReportingLevel(LogLevel level); // These functions are not thread safe. - static std::string getLogPath(); static void init(); static void open(); @@ -62,6 +65,7 @@ private: static inline std::ofstream sFile; static inline LogLevel sReportingLevel = LogInfo; static inline std::mutex sLogMutex; + static inline std::string sLogPath; LogLevel mMessageLevel; }; diff --git a/es-core/src/MameNames.cpp b/es-core/src/MameNames.cpp index 39e9a2725..6c1683a60 100644 --- a/es-core/src/MameNames.cpp +++ b/es-core/src/MameNames.cpp @@ -1,12 +1,11 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MameNames.cpp // // Provides expanded game names based on short MAME name arguments. Also contains // functions to check whether a passed argument is a MAME BIOS or a MAME device. -// The data sources are stored in the .emulationstation/resources directory -// as the files mamebioses.xml, mamedevices.xml and mamenames.xml. +// The data sources are stored as the files mamebioses.xml, mamedevices.xml and mamenames.xml. // #include "MameNames.h" diff --git a/es-core/src/MameNames.h b/es-core/src/MameNames.h index 144017010..051de283e 100644 --- a/es-core/src/MameNames.h +++ b/es-core/src/MameNames.h @@ -1,12 +1,11 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MameNames.h // // Provides expanded game names based on short MAME name arguments. Also contains // functions to check whether a passed argument is a MAME BIOS or a MAME device. -// The data sources are stored in the .emulationstation/resources directory -// as the files mamebioses.xml, mamedevices.xml and mamenames.xml. +// The data sources are stored as the files mamebioses.xml, mamedevices.xml and mamenames.xml. // #ifndef ES_CORE_MAMENAMES_H diff --git a/es-core/src/Scripting.cpp b/es-core/src/Scripting.cpp index a34eab10a..7eff423d9 100644 --- a/es-core/src/Scripting.cpp +++ b/es-core/src/Scripting.cpp @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scripting.cpp // // Executes custom scripts for various events. // By calling fireEvent() the scripts inside the directory corresponding to the // argument "eventName" will be executed with arg1, arg2, arg3 and arg4 as arguments. // -// The scripts are searched for in ~/.emulationstation/scripts/ +// The scripts are searched for in /scripts/ // For example, if the event is called "game-start", all scripts inside the directory -// ~/.emulationstation/scripts/game-start/ will be executed. +// /scripts/game-start/ will be executed. // #include "Scripting.h" @@ -39,8 +39,8 @@ namespace Scripting std::list scriptDirList; std::string scriptDir; - // Check in homepath. - scriptDir = Utils::FileSystem::getHomePath() + "/.emulationstation/scripts/" + eventName; + // Check in application data directory. + scriptDir = Utils::FileSystem::getAppDataDirectory() + "/scripts/" + eventName; if (Utils::FileSystem::exists(scriptDir)) scriptDirList.push_back(scriptDir); @@ -89,7 +89,11 @@ namespace Scripting .append(arg4) .append(arg4Quotation); LOG(LogDebug) << "Executing: " << script; +#if defined(__ANDROID__) + Utils::Platform::runSystemCommand("sh " + script); +#else Utils::Platform::runSystemCommand(script); +#endif } } } diff --git a/es-core/src/Scripting.h b/es-core/src/Scripting.h index 30f5c6e21..ff88be1c2 100644 --- a/es-core/src/Scripting.h +++ b/es-core/src/Scripting.h @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scripting.h // // Executes custom scripts for various events. // By calling fireEvent() the scripts inside the directory corresponding to the // argument "eventName" will be executed with arg1, arg2, arg3 and arg4 as arguments. // -// The scripts are searched for in ~/.emulationstation/scripts/ +// The scripts are searched for in /scripts/ // For example, if the event is called "game-start", all scripts inside the directory -// ~/.emulationstation/scripts/game-start/ will be executed. +// /scripts/game-start/ will be executed. // #ifndef ES_CORE_SCRIPTING_H diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 5f560076b..284a8c737 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Settings.cpp // // Functions to read from and write to the configuration file es_settings.xml. @@ -46,6 +46,7 @@ namespace "DebugGrid", "DebugText", "DebugImage", + "LegacyAppDataDirectory", "ScraperFilter", "TransitionsSystemToSystem", "TransitionsSystemToGamelist", @@ -77,6 +78,9 @@ Settings::Settings() { mWasChanged = false; setDefaults(); + if (Utils::FileSystem::getFileName(Utils::FileSystem::getAppDataDirectory()) == + ".emulationstation") + mBoolMap["LegacyAppDataDirectory"] = std::make_pair(true, true); loadFile(); } @@ -145,7 +149,7 @@ void Settings::setDefaults() mIntMap["ScraperRetryOnErrorTimer"] = {3, 3}; mIntMap["ScraperSearchFileHashMaxSize"] = {384, 384}; mBoolMap["ScraperOverwriteData"] = {true, true}; - mBoolMap["ScraperHaltOnInvalidMedia"] = {true, true}; + mBoolMap["ScraperIgnoreHTTP404Errors"] = {true, true}; mBoolMap["ScraperSearchFileHash"] = {true, true}; mBoolMap["ScraperSearchMetadataName"] = {true, true}; mBoolMap["ScraperIncludeFolders"] = {true, true}; @@ -158,9 +162,10 @@ void Settings::setDefaults() mBoolMap["ScraperRegionFallback"] = {true, true}; // UI settings. - mStringMap["Theme"] = {"slate-es-de", "slate-es-de"}; + mStringMap["Theme"] = {"linear-es-de", "linear-es-de"}; mStringMap["ThemeVariant"] = {"", ""}; mStringMap["ThemeColorScheme"] = {"", ""}; + mStringMap["ThemeFontSize"] = {"", ""}; mStringMap["ThemeAspectRatio"] = {"", ""}; mStringMap["ThemeTransitions"] = {"automatic", "automatic"}; mStringMap["QuickSystemSelect"] = {"leftrightshoulders", "leftrightshoulders"}; @@ -199,8 +204,7 @@ void Settings::setDefaults() mBoolMap["ScreensaverSlideshowScanlines"] = {false, false}; mBoolMap["ScreensaverSlideshowCustomImages"] = {false, false}; mBoolMap["ScreensaverSlideshowRecurse"] = {false, false}; - mStringMap["ScreensaverSlideshowImageDir"] = {"~/.emulationstation/slideshow/custom_images", - "~/.emulationstation/slideshow/custom_images"}; + mStringMap["ScreensaverSlideshowCustomDir"] = {"", ""}; // UI settings -> screensaver settings -> video screensaver settings. mIntMap["ScreensaverSwapVideoTimeout"] = {0, 0}; @@ -235,7 +239,14 @@ void Settings::setDefaults() // Input device settings. mStringMap["InputControllerType"] = {"xbox", "xbox"}; +#if defined(__ANDROID__) + mStringMap["InputTouchOverlaySize"] = {"medium", "medium"}; + mStringMap["InputTouchOverlayOpacity"] = {"normal", "normal"}; + mIntMap["InputTouchOverlayFadeTime"] = {6, 6}; + mBoolMap["InputTouchOverlay"] = {true, true}; +#endif mBoolMap["InputOnlyFirstController"] = {false, false}; + mBoolMap["InputSwapButtons"] = {false, false}; mBoolMap["InputIgnoreKeyboard"] = {false, false}; // Game collection settings. @@ -271,7 +282,9 @@ void Settings::setDefaults() #if defined(_WIN64) mBoolMap["HideTaskbar"] = {false, false}; #endif +#if !defined(__ANDROID__) mBoolMap["RunInBackground"] = {false, false}; +#endif #if defined(VIDEO_HW_DECODING) mBoolMap["VideoHardwareDecoding"] = {false, false}; #endif @@ -286,7 +299,7 @@ void Settings::setDefaults() mBoolMap["CustomEventScripts"] = {false, false}; mBoolMap["ParseGamelistOnly"] = {false, false}; mBoolMap["MAMENameStripExtraInfo"] = {true, true}; -#if defined(__unix__) +#if defined(__unix__) && !defined(__ANDROID__) mBoolMap["DisableComposition"] = {false, false}; #endif mBoolMap["DebugMode"] = {false, false}; @@ -294,7 +307,7 @@ void Settings::setDefaults() mBoolMap["EnableMenuKidMode"] = {false, false}; // macOS requires root privileges to reboot and power off so it doesn't make much // sense to enable this setting and menu entry for that operating system. -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__ANDROID__) mBoolMap["ShowQuitMenu"] = {false, false}; #endif @@ -325,10 +338,15 @@ void Settings::setDefaults() mBoolMap["DebugSkipMissingThemeFiles"] = {false, false}; mBoolMap["DebugSkipMissingThemeFilesCustomCollections"] = {true, true}; mBoolMap["LegacyGamelistFileLocation"] = {false, false}; + mBoolMap["CreatePlaceholderSystemDirectories"] = {false, false}; mStringMap["OpenGLVersion"] = {"", ""}; +#if !defined(__ANDROID__) mStringMap["ROMDirectory"] = {"", ""}; +#endif mStringMap["UIMode_passkey"] = {"uuddlrlrba", "uuddlrlrba"}; +#if !defined(__ANDROID__) mStringMap["UserThemeDirectory"] = {"", ""}; +#endif mIntMap["LottieMaxFileCache"] = {150, 150}; mIntMap["LottieMaxTotalCache"] = {1024, 1024}; mIntMap["ScraperConnectionTimeout"] = {30, 30}; @@ -345,6 +363,7 @@ void Settings::setDefaults() mBoolMap["DebugGrid"] = {false, false}; mBoolMap["DebugText"] = {false, false}; mBoolMap["DebugImage"] = {false, false}; + mBoolMap["LegacyAppDataDirectory"] = {false, false}; mIntMap["ScraperFilter"] = {0, 0}; mIntMap["TransitionsSystemToSystem"] = {ViewTransitionAnimation::INSTANT, ViewTransitionAnimation::INSTANT}; @@ -362,9 +381,13 @@ void Settings::setDefaults() void Settings::saveFile() { - LOG(LogDebug) << "Settings::saveFile(): Saving settings to es_settings.xml"; - const std::string path = - Utils::FileSystem::getHomePath() + "/.emulationstation/es_settings.xml"; + std::string path; + if (mBoolMap["LegacyAppDataDirectory"].second == true) { + path = Utils::FileSystem::getAppDataDirectory() + "/es_settings.xml"; + } + else { + path = Utils::FileSystem::getAppDataDirectory() + "/settings/es_settings.xml"; + } pugi::xml_document doc; @@ -394,18 +417,20 @@ void Settings::saveFile() void Settings::loadFile() { - const std::string configFile {Utils::FileSystem::getHomePath() + - "/.emulationstation/es_settings.xml"}; + std::string path; + if (mBoolMap["LegacyAppDataDirectory"].second == true) + path = Utils::FileSystem::getAppDataDirectory() + "/es_settings.xml"; + else + path = Utils::FileSystem::getAppDataDirectory() + "/settings/es_settings.xml"; - if (!Utils::FileSystem::exists(configFile)) + if (!Utils::FileSystem::exists(path)) return; pugi::xml_document doc; #if defined(_WIN64) - pugi::xml_parse_result result { - doc.load_file(Utils::String::stringToWideString(configFile).c_str())}; + pugi::xml_parse_result result {doc.load_file(Utils::String::stringToWideString(path).c_str())}; #else - pugi::xml_parse_result result {doc.load_file(configFile.c_str())}; + pugi::xml_parse_result result {doc.load_file(path.c_str())}; #endif if (!result) { LOG(LogError) << "Couldn't parse the es_settings.xml file: " << result.description(); diff --git a/es-core/src/Settings.h b/es-core/src/Settings.h index c35d871a2..90b175f2c 100644 --- a/es-core/src/Settings.h +++ b/es-core/src/Settings.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Settings.h // // Functions to read from and write to the configuration file es_settings.xml. diff --git a/es-core/src/Sound.cpp b/es-core/src/Sound.cpp index 1c0484ee4..23bdad436 100644 --- a/es-core/src/Sound.cpp +++ b/es-core/src/Sound.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Sound.cpp // // Higher-level audio functions. diff --git a/es-core/src/Sound.h b/es-core/src/Sound.h index eefa46ad7..22bae66a3 100644 --- a/es-core/src/Sound.h +++ b/es-core/src/Sound.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Sound.h // // Higher-level audio functions. diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 4cfdfa06c..7cedb242d 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ThemeData.cpp // // Finds available themes on the file system and loads and parses these. @@ -51,6 +51,13 @@ std::vector ThemeData::sSupportedTransitionAnimations { {"builtin-slide"}, {"builtin-fade"}}; +std::vector> ThemeData::sSupportedFontSizes { + {"medium", "medium"}, + {"large", "large"}, + {"small", "small"}, + {"x-large", "extra large"}, + {"x-small", "extra small"}}; + std::vector> ThemeData::sSupportedAspectRatios { {"automatic", "automatic"}, {"16:9", "16:9"}, @@ -63,10 +70,15 @@ std::vector> ThemeData::sSupportedAspectRati {"4:3_vertical", "4:3 vertical"}, {"5:4", "5:4"}, {"5:4_vertical", "5:4 vertical"}, + {"19.5:9", "19.5:9"}, + {"19.5:9_vertical", "19.5:9 vertical"}, + {"20:9", "20:9"}, + {"20:9_vertical", "20:9 vertical"}, {"21:9", "21:9"}, {"21:9_vertical", "21:9 vertical"}, {"32:9", "32:0"}, - {"32:9_vertical", "32:9 vertical"}}; + {"32:9_vertical", "32:9 vertical"}, + {"1:1", "1:1"}}; std::map ThemeData::sAspectRatioMap { {"16:9", 1.7777f}, @@ -79,10 +91,15 @@ std::map ThemeData::sAspectRatioMap { {"4:3_vertical", 0.75f}, {"5:4", 1.25f}, {"5:4_vertical", 0.8f}, + {"19.5:9", 2.1667f}, + {"19.5:9_vertical", 0.4615f}, + {"20:9", 2.2222f}, + {"20:9_vertical", 0.45f}, {"21:9", 2.3703f}, {"21:9_vertical", 0.4219f}, {"32:9", 3.5555f}, - {"32:9_vertical", 0.2813f}}; + {"32:9_vertical", 0.2813f}, + {"1:1", 1.0f}}; std::map> ThemeData::sPropertyAttributeMap // The data type is defined by the parent property. @@ -232,6 +249,7 @@ std::map> {{"pos", NORMALIZED_PAIR}, {"size", NORMALIZED_PAIR}, {"origin", NORMALIZED_PAIR}, + {"selectorWidth", FLOAT}, {"selectorHeight", FLOAT}, {"selectorHorizontalOffset", FLOAT}, {"selectorVerticalOffset", FLOAT}, @@ -273,6 +291,7 @@ std::map> {"rotation", FLOAT}, {"rotationOrigin", NORMALIZED_PAIR}, {"stationary", STRING}, + {"renderDuringTransitions", BOOLEAN}, {"flipHorizontal", BOOLEAN}, {"flipVertical", BOOLEAN}, {"path", PATH}, @@ -470,6 +489,7 @@ std::map> {"rotation", FLOAT}, {"rotationOrigin", NORMALIZED_PAIR}, {"stationary", STRING}, + {"hideIfZero", BOOLEAN}, {"gameselector", STRING}, {"gameselectorEntry", UNSIGNED_INTEGER}, {"interpolation", STRING}, @@ -550,9 +570,9 @@ void ThemeData::loadFile(const std::map& sysDataMap, if (!root) throw error << ": Missing tag"; - // Check for legacy theme version. + // Check if there's an unsupported theme version tag. if (root.child("formatVersion") != nullptr) - throw error << ": Legacy tag found"; + throw error << ": Unsupported tag found"; if (sCurrentTheme->second.capabilities.variants.size() > 0) { for (auto& variant : sCurrentTheme->second.capabilities.variants) @@ -585,6 +605,17 @@ void ThemeData::loadFile(const std::map& sysDataMap, mSelectedColorScheme = mColorSchemes.front(); } + if (sCurrentTheme->second.capabilities.fontSizes.size() > 0) { + for (auto& fontSize : sCurrentTheme->second.capabilities.fontSizes) + mFontSizes.emplace_back(fontSize); + + if (std::find(mFontSizes.cbegin(), mFontSizes.cend(), + Settings::getInstance()->getString("ThemeFontSize")) != mFontSizes.cend()) + mSelectedFontSize = Settings::getInstance()->getString("ThemeFontSize"); + else + mSelectedFontSize = mFontSizes.front(); + } + sAspectRatioMatch = false; if (sCurrentTheme->second.capabilities.aspectRatios.size() > 0) { @@ -622,10 +653,11 @@ void ThemeData::loadFile(const std::map& sysDataMap, parseVariables(root); parseColorSchemes(root); + parseFontSizes(root); parseIncludes(root); parseViews(root); if (root.child("feature") != nullptr) - throw error << ": Legacy tag found"; + throw error << ": Unsupported tag found"; parseVariants(root); parseAspectRatios(root); } @@ -667,16 +699,16 @@ void ThemeData::populateThemes() // Check for themes first under the user theme directory (which is in the ES-DE home directory // by default), then under the data installation directory (Unix only) and last under the ES-DE // binary directory. - const std::string defaultUserThemeDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes"}; - std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( +#if defined(__ANDROID__) + const std::string userThemeDirectory {Utils::FileSystem::getInternalAppDataDirectory() + + "/themes"}; +#else + const std::string defaultUserThemeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"}; + const std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( Settings::getInstance()->getString("UserThemeDirectory"))}; -#if defined(_WIN64) - userThemeDirSetting = Utils::String::replace(userThemeDirSetting, "\\", "/"); -#endif std::string userThemeDirectory; - if (userThemeDirSetting == "") { + if (userThemeDirSetting.empty()) { userThemeDirectory = defaultUserThemeDir; } else if (Utils::FileSystem::isDirectory(userThemeDirSetting) || @@ -695,31 +727,30 @@ void ThemeData::populateThemes() << defaultUserThemeDir << "\""; userThemeDirectory = defaultUserThemeDir; } +#endif -#if defined(__unix__) || defined(__APPLE__) -#if defined(APPIMAGE_BUILD) - static const size_t pathCount {2}; -#else - static const size_t pathCount {3}; -#endif -#else - static const size_t pathCount {2}; -#endif - std::string paths[pathCount] = { +#if defined(__ANDROID__) + const std::vector themePaths {Utils::FileSystem::getProgramDataPath() + "/themes", + Utils::FileSystem::getAppDataDirectory() + "/themes", + userThemeDirectory}; +#elif defined(__APPLE__) + const std::vector themePaths { Utils::FileSystem::getExePath() + "/themes", -#if defined(__APPLE__) - Utils::FileSystem::getExePath() + "/../Resources/themes", -#elif defined(__unix__) && !defined(APPIMAGE_BUILD) - Utils::FileSystem::getProgramDataPath() + "/themes", + Utils::FileSystem::getExePath() + "/../Resources/themes", userThemeDirectory}; +#elif defined(_WIN64) || defined(APPIMAGE_BUILD) + const std::vector themePaths {Utils::FileSystem::getExePath() + "/themes", + userThemeDirectory}; +#else + const std::vector themePaths {Utils::FileSystem::getExePath() + "/themes", + Utils::FileSystem::getProgramDataPath() + "/themes", + userThemeDirectory}; #endif - userThemeDirectory - }; - for (size_t i {0}; i < pathCount; ++i) { - if (!Utils::FileSystem::isDirectory(paths[i])) + for (auto path : themePaths) { + if (!Utils::FileSystem::isDirectory(path)) continue; - Utils::FileSystem::StringList dirContent {Utils::FileSystem::getDirContent(paths[i])}; + Utils::FileSystem::StringList dirContent {Utils::FileSystem::getDirContent(path)}; for (Utils::FileSystem::StringList::const_iterator it = dirContent.cbegin(); it != dirContent.cend(); ++it) { @@ -730,22 +761,20 @@ void ThemeData::populateThemes() Utils::String::toLower(themeDirName.substr(themeDirName.length() - 8, 8)) == "disabled")) continue; - #if defined(_WIN64) LOG(LogDebug) << "Loading theme capabilities for \"" << Utils::String::replace(*it, "/", "\\") << "\"..."; #else LOG(LogDebug) << "Loading theme capabilities for \"" << *it << "\"..."; #endif - ThemeCapability capabilities {parseThemeCapabilities(*it)}; + ThemeCapability capabilities {parseThemeCapabilities((*it))}; if (!capabilities.validTheme) continue; std::string themeName; - if (capabilities.themeName != "") { + if (capabilities.themeName != "") themeName.append(" (\"").append(capabilities.themeName).append("\")"); - } #if defined(_WIN64) LOG(LogInfo) << "Added theme \"" << Utils::String::replace(*it, "/", "\\") << "\"" @@ -760,6 +789,8 @@ void ThemeData::populateThemes() << " variant" << (capabilities.variants.size() != 1 ? "s" : "") << ", " << capabilities.colorSchemes.size() << " color scheme" << (capabilities.colorSchemes.size() != 1 ? "s" : "") << ", " + << capabilities.fontSizes.size() << " font size" + << (capabilities.fontSizes.size() != 1 ? "s" : "") << ", " << aspectRatios << " aspect ratio" << (aspectRatios != 1 ? "s" : "") << " and " << capabilities.transitions.size() << " transition" << (capabilities.transitions.size() != 1 ? "s" : ""); @@ -789,11 +820,11 @@ const std::string ThemeData::getSystemThemeFile(const std::string& system) std::map::const_iterator theme { sThemes.find(Settings::getInstance()->getString("Theme"))}; if (theme == sThemes.cend()) { - // Currently configured theme is missing, attempt to load the default theme slate-es-de + // Currently configured theme is missing, attempt to load the default theme linear-es-de // instead, and if that's also missing then pick the first available one. bool defaultSetFound {true}; - theme = sThemes.find("slate-es-de"); + theme = sThemes.find("linear-es-de"); if (theme == sThemes.cend()) { theme = sThemes.cbegin(); @@ -811,6 +842,18 @@ const std::string ThemeData::getSystemThemeFile(const std::string& system) return theme->second.getThemePath(system); } +const std::string ThemeData::getFontSizeLabel(const std::string& fontSize) +{ + auto it = std::find_if(sSupportedFontSizes.cbegin(), sSupportedFontSizes.cend(), + [&fontSize](const std::pair& entry) { + return entry.first == fontSize; + }); + if (it != sSupportedFontSizes.cend()) + return it->second; + else + return "invalid font size"; +} + const std::string ThemeData::getAspectRatioLabel(const std::string& aspectRatio) { auto it = std::find_if(sSupportedAspectRatios.cbegin(), sSupportedAspectRatios.cend(), @@ -972,6 +1015,7 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string& { ThemeCapability capabilities; std::vector aspectRatiosTemp; + std::vector fontSizesTemp; bool hasTriggers {false}; const std::string capFile {path + "/capabilities.xml"}; @@ -1026,6 +1070,29 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string& } } + for (pugi::xml_node fontSize {themeCapabilities.child("fontSize")}; fontSize; + fontSize = fontSize.next_sibling("fontSize")) { + const std::string& value {fontSize.text().get()}; + if (std::find_if(sSupportedFontSizes.cbegin(), sSupportedFontSizes.cend(), + [&value](const std::pair& entry) { + return entry.first == value; + }) == sSupportedFontSizes.cend()) { + LOG(LogWarning) << "Declared font size \"" << value + << "\" is not supported, ignoring entry in \"" << capFile << "\""; + } + else { + if (std::find(fontSizesTemp.cbegin(), fontSizesTemp.cend(), value) != + fontSizesTemp.cend()) { + LOG(LogWarning) + << "Font size \"" << value + << "\" is declared multiple times, ignoring entry in \"" << capFile << "\""; + } + else { + fontSizesTemp.emplace_back(value); + } + } + } + for (pugi::xml_node variant {themeCapabilities.child("variant")}; variant; variant = variant.next_sibling("variant")) { ThemeVariant readVariant; @@ -1403,6 +1470,17 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string& } } + // Add the font sizes in the order they are defined in sSupportedFontSizes so they always + // show up in the same order in the UI Settings menu. + if (!fontSizesTemp.empty()) { + for (auto& fontSize : sSupportedFontSizes) { + if (std::find(fontSizesTemp.cbegin(), fontSizesTemp.cend(), fontSize.first) != + fontSizesTemp.cend()) { + capabilities.fontSizes.emplace_back(fontSize.first); + } + } + } + if (hasTriggers) { for (auto& variant : capabilities.variants) { for (auto it = variant.overrides.begin(); it != variant.overrides.end();) { @@ -1430,15 +1508,15 @@ ThemeData::ThemeCapability ThemeData::parseThemeCapabilities(const std::string& void ThemeData::parseIncludes(const pugi::xml_node& root) { - ThemeException error; - error << "ThemeData::parseIncludes(): "; - error.setFiles(mPaths); - - // Check for legacy theme version. - if (root.child("formatVersion") != nullptr) - throw error << ": Legacy tag found"; - for (pugi::xml_node node {root.child("include")}; node; node = node.next_sibling("include")) { + ThemeException error; + error << "ThemeData::parseIncludes(): "; + error.setFiles(mPaths); + + // Check if there's an unsupported theme version tag. + if (root.child("formatVersion") != nullptr) + throw error << ": Unsupported tag found"; + std::string relPath {resolvePlaceholders(node.text().as_string())}; std::string path {Utils::FileSystem::resolveRelativePath(relPath, mPaths.back(), true)}; @@ -1492,10 +1570,11 @@ void ThemeData::parseIncludes(const pugi::xml_node& root) parseTransitions(theme); parseVariables(theme); parseColorSchemes(theme); + parseFontSizes(theme); parseIncludes(theme); parseViews(theme); if (theme.child("feature") != nullptr) - throw error << ": Legacy tag found"; + throw error << ": Unsupported tag found"; parseVariants(theme); parseAspectRatios(theme); @@ -1541,6 +1620,7 @@ void ThemeData::parseVariants(const pugi::xml_node& root) parseTransitions(node); parseVariables(node); parseColorSchemes(node); + parseFontSizes(node); parseIncludes(node); parseViews(node); parseAspectRatios(node); @@ -1588,6 +1668,43 @@ void ThemeData::parseColorSchemes(const pugi::xml_node& root) } } +void ThemeData::parseFontSizes(const pugi::xml_node& root) +{ + if (sCurrentTheme == sThemes.end()) + return; + + if (mSelectedFontSize == "") + return; + + ThemeException error; + error << "ThemeData::parseFontSizes(): "; + error.setFiles(mPaths); + + for (pugi::xml_node node {root.child("fontSize")}; node; node = node.next_sibling("fontSize")) { + if (!node.attribute("name")) + throw error << ": tag missing \"name\" attribute"; + + const std::string delim {" \t\r\n,"}; + const std::string nameAttr {node.attribute("name").as_string()}; + size_t prevOff {nameAttr.find_first_not_of(delim, 0)}; + size_t off {nameAttr.find_first_of(delim, prevOff)}; + std::string viewKey; + while (off != std::string::npos || prevOff != std::string::npos) { + viewKey = nameAttr.substr(prevOff, off - prevOff); + prevOff = nameAttr.find_first_not_of(delim, off); + off = nameAttr.find_first_of(delim, prevOff); + + if (std::find(mFontSizes.cbegin(), mFontSizes.cend(), viewKey) == mFontSizes.cend()) { + throw error << ": value \"" << viewKey + << "\" is not defined in capabilities.xml"; + } + + if (mSelectedFontSize == viewKey) + parseVariables(node); + } + } +} + void ThemeData::parseAspectRatios(const pugi::xml_node& root) { if (sCurrentTheme == sThemes.end()) @@ -1625,6 +1742,7 @@ void ThemeData::parseAspectRatios(const pugi::xml_node& root) if (sSelectedAspectRatio == viewKey) { parseVariables(node); parseColorSchemes(node); + parseFontSizes(node); parseIncludes(node); parseViews(node); } @@ -1755,8 +1873,8 @@ void ThemeData::parseElement(const pugi::xml_node& root, element.type = root.name(); if (root.attribute("extra") != nullptr) - throw error << ": Legacy \"extra\" attribute found for element of type \"" << element.type - << "\""; + throw error << ": Unsupported \"extra\" attribute found for element of type \"" + << element.type << "\""; for (pugi::xml_node node {root.first_child()}; node; node = node.next_sibling()) { auto typeIt = typeMap.find(node.name()); diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 7574b0712..d6ed87fa3 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ThemeData.h // // Finds available themes on the file system and loads and parses these. @@ -184,6 +184,7 @@ public: std::string themeName; std::vector variants; std::vector colorSchemes; + std::vector fontSizes; std::vector aspectRatios; std::vector transitions; std::vector suppressedTransitionProfiles; @@ -222,6 +223,7 @@ public: static void populateThemes(); const static std::map& getThemes() { return sThemes; } const static std::string getSystemThemeFile(const std::string& system); + const static std::string getFontSizeLabel(const std::string& fontSize); const static std::string getAspectRatioLabel(const std::string& aspectRatio); static void setThemeTransitions(); @@ -251,6 +253,7 @@ private: void parseIncludes(const pugi::xml_node& root); void parseVariants(const pugi::xml_node& root); void parseColorSchemes(const pugi::xml_node& root); + void parseFontSizes(const pugi::xml_node& root); void parseAspectRatios(const pugi::xml_node& root); void parseTransitions(const pugi::xml_node& root); void parseVariables(const pugi::xml_node& root); @@ -264,6 +267,8 @@ private: static std::vector sSupportedMediaTypes; static std::vector sSupportedTransitions; static std::vector sSupportedTransitionAnimations; + + static std::vector> sSupportedFontSizes; static std::vector> sSupportedAspectRatios; static std::map sAspectRatioMap; @@ -278,9 +283,11 @@ private: std::deque mPaths; std::vector mVariants; std::vector mColorSchemes; + std::vector mFontSizes; std::string mSelectedVariant; std::string mOverrideVariant; std::string mSelectedColorScheme; + std::string mSelectedFontSize; static inline std::string sSelectedAspectRatio; static inline bool sAspectRatioMatch {false}; bool mCustomCollection; diff --git a/es-core/src/Window.cpp b/es-core/src/Window.cpp index dc9481ff1..2ca97d108 100644 --- a/es-core/src/Window.cpp +++ b/es-core/src/Window.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE Frontend // Window.cpp // // Window management, screensaver management, help prompts and splash screen. @@ -18,6 +18,10 @@ #include "guis/GuiInfoPopup.h" #include "resources/Font.h" +#if defined(__ANDROID__) +#include "InputOverlay.h" +#endif + #include #include @@ -144,6 +148,10 @@ bool Window::init() mDefaultFonts.at(1)->buildTextCache("Loading systems...", 0.0f, 0.0f, 0x777777FF)); mSplashTextReloading = std::unique_ptr( mDefaultFonts.at(1)->buildTextCache("Reloading...", 0.0f, 0.0f, 0x777777FF)); + mSplashTextResourceCopy = std::unique_ptr( + mDefaultFonts.at(1)->buildTextCache("Copying resources...", 0.0f, 0.0f, 0x777777FF)); + mSplashTextDirCreation = std::unique_ptr(mDefaultFonts.at(1)->buildTextCache( + "Creating system directories...", 0.0f, 0.0f, 0x777777FF)); mSplashTextPositions.x = (mRenderer->getScreenWidth() - mSplashTextScanning->metrics.size.x) / 2.0f; @@ -439,6 +447,11 @@ void Window::update(int deltaTime) if (mScreensaver && mRenderScreensaver) mScreensaver->update(deltaTime); + +#if defined(__ANDROID__) + if (Settings::getInstance()->getBool("InputTouchOverlay")) + InputOverlay::getInstance().update(deltaTime); +#endif } bool Window::isBackgroundDimmed() @@ -658,6 +671,11 @@ void Window::render() if (mRenderScreensaver) mScreensaver->renderScreensaver(); +#if defined(__ANDROID__) + if (Settings::getInstance()->getBool("InputTouchOverlay")) + InputOverlay::getInstance().render(mRenderer->getIdentity()); +#endif + if (Settings::getInstance()->getBool("DisplayGPUStatistics") && mFrameDataText) { mRenderer->setMatrix(mRenderer->getIdentity()); mDefaultFonts.at(1)->renderTextCache(mFrameDataText.get()); @@ -698,6 +716,12 @@ void Window::renderSplashScreen(SplashScreenState state, float progress) textPosX = mSplashTextPositions.w; textPosY += mDefaultFonts.at(1)->getLetterHeight(); } + else if (state == SplashScreenState::RESOURCE_COPY) { + textPosX = (mRenderer->getScreenWidth() - mSplashTextResourceCopy->metrics.size.x) / 2.0f; + } + else if (state == SplashScreenState::DIR_CREATION) { + textPosX = (mRenderer->getScreenWidth() - mSplashTextDirCreation->metrics.size.x) / 2.0f; + } trans = glm::translate(trans, glm::round(glm::vec3 {textPosX, textPosY, 0.0f})); mRenderer->setMatrix(trans); @@ -708,6 +732,10 @@ void Window::renderSplashScreen(SplashScreenState state, float progress) mDefaultFonts.at(1)->renderTextCache(mSplashTextPopulating.get()); else if (state == SplashScreenState::RELOADING) mDefaultFonts.at(1)->renderTextCache(mSplashTextReloading.get()); + else if (state == SplashScreenState::RESOURCE_COPY) + mDefaultFonts.at(1)->renderTextCache(mSplashTextResourceCopy.get()); + else if (state == SplashScreenState::DIR_CREATION) + mDefaultFonts.at(1)->renderTextCache(mSplashTextDirCreation.get()); mRenderer->swapBuffers(); } @@ -859,6 +887,10 @@ void Window::stopMediaViewer() void Window::startPDFViewer(FileData* game) { if (mPDFViewer) { +#if defined(ANDROID_LITE_RELEASE) + queueInfoPopup("PDF VIEWER ONLY AVAILABLE IN FULL VERSION", 6000); + return; +#endif if (mPDFViewer->startPDFViewer(game)) { setAllowTextScrolling(false); setAllowFileAnimation(false); diff --git a/es-core/src/Window.h b/es-core/src/Window.h index 198e8c2a7..95d166933 100644 --- a/es-core/src/Window.h +++ b/es-core/src/Window.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE Frontend // Window.h // // Window management, screensaver management, help prompts and splash screen. @@ -109,7 +109,9 @@ public: enum class SplashScreenState { SCANNING, POPULATING, - RELOADING + RELOADING, + RESOURCE_COPY, + DIR_CREATION }; void renderSplashScreen(SplashScreenState state, float progress); @@ -155,6 +157,7 @@ public: void invalidateCachedBackground(); bool isInvalidatingCachedBackground() { return mInvalidateCacheTimer > 0; } + std::vector& getGameEndEventParams() { return mGameEndEventParams; } bool getGameLaunchedState() { return mGameLaunchedState; } void setAllowTextScrolling(bool value) { mAllowTextScrolling = value; } bool getAllowTextScrolling() { return mAllowTextScrolling; } @@ -188,6 +191,8 @@ private: std::unique_ptr mSplashTextScanning; std::unique_ptr mSplashTextPopulating; std::unique_ptr mSplashTextReloading; + std::unique_ptr mSplashTextResourceCopy; + std::unique_ptr mSplashTextDirCreation; glm::vec4 mSplashTextPositions; std::vector mProgressBarRectangles; @@ -205,6 +210,7 @@ private: std::queue> mInfoPopupQueue; std::shared_ptr mPostprocessedBackground; + std::vector mGameEndEventParams; std::string mListScrollText; std::shared_ptr mListScrollFont; float mListScrollOpacity; @@ -221,9 +227,9 @@ private: bool mRenderMediaViewer; bool mRenderLaunchScreen; bool mRenderPDFViewer; - bool mGameLaunchedState; - bool mAllowTextScrolling; - bool mAllowFileAnimation; + std::atomic mGameLaunchedState; + std::atomic mAllowTextScrolling; + std::atomic mAllowFileAnimation; bool mCachedBackground; bool mInvalidatedCachedBackground; bool mInitiateCacheTimer; diff --git a/es-core/src/animations/Animation.h b/es-core/src/animations/Animation.h index 62c5a15f8..ac23926f0 100644 --- a/es-core/src/animations/Animation.h +++ b/es-core/src/animations/Animation.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Animation.h // // Animation base class. diff --git a/es-core/src/animations/AnimationController.cpp b/es-core/src/animations/AnimationController.cpp index f951802ca..7c8533aa0 100644 --- a/es-core/src/animations/AnimationController.cpp +++ b/es-core/src/animations/AnimationController.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AnimationController.cpp // // Basic animation controls. diff --git a/es-core/src/animations/AnimationController.h b/es-core/src/animations/AnimationController.h index a44d23072..ff64c6209 100644 --- a/es-core/src/animations/AnimationController.h +++ b/es-core/src/animations/AnimationController.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AnimationController.h // // Basic animation controls. diff --git a/es-core/src/animations/LambdaAnimation.h b/es-core/src/animations/LambdaAnimation.h index a6dea3ec1..c4fddfcbf 100644 --- a/es-core/src/animations/LambdaAnimation.h +++ b/es-core/src/animations/LambdaAnimation.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // LambdaAnimation.h // // Custom animations, expressed as lambdas. diff --git a/es-core/src/animations/MoveCameraAnimation.h b/es-core/src/animations/MoveCameraAnimation.h index ca3e47e3d..728cd2a6c 100644 --- a/es-core/src/animations/MoveCameraAnimation.h +++ b/es-core/src/animations/MoveCameraAnimation.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MoveCameraAnimation.h // // Animation to play when moving the camera, used by the slide transition style. diff --git a/es-core/src/components/AnimatedImageComponent.cpp b/es-core/src/components/AnimatedImageComponent.cpp index 169be0e63..8e640ca32 100644 --- a/es-core/src/components/AnimatedImageComponent.cpp +++ b/es-core/src/components/AnimatedImageComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AnimatedImageComponent.cpp // // Creates animation from multiple images files. diff --git a/es-core/src/components/AnimatedImageComponent.h b/es-core/src/components/AnimatedImageComponent.h index 396101afb..81622fcbd 100644 --- a/es-core/src/components/AnimatedImageComponent.h +++ b/es-core/src/components/AnimatedImageComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // AnimatedImageComponent.h // // Creates animation from multiple images files. diff --git a/es-core/src/components/BadgeComponent.cpp b/es-core/src/components/BadgeComponent.cpp index fa5fc95df..6673a7e8b 100644 --- a/es-core/src/components/BadgeComponent.cpp +++ b/es-core/src/components/BadgeComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // BadgeComponent.cpp // // Game badges icons. diff --git a/es-core/src/components/BadgeComponent.h b/es-core/src/components/BadgeComponent.h index e85dd0013..db26bf980 100644 --- a/es-core/src/components/BadgeComponent.h +++ b/es-core/src/components/BadgeComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // BadgeComponent.h // // Game badges icons. diff --git a/es-core/src/components/BusyComponent.cpp b/es-core/src/components/BusyComponent.cpp index 98e761198..56f915526 100644 --- a/es-core/src/components/BusyComponent.cpp +++ b/es-core/src/components/BusyComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // BusyComponent.cpp // // Animated busy indicator. diff --git a/es-core/src/components/BusyComponent.h b/es-core/src/components/BusyComponent.h index 4b7c54b8c..1a3cb5dcb 100644 --- a/es-core/src/components/BusyComponent.h +++ b/es-core/src/components/BusyComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // BusyComponent.h // // Animated busy indicator. diff --git a/es-core/src/components/ButtonComponent.cpp b/es-core/src/components/ButtonComponent.cpp index f7cbad97f..1fc36ff29 100644 --- a/es-core/src/components/ButtonComponent.cpp +++ b/es-core/src/components/ButtonComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ButtonComponent.cpp // // Basic on/off button. diff --git a/es-core/src/components/ButtonComponent.h b/es-core/src/components/ButtonComponent.h index afcbc1e21..af17cc3fc 100644 --- a/es-core/src/components/ButtonComponent.h +++ b/es-core/src/components/ButtonComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ButtonComponent.h // // Basic on/off button. diff --git a/es-core/src/components/ComponentGrid.cpp b/es-core/src/components/ComponentGrid.cpp index 1c6eb508c..507560eee 100644 --- a/es-core/src/components/ComponentGrid.cpp +++ b/es-core/src/components/ComponentGrid.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ComponentGrid.cpp // // Provides basic layout of components in an X*Y grid. diff --git a/es-core/src/components/ComponentGrid.h b/es-core/src/components/ComponentGrid.h index 0de281bee..41a471a4f 100644 --- a/es-core/src/components/ComponentGrid.h +++ b/es-core/src/components/ComponentGrid.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ComponentGrid.h // // Provides basic layout of components in an X*Y grid. diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index 5648ff6e5..f9debc3f1 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ComponentList.cpp // // Used to lay out and navigate lists in GUI menus. diff --git a/es-core/src/components/ComponentList.h b/es-core/src/components/ComponentList.h index 489f7143d..c416f0452 100644 --- a/es-core/src/components/ComponentList.h +++ b/es-core/src/components/ComponentList.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ComponentList.h // // Used to lay out and navigate lists in GUI menus. diff --git a/es-core/src/components/DateTimeComponent.cpp b/es-core/src/components/DateTimeComponent.cpp index 72872ca63..6e99ae444 100644 --- a/es-core/src/components/DateTimeComponent.cpp +++ b/es-core/src/components/DateTimeComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // DateTimeComponent.cpp // // Provides the date and time, in absolute (actual date) or relative diff --git a/es-core/src/components/DateTimeComponent.h b/es-core/src/components/DateTimeComponent.h index c6d20a36c..a952e7b34 100644 --- a/es-core/src/components/DateTimeComponent.h +++ b/es-core/src/components/DateTimeComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // DateTimeComponent.h // // Provides the date and time, in absolute (actual date) or relative diff --git a/es-core/src/components/DateTimeEditComponent.cpp b/es-core/src/components/DateTimeEditComponent.cpp index 01d964a51..ca01cf237 100644 --- a/es-core/src/components/DateTimeEditComponent.cpp +++ b/es-core/src/components/DateTimeEditComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // DateTimeEditComponent.cpp // // Date and time edit component. diff --git a/es-core/src/components/DateTimeEditComponent.h b/es-core/src/components/DateTimeEditComponent.h index 4dbf33391..cfb58b7e3 100644 --- a/es-core/src/components/DateTimeEditComponent.h +++ b/es-core/src/components/DateTimeEditComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // DateTimeEditComponent.h // // Date and time edit component. diff --git a/es-core/src/components/FlexboxComponent.cpp b/es-core/src/components/FlexboxComponent.cpp index f086dca14..b7f666bee 100644 --- a/es-core/src/components/FlexboxComponent.cpp +++ b/es-core/src/components/FlexboxComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FlexboxComponent.cpp // // Flexbox layout component. diff --git a/es-core/src/components/FlexboxComponent.h b/es-core/src/components/FlexboxComponent.h index 19deffe43..549f8a348 100644 --- a/es-core/src/components/FlexboxComponent.h +++ b/es-core/src/components/FlexboxComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FlexboxComponent.h // // Flexbox layout component. diff --git a/es-core/src/components/GIFAnimComponent.cpp b/es-core/src/components/GIFAnimComponent.cpp index 3d3d3d2b6..bcfbd026e 100644 --- a/es-core/src/components/GIFAnimComponent.cpp +++ b/es-core/src/components/GIFAnimComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GIFAnimComponent.cpp // // Component to play GIF animations. diff --git a/es-core/src/components/GIFAnimComponent.h b/es-core/src/components/GIFAnimComponent.h index bf9fdacaf..d43efdb9e 100644 --- a/es-core/src/components/GIFAnimComponent.h +++ b/es-core/src/components/GIFAnimComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GIFAnimComponent.h // // Component to play GIF animations. diff --git a/es-core/src/components/GameSelectorComponent.h b/es-core/src/components/GameSelectorComponent.h index 2d957dc8a..d856943bc 100644 --- a/es-core/src/components/GameSelectorComponent.h +++ b/es-core/src/components/GameSelectorComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GameSelectorComponent.h // // Makes a selection of games based on theme-controlled criteria. diff --git a/es-core/src/components/HelpComponent.cpp b/es-core/src/components/HelpComponent.cpp index a766c5ebd..fd42b8d65 100644 --- a/es-core/src/components/HelpComponent.cpp +++ b/es-core/src/components/HelpComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HelpComponent.cpp // // Help information in icon and text pairs. @@ -33,6 +33,18 @@ void HelpComponent::assignIcons() std::map sIconPathMapOld {sIconPathMap}; sIconPathMap.clear(); + std::string buttonA {"a"}; + std::string buttonB {"b"}; + std::string buttonX {"x"}; + std::string buttonY {"y"}; + + if (Settings::getInstance()->getBool("InputSwapButtons")) { + buttonA = "b"; + buttonB = "a"; + buttonX = "y"; + buttonY = "x"; + } + // These graphics files are common between all controller types. sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ? ":/graphics/help/dpad_updown.svg" : @@ -67,18 +79,18 @@ void HelpComponent::assignIcons() // These graphics files are custom per controller type. if (controllerType == "snes") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_SNES.empty() ? - ":/graphics/help/button_a_SNES.svg" : - mStyle.mCustomButtons.button_a_SNES; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_SNES.empty() ? - ":/graphics/help/button_b_SNES.svg" : - mStyle.mCustomButtons.button_b_SNES; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_SNES.empty() ? - ":/graphics/help/button_x_SNES.svg" : - mStyle.mCustomButtons.button_x_SNES; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_SNES.empty() ? - ":/graphics/help/button_y_SNES.svg" : - mStyle.mCustomButtons.button_y_SNES; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_SNES.empty() ? + ":/graphics/help/button_a_SNES.svg" : + mStyle.mCustomButtons.button_a_SNES; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_SNES.empty() ? + ":/graphics/help/button_b_SNES.svg" : + mStyle.mCustomButtons.button_b_SNES; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_SNES.empty() ? + ":/graphics/help/button_x_SNES.svg" : + mStyle.mCustomButtons.button_x_SNES; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_SNES.empty() ? + ":/graphics/help/button_y_SNES.svg" : + mStyle.mCustomButtons.button_y_SNES; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_SNES.empty() ? ":/graphics/help/button_back_SNES.svg" : mStyle.mCustomButtons.button_back_SNES; @@ -87,18 +99,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_SNES; } else if (controllerType == "switchpro") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_switch.empty() ? - ":/graphics/help/button_a_switch.svg" : - mStyle.mCustomButtons.button_a_switch; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_switch.empty() ? - ":/graphics/help/button_b_switch.svg" : - mStyle.mCustomButtons.button_b_switch; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_switch.empty() ? - ":/graphics/help/button_x_switch.svg" : - mStyle.mCustomButtons.button_x_switch; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_switch.empty() ? - ":/graphics/help/button_y_switch.svg" : - mStyle.mCustomButtons.button_y_switch; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_switch.empty() ? + ":/graphics/help/button_a_switch.svg" : + mStyle.mCustomButtons.button_a_switch; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_switch.empty() ? + ":/graphics/help/button_b_switch.svg" : + mStyle.mCustomButtons.button_b_switch; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_switch.empty() ? + ":/graphics/help/button_x_switch.svg" : + mStyle.mCustomButtons.button_x_switch; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_switch.empty() ? + ":/graphics/help/button_y_switch.svg" : + mStyle.mCustomButtons.button_y_switch; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_switch.empty() ? ":/graphics/help/button_back_switch.svg" : mStyle.mCustomButtons.button_back_switch; @@ -107,18 +119,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_switch; } else if (controllerType == "ps123") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS123.empty() ? ":/graphics/help/button_back_PS123.svg" : mStyle.mCustomButtons.button_back_PS123; @@ -127,18 +139,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_PS123; } else if (controllerType == "ps4") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS4.empty() ? ":/graphics/help/button_back_PS4.svg" : mStyle.mCustomButtons.button_back_PS4; @@ -147,18 +159,18 @@ void HelpComponent::assignIcons() mStyle.mCustomButtons.button_start_PS4; } else if (controllerType == "ps5") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_PS.empty() ? - ":/graphics/help/button_a_PS.svg" : - mStyle.mCustomButtons.button_a_PS; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_PS.empty() ? - ":/graphics/help/button_b_PS.svg" : - mStyle.mCustomButtons.button_b_PS; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_PS.empty() ? - ":/graphics/help/button_x_PS.svg" : - mStyle.mCustomButtons.button_x_PS; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_PS.empty() ? - ":/graphics/help/button_y_PS.svg" : - mStyle.mCustomButtons.button_y_PS; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_PS.empty() ? + ":/graphics/help/button_a_PS.svg" : + mStyle.mCustomButtons.button_a_PS; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_PS.empty() ? + ":/graphics/help/button_b_PS.svg" : + mStyle.mCustomButtons.button_b_PS; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_PS.empty() ? + ":/graphics/help/button_x_PS.svg" : + mStyle.mCustomButtons.button_x_PS; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_PS.empty() ? + ":/graphics/help/button_y_PS.svg" : + mStyle.mCustomButtons.button_y_PS; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_PS5.empty() ? ":/graphics/help/button_back_PS5.svg" : mStyle.mCustomButtons.button_back_PS5; @@ -168,18 +180,18 @@ void HelpComponent::assignIcons() } else if (controllerType == "xbox360") { - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? - ":/graphics/help/button_a_XBOX.svg" : - mStyle.mCustomButtons.button_a_XBOX; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? - ":/graphics/help/button_b_XBOX.svg" : - mStyle.mCustomButtons.button_b_XBOX; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? - ":/graphics/help/button_x_XBOX.svg" : - mStyle.mCustomButtons.button_x_XBOX; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? - ":/graphics/help/button_y_XBOX.svg" : - mStyle.mCustomButtons.button_y_XBOX; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ? + ":/graphics/help/button_a_XBOX.svg" : + mStyle.mCustomButtons.button_a_XBOX; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ? + ":/graphics/help/button_b_XBOX.svg" : + mStyle.mCustomButtons.button_b_XBOX; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ? + ":/graphics/help/button_x_XBOX.svg" : + mStyle.mCustomButtons.button_x_XBOX; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ? + ":/graphics/help/button_y_XBOX.svg" : + mStyle.mCustomButtons.button_y_XBOX; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX360.empty() ? ":/graphics/help/button_back_XBOX360.svg" : mStyle.mCustomButtons.button_back_XBOX360; @@ -189,18 +201,18 @@ void HelpComponent::assignIcons() } else { // Xbox One and later. - sIconPathMap["a"] = mStyle.mCustomButtons.button_a_XBOX.empty() ? - ":/graphics/help/button_a_XBOX.svg" : - mStyle.mCustomButtons.button_a_XBOX; - sIconPathMap["b"] = mStyle.mCustomButtons.button_b_XBOX.empty() ? - ":/graphics/help/button_b_XBOX.svg" : - mStyle.mCustomButtons.button_b_XBOX; - sIconPathMap["x"] = mStyle.mCustomButtons.button_x_XBOX.empty() ? - ":/graphics/help/button_x_XBOX.svg" : - mStyle.mCustomButtons.button_x_XBOX; - sIconPathMap["y"] = mStyle.mCustomButtons.button_y_XBOX.empty() ? - ":/graphics/help/button_y_XBOX.svg" : - mStyle.mCustomButtons.button_y_XBOX; + sIconPathMap[buttonA] = mStyle.mCustomButtons.button_a_XBOX.empty() ? + ":/graphics/help/button_a_XBOX.svg" : + mStyle.mCustomButtons.button_a_XBOX; + sIconPathMap[buttonB] = mStyle.mCustomButtons.button_b_XBOX.empty() ? + ":/graphics/help/button_b_XBOX.svg" : + mStyle.mCustomButtons.button_b_XBOX; + sIconPathMap[buttonX] = mStyle.mCustomButtons.button_x_XBOX.empty() ? + ":/graphics/help/button_x_XBOX.svg" : + mStyle.mCustomButtons.button_x_XBOX; + sIconPathMap[buttonY] = mStyle.mCustomButtons.button_y_XBOX.empty() ? + ":/graphics/help/button_y_XBOX.svg" : + mStyle.mCustomButtons.button_y_XBOX; sIconPathMap["back"] = mStyle.mCustomButtons.button_back_XBOX.empty() ? ":/graphics/help/button_back_XBOX.svg" : mStyle.mCustomButtons.button_back_XBOX; diff --git a/es-core/src/components/HelpComponent.h b/es-core/src/components/HelpComponent.h index dfdc36abc..f55acadb8 100644 --- a/es-core/src/components/HelpComponent.h +++ b/es-core/src/components/HelpComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // HelpComponent.h // // Help information in icon and text pairs. diff --git a/es-core/src/components/IList.h b/es-core/src/components/IList.h index 1f85a5bab..fc5145223 100644 --- a/es-core/src/components/IList.h +++ b/es-core/src/components/IList.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // IList.h // // List base class, used by the system view, gamelist view and menu system. diff --git a/es-core/src/components/ImageComponent.cpp b/es-core/src/components/ImageComponent.cpp index 1f80e2f25..37f59a7e0 100644 --- a/es-core/src/components/ImageComponent.cpp +++ b/es-core/src/components/ImageComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ImageComponent.cpp // // Handles images: loading, resizing, cropping, color shifting etc. @@ -462,6 +462,15 @@ void ImageComponent::render(const glm::mat4& parentTrans) } mVertices->shaderFlags = mVertices->shaderFlags | Renderer::ShaderFlags::PREMULTIPLIED; + +#if defined(USE_OPENGLES) + // This is required as not all mobile GPUs support mipmapping when using the BGRA + // pixel format. + if (mMipmapping) + mVertices->shaderFlags = + mVertices->shaderFlags | Renderer::ShaderFlags::CONVERT_PIXEL_FORMAT; +#endif + mRenderer->drawTriangleStrips(&mVertices[0], 4); } else { @@ -548,6 +557,9 @@ void ImageComponent::applyTheme(const std::shared_ptr& theme, << element.substr(6) << "\" defined as \"" << stationary << "\""; } + if (elem->has("renderDuringTransitions")) + mRenderDuringTransitions = elem->get("renderDuringTransitions"); + // Enable linear interpolation by default if element is arbitrarily rotated. if (properties & ThemeFlags::ROTATION && elem->has("rotation")) { const float rotation {std::abs(elem->get("rotation"))}; diff --git a/es-core/src/components/ImageComponent.h b/es-core/src/components/ImageComponent.h index ed2747fc4..90c7a385b 100644 --- a/es-core/src/components/ImageComponent.h +++ b/es-core/src/components/ImageComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ImageComponent.h // // Handles images: loading, resizing, cropping, color shifting etc. diff --git a/es-core/src/components/LottieAnimComponent.cpp b/es-core/src/components/LottieAnimComponent.cpp index ce2b57490..8c92e0915 100644 --- a/es-core/src/components/LottieAnimComponent.cpp +++ b/es-core/src/components/LottieAnimComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // LottieAnimComponent.cpp // // Component to play Lottie animations using the rlottie library. diff --git a/es-core/src/components/LottieAnimComponent.h b/es-core/src/components/LottieAnimComponent.h index bae80e309..d96829941 100644 --- a/es-core/src/components/LottieAnimComponent.h +++ b/es-core/src/components/LottieAnimComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // LottieAnimComponent.h // // Component to play Lottie animations using the rlottie library. diff --git a/es-core/src/components/MenuComponent.cpp b/es-core/src/components/MenuComponent.cpp index bda94fced..8b40de4ae 100644 --- a/es-core/src/components/MenuComponent.cpp +++ b/es-core/src/components/MenuComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MenuComponent.cpp // // Basic component for building a menu. diff --git a/es-core/src/components/MenuComponent.h b/es-core/src/components/MenuComponent.h index 31f1dfbfe..cb6100e5f 100644 --- a/es-core/src/components/MenuComponent.h +++ b/es-core/src/components/MenuComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MenuComponent.h // // Basic component for building a menu. diff --git a/es-core/src/components/NinePatchComponent.cpp b/es-core/src/components/NinePatchComponent.cpp index 6a3b2ad6d..321422b61 100644 --- a/es-core/src/components/NinePatchComponent.cpp +++ b/es-core/src/components/NinePatchComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // NinePatchComponent.cpp // // Breaks up an image into 3x3 patches to accomodate resizing without distortions. diff --git a/es-core/src/components/NinePatchComponent.h b/es-core/src/components/NinePatchComponent.h index 010c231e5..d7473b5cc 100644 --- a/es-core/src/components/NinePatchComponent.h +++ b/es-core/src/components/NinePatchComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // NinePatchComponent.h // // Breaks up an image into 3x3 patches to accomodate resizing without distortions. diff --git a/es-core/src/components/OptionListComponent.h b/es-core/src/components/OptionListComponent.h index e8a38a908..14106ac6f 100644 --- a/es-core/src/components/OptionListComponent.h +++ b/es-core/src/components/OptionListComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // OptionListComponent.h // // Provides a list of option components. diff --git a/es-core/src/components/RatingComponent.cpp b/es-core/src/components/RatingComponent.cpp index 6523d85a6..7785963c7 100644 --- a/es-core/src/components/RatingComponent.cpp +++ b/es-core/src/components/RatingComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // RatingComponent.cpp // // Game rating icons. @@ -21,6 +21,7 @@ RatingComponent::RatingComponent(bool colorizeChanges, bool linearInterpolation) , mColorChangedValue {mMenuColorPrimary} , mColorizeChanges {colorizeChanges} , mOverlay {true} + , mHideIfZero {false} { mSize = glm::vec2 {std::round(mRenderer->getScreenHeight() * 0.06f) * NUM_RATING_STARS, std::round(mRenderer->getScreenHeight() * 0.06f)}; @@ -127,6 +128,9 @@ void RatingComponent::render(const glm::mat4& parentTrans) if (!isVisible() || mThemeOpacity == 0.0f || mOpacity == 0.0f) return; + if (mHideIfZero && mValue == 0.0f) + return; + glm::mat4 trans {parentTrans * getTransform()}; mIconUnfilled.setOpacity(mOpacity * mThemeOpacity); @@ -227,6 +231,9 @@ void RatingComponent::applyTheme(const std::shared_ptr& theme, << element.substr(7) << "\" defined as \"" << stationary << "\""; } + if (elem->has("hideIfZero")) + mHideIfZero = elem->get("hideIfZero"); + bool linearInterpolation {false}; // Enable linear interpolation by default if element is arbitrarily rotated. diff --git a/es-core/src/components/RatingComponent.h b/es-core/src/components/RatingComponent.h index e036e9b31..b0ebe872d 100644 --- a/es-core/src/components/RatingComponent.h +++ b/es-core/src/components/RatingComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // RatingComponent.h // // Game rating icons. @@ -61,6 +61,7 @@ private: bool mColorizeChanges; bool mOverlay; + bool mHideIfZero; }; #endif // ES_APP_COMPONENTS_RATING_COMPONENT_H diff --git a/es-core/src/components/ScrollIndicatorComponent.h b/es-core/src/components/ScrollIndicatorComponent.h index f9913351b..efc55bb85 100644 --- a/es-core/src/components/ScrollIndicatorComponent.h +++ b/es-core/src/components/ScrollIndicatorComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ScrollIndicatorComponent.h // // Visually indicates whether a menu can be scrolled (up, up/down or down). diff --git a/es-core/src/components/ScrollableContainer.cpp b/es-core/src/components/ScrollableContainer.cpp index f64a1c8b4..14bd609e7 100644 --- a/es-core/src/components/ScrollableContainer.cpp +++ b/es-core/src/components/ScrollableContainer.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ScrollableContainer.cpp // // Component containing scrollable information, used for the game diff --git a/es-core/src/components/ScrollableContainer.h b/es-core/src/components/ScrollableContainer.h index 966b691c3..8b1e14844 100644 --- a/es-core/src/components/ScrollableContainer.h +++ b/es-core/src/components/ScrollableContainer.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ScrollableContainer.h // // Component containing scrollable information, used for the game diff --git a/es-core/src/components/SliderComponent.cpp b/es-core/src/components/SliderComponent.cpp index 00de12644..cbeef8e59 100644 --- a/es-core/src/components/SliderComponent.cpp +++ b/es-core/src/components/SliderComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SliderComponent.cpp // // Slider to set value in a predefined range. diff --git a/es-core/src/components/SliderComponent.h b/es-core/src/components/SliderComponent.h index b83cb10e1..2f2188d6a 100644 --- a/es-core/src/components/SliderComponent.h +++ b/es-core/src/components/SliderComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SliderComponent.h // // Slider to set value in a predefined range. diff --git a/es-core/src/components/SwitchComponent.cpp b/es-core/src/components/SwitchComponent.cpp index a7fc3031a..506533370 100644 --- a/es-core/src/components/SwitchComponent.cpp +++ b/es-core/src/components/SwitchComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SwitchComponent.cpp // // Basic on/off switch used in menus. diff --git a/es-core/src/components/SwitchComponent.h b/es-core/src/components/SwitchComponent.h index 25a2dc8f0..6e02ec0be 100644 --- a/es-core/src/components/SwitchComponent.h +++ b/es-core/src/components/SwitchComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SwitchComponent.h // // Basic on/off switch used in menus. diff --git a/es-core/src/components/TextComponent.cpp b/es-core/src/components/TextComponent.cpp index 0f4dc1f95..715a70045 100644 --- a/es-core/src/components/TextComponent.cpp +++ b/es-core/src/components/TextComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextComponent.cpp // // Displays text. @@ -691,7 +691,10 @@ void TextComponent::applyTheme(const std::shared_ptr& theme, mThemeMetadata = type; if (elem->has("defaultValue")) { if (mThemeMetadata == "developer" || mThemeMetadata == "publisher" || - mThemeMetadata == "genre" || mThemeMetadata == "players") { + mThemeMetadata == "genre" || mThemeMetadata == "players" || + mThemeMetadata == "systemName" || mThemeMetadata == "systemFullname" || + mThemeMetadata == "sourceSystemName" || + mThemeMetadata == "sourceSystemFullname") { const std::string& defaultValue {elem->get("defaultValue")}; if (defaultValue == ":space:") mDefaultValue = " "; diff --git a/es-core/src/components/TextComponent.h b/es-core/src/components/TextComponent.h index 7e180746b..837c8c92e 100644 --- a/es-core/src/components/TextComponent.h +++ b/es-core/src/components/TextComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextComponent.h // // Displays text. @@ -62,6 +62,8 @@ public: std::string getHiddenValue() const override { return mHiddenText; } void setHiddenValue(const std::string& value) override { setHiddenText(value); } + const std::string getDefaultValue() const { return mDefaultValue; } + float const getOpacity() const override { return static_cast((mColor & 0x000000FF) / 255.0f); diff --git a/es-core/src/components/TextEditComponent.cpp b/es-core/src/components/TextEditComponent.cpp index a895f01e3..87475188b 100644 --- a/es-core/src/components/TextEditComponent.cpp +++ b/es-core/src/components/TextEditComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextEditComponent.cpp // // Component for editing text fields in menus. @@ -79,8 +79,10 @@ void TextEditComponent::setValue(const std::string& val) void TextEditComponent::textInput(const std::string& text, const bool pasting) { +#if !defined(__ANDROID__) if (mMaskInput && !pasting) return; +#endif // Allow pasting up to a reasonable max clipboard size. if (pasting && text.length() > (isMultiline() ? 16384 : 300)) @@ -128,6 +130,9 @@ std::string TextEditComponent::getValue() const void TextEditComponent::startEditing() { + if (mEditing) + return; + SDL_StartTextInput(); mEditing = true; updateHelpPrompts(); @@ -136,6 +141,9 @@ void TextEditComponent::startEditing() void TextEditComponent::stopEditing() { + if (!mEditing) + return; + SDL_StopTextInput(); mEditing = false; mMaskInput = false; @@ -197,11 +205,13 @@ bool TextEditComponent::input(InputConfig* config, Input input) } return true; } +#if !defined(__ANDROID__) else if (input.id == SDLK_BACKSPACE) { mMaskInput = false; textInput("\b"); return true; } +#endif } if (cursorLeft || cursorRight) { @@ -211,7 +221,7 @@ bool TextEditComponent::input(InputConfig* config, Input input) moveCursor(mCursorRepeatDir); return false; } - else if (cursorDown) { + else if (cursorDown && isEditing()) { // Stop editing and let the button down event be captured by the parent component. stopEditing(); return false; @@ -234,6 +244,9 @@ bool TextEditComponent::input(InputConfig* config, Input input) return true; } + if (config->isMappedTo("b", input)) + stopEditing(); + // Consume all input when editing text. mMaskInput = false; return true; diff --git a/es-core/src/components/TextEditComponent.h b/es-core/src/components/TextEditComponent.h index a9e35fa06..a4c1fcb58 100644 --- a/es-core/src/components/TextEditComponent.h +++ b/es-core/src/components/TextEditComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextEditComponent.h // // Component for editing text fields in menus. diff --git a/es-core/src/components/VideoComponent.cpp b/es-core/src/components/VideoComponent.cpp index 8e8b2f9a5..af20c72e9 100644 --- a/es-core/src/components/VideoComponent.cpp +++ b/es-core/src/components/VideoComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VideoComponent.cpp // // Base class for playing videos. @@ -14,8 +14,6 @@ #include "utils/FileSystemUtil.h" #include "utils/StringUtil.h" -#include - #define SCREENSAVER_FADE_IN_TIME 900 #define MEDIA_VIEWER_FADE_IN_TIME 600 diff --git a/es-core/src/components/VideoComponent.h b/es-core/src/components/VideoComponent.h index ccc4afe12..a9347c567 100644 --- a/es-core/src/components/VideoComponent.h +++ b/es-core/src/components/VideoComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VideoComponent.h // // Base class for playing videos. @@ -15,6 +15,8 @@ #include #include +#include + class MediaViewer; class TextureResource; @@ -84,6 +86,9 @@ public: virtual void stopVideoPlayer(bool muteAudio = true) {} virtual void pauseVideoPlayer() {} + // Needed on Android to reset the static image delay timer on activity resume. + void resetVideoPlayerTimer() { mStartTime = SDL_GetTicks() + mConfig.startDelay; } + // Handle looping of the video. Must be called periodically. virtual void handleLooping() {} // Used to immediately mute audio even if there are still samples to play in the buffer. diff --git a/es-core/src/components/VideoFFmpegComponent.cpp b/es-core/src/components/VideoFFmpegComponent.cpp index 0d255b373..d8db22453 100644 --- a/es-core/src/components/VideoFFmpegComponent.cpp +++ b/es-core/src/components/VideoFFmpegComponent.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VideoFFmpegComponent.cpp // // Video player based on FFmpeg. @@ -189,6 +189,11 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans) mBlackFrame.render(trans); } + if (mDrawPillarboxes && (mBlackFrameOffset.x != 0.0f || mBlackFrameOffset.y != 0.0f)) { + trans = + glm::translate(trans, glm::vec3 {mBlackFrameOffset.x, mBlackFrameOffset.y, 0.0f}); + } + mRenderer->setMatrix(trans); // This is needed to avoid a slight gap before the video starts playing. @@ -196,10 +201,10 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans) return; // clang-format off - vertices[0] = {{0.0f + mBlackFrameOffset.x, 0.0f + mBlackFrameOffset.y }, {mTopLeftCrop.x, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF}; - vertices[1] = {{0.0f + mBlackFrameOffset.x, mSize.y + mBlackFrameOffset.y }, {mTopLeftCrop.x, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF}; - vertices[2] = {{mSize.x + mBlackFrameOffset.x, 0.0f + + mBlackFrameOffset.y }, {mBottomRightCrop.x * 1.0f, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF}; - vertices[3] = {{mSize.x + mBlackFrameOffset.x, mSize.y + + mBlackFrameOffset.y}, {mBottomRightCrop.x * 1.0f, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF}; + vertices[0] = {{0.0f, 0.0f }, {mTopLeftCrop.x, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF}; + vertices[1] = {{0.0f, mSize.y}, {mTopLeftCrop.x, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF}; + vertices[2] = {{mSize.x, 0.0f }, {mBottomRightCrop.x * 1.0f, 1.0f - mBottomRightCrop.y}, 0xFFFFFFFF}; + vertices[3] = {{mSize.x, mSize.y}, {mBottomRightCrop.x * 1.0f, 1.0f - mTopLeftCrop.y }, 0xFFFFFFFF}; // clang-format on vertices[0].color = mColorShift; @@ -219,12 +224,26 @@ void VideoFFmpegComponent::render(const glm::mat4& parentTrans) vertices->dimming = mDimming; if (mVideoCornerRadius > 0.0f) { - // We don't want to apply anti-aliasing to rounded corners as the black frame is - // rendered behind the video and that would generate ugly edge artifacts for any - // videos with lighter content. - vertices->cornerRadius = mVideoCornerRadius; - vertices->shaderFlags = - vertices->shaderFlags | Renderer::ShaderFlags::ROUNDED_CORNERS_NO_AA; + // Don't round the corners for the video frame if pillarboxes are enabled. + // For extreme roundings it will still get applied though as we don't want the + // video content to render outside the black frame. + bool renderVideoCorners {true}; + if (mDrawPillarboxes) { + if (mBlackFrame.getSize().x > mSize.x && + mBlackFrame.getSize().x - mSize.x >= mVideoCornerRadius * 2.0f) + renderVideoCorners = false; + else if (mBlackFrame.getSize().y > mSize.y && + mBlackFrame.getSize().y - mSize.y >= mVideoCornerRadius * 2.0f) + renderVideoCorners = false; + } + if (renderVideoCorners) { + vertices->cornerRadius = mVideoCornerRadius; + // We don't want to apply anti-aliasing to rounded corners as the black frame is + // rendered behind the video and that would generate ugly edge artifacts for any + // videos with lighter content. + vertices->shaderFlags = + vertices->shaderFlags | Renderer::ShaderFlags::ROUNDED_CORNERS_NO_AA; + } } std::unique_lock pictureLock {mPictureMutex}; @@ -291,6 +310,29 @@ void VideoFFmpegComponent::updatePlayer() if (mPaused || !mFormatContext) return; + const long double deltaTime { + static_cast(std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - mTimeReference) + .count()) / + 1000000000.0l}; + + // If there were more than 1.2 seconds since the last update then it's not a normal delay, for + // example the application may have been suspended or the computer may have been resumed from + // sleep. In this case don't proceed and instead wait for the next update. This avoids a + // massive fast-forward as the frame processing would otherwise have tried to catch up. + // The frame queues are emptied as well and the audio stream is cleared in order to + // re-synchronize the streams. This is neeeded as some platforms like Android keep processing + // the audio buffers before suspending the application (i.e. after rendering has stopped). + if (deltaTime > 1.2) { + AudioManager::getInstance().clearStream(); + mTimeReference = std::chrono::high_resolution_clock::now(); + while (mAudioFrameQueue.size() > 1 && mVideoFrameQueue.size() > 1 && + mAudioFrameQueue.front().pts > mVideoFrameQueue.front().pts) { + mVideoFrameQueue.pop(); + } + return; + } + // Output any audio that has been added by the processing thread. std::unique_lock audioLock {mAudioMutex}; if (mOutputAudio.size()) { @@ -299,14 +341,8 @@ void VideoFFmpegComponent::updatePlayer() mOutputAudio.clear(); } - if (mIsActuallyPlaying && mStartTimeAccumulation) { - mAccumulatedTime = - mAccumulatedTime + - static_cast(std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - mTimeReference) - .count()) / - 1000000000.0l; - } + if (mIsActuallyPlaying && mStartTimeAccumulation) + mAccumulatedTime = mAccumulatedTime + static_cast(deltaTime); mTimeReference = std::chrono::high_resolution_clock::now(); diff --git a/es-core/src/components/VideoFFmpegComponent.h b/es-core/src/components/VideoFFmpegComponent.h index e2294ce69..85ccdcf39 100644 --- a/es-core/src/components/VideoFFmpegComponent.h +++ b/es-core/src/components/VideoFFmpegComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // VideoFFmpegComponent.h // // Video player based on FFmpeg. diff --git a/es-core/src/components/primary/CarouselComponent.h b/es-core/src/components/primary/CarouselComponent.h index 9b57fce1f..76ba383de 100644 --- a/es-core/src/components/primary/CarouselComponent.h +++ b/es-core/src/components/primary/CarouselComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CarouselComponent.h // // Carousel, usable in both the system and gamelist views. diff --git a/es-core/src/components/primary/GridComponent.h b/es-core/src/components/primary/GridComponent.h index f2bbd4214..939edc5e2 100644 --- a/es-core/src/components/primary/GridComponent.h +++ b/es-core/src/components/primary/GridComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GridComponent.h // // Grid, usable in both the system and gamelist views. @@ -675,7 +675,7 @@ template void GridComponent::render(const glm::mat4& parentTrans int loadedItems {0}; if (currRow > 0) { - if (GuiComponent::isAnimationPlaying(0) || mItemSpacing.y < mVerticalMargin) { + if (GuiComponent::isAnimationPlaying(0) || mItemSpacing.y <= mVerticalMargin) { loadItems += mColumns; startPos = (currRow - 1) * mColumns; } diff --git a/es-core/src/components/primary/PrimaryComponent.h b/es-core/src/components/primary/PrimaryComponent.h index 5af99735c..613c3821e 100644 --- a/es-core/src/components/primary/PrimaryComponent.h +++ b/es-core/src/components/primary/PrimaryComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // PrimaryComponent.h // // Base class for the primary components (carousel, grid and textlist). diff --git a/es-core/src/components/primary/TextListComponent.h b/es-core/src/components/primary/TextListComponent.h index 204d4014b..069b5663d 100644 --- a/es-core/src/components/primary/TextListComponent.h +++ b/es-core/src/components/primary/TextListComponent.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextListComponent.h // // Text list, usable in both the system and gamelist views. @@ -123,6 +123,7 @@ private: bool mGamelistView; std::shared_ptr mFont; + float mSelectorWidth; float mSelectorHeight; float mSelectorHorizontalOffset; float mSelectorVerticalOffset; @@ -162,6 +163,7 @@ TextListComponent::TextListComponent() , mPreviousScrollVelocity {0} , mGamelistView {std::is_same_v ? true : false} , mFont {Font::get(FONT_SIZE_MEDIUM_FIXED)} + , mSelectorWidth {mSize.x} , mSelectorHeight {mFont->getSize() * 1.5f} , mSelectorHorizontalOffset {0.0f} , mSelectorVerticalOffset {0.0f} @@ -330,7 +332,7 @@ template void TextListComponent::render(const glm::mat4& parentT mRenderer->setMatrix(trans); mRenderer->drawRect(mSelectorHorizontalOffset, (mCursor - startEntry) * entrySize + mSelectorVerticalOffset, - mSize.x, mSelectorHeight, mSelectorColor, mSelectorColorEnd, + mSelectorWidth, mSelectorHeight, mSelectorColor, mSelectorColorEnd, mSelectorColorGradientHorizontal); } } @@ -670,12 +672,23 @@ void TextListComponent::applyTheme(const std::shared_ptr& theme, } } + mSize.x = glm::clamp(mSize.x, mRenderer->getScreenWidth() * 0.05f, + mRenderer->getScreenWidth() * 1.0f); + mSize.y = glm::clamp(mSize.y, mRenderer->getScreenHeight() * 0.05f, + mRenderer->getScreenHeight() * 1.0f); + + if (elem->has("selectorWidth")) + mSelectorWidth = + glm::clamp(elem->get("selectorWidth"), 0.0f, 1.0f) * Renderer::getScreenWidth(); + else + mSelectorWidth = mSize.x; + if (elem->has("selectorImagePath")) { const std::string& path {elem->get("selectorImagePath")}; bool tile {elem->has("selectorImageTile") && elem->get("selectorImageTile")}; mSelectorImage.setImage(path, tile); - mSelectorImage.setSize(mSize.x, mSelectorHeight); - mSelectorImage.setResize(mSize.x, mSelectorHeight); + mSelectorImage.setSize(mSelectorWidth, mSelectorHeight); + mSelectorImage.setResize(mSelectorWidth, mSelectorHeight); mSelectorImage.setColorShift(mSelectorColor); mSelectorImage.setColorShiftEnd(mSelectorColorEnd); } @@ -685,11 +698,6 @@ void TextListComponent::applyTheme(const std::shared_ptr& theme, if (elem->has("fadeAbovePrimary")) mFadeAbovePrimary = elem->get("fadeAbovePrimary"); - - mSize.x = glm::clamp(mSize.x, mRenderer->getScreenWidth() * 0.05f, - mRenderer->getScreenWidth() * 1.0f); - mSize.y = glm::clamp(mSize.y, mRenderer->getScreenHeight() * 0.05f, - mRenderer->getScreenHeight() * 1.0f); } template void TextListComponent::onCursorChanged(const CursorState& state) diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index 86762de32..f7056c90d 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiDetectDevice.cpp // // Detect input devices (keyboards, joysticks and gamepads). diff --git a/es-core/src/guis/GuiDetectDevice.h b/es-core/src/guis/GuiDetectDevice.h index df8980cd2..d040e0ad4 100644 --- a/es-core/src/guis/GuiDetectDevice.h +++ b/es-core/src/guis/GuiDetectDevice.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiDetectDevice.h // // Detect input devices (keyboards, joysticks and gamepads). diff --git a/es-core/src/guis/GuiInfoPopup.cpp b/es-core/src/guis/GuiInfoPopup.cpp index c242e75b5..b07767f5b 100644 --- a/es-core/src/guis/GuiInfoPopup.cpp +++ b/es-core/src/guis/GuiInfoPopup.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiInfoPopup.cpp // // Popup window used for user notifications. diff --git a/es-core/src/guis/GuiInfoPopup.h b/es-core/src/guis/GuiInfoPopup.h index 8be3daa98..3f8dc120f 100644 --- a/es-core/src/guis/GuiInfoPopup.h +++ b/es-core/src/guis/GuiInfoPopup.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiInfoPopup.h // // Popup window used for user notifications. diff --git a/es-core/src/guis/GuiInputConfig.cpp b/es-core/src/guis/GuiInputConfig.cpp index ea45fe2fb..66a22d9c4 100644 --- a/es-core/src/guis/GuiInputConfig.cpp +++ b/es-core/src/guis/GuiInputConfig.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiInputConfig.cpp // // Input device configuration GUI (for keyboards, joysticks and gamepads). diff --git a/es-core/src/guis/GuiInputConfig.h b/es-core/src/guis/GuiInputConfig.h index f526c747d..5410cd6da 100644 --- a/es-core/src/guis/GuiInputConfig.h +++ b/es-core/src/guis/GuiInputConfig.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiInputConfig.h // // Input device configuration GUI (for keyboards, joysticks and gamepads). diff --git a/es-core/src/guis/GuiMsgBox.cpp b/es-core/src/guis/GuiMsgBox.cpp index 12ef4a155..eeed306db 100644 --- a/es-core/src/guis/GuiMsgBox.cpp +++ b/es-core/src/guis/GuiMsgBox.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMsgBox.cpp // // Popup message dialog with a notification text and a choice of one, diff --git a/es-core/src/guis/GuiMsgBox.h b/es-core/src/guis/GuiMsgBox.h index c751eda65..ae60deeac 100644 --- a/es-core/src/guis/GuiMsgBox.h +++ b/es-core/src/guis/GuiMsgBox.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMsgBox.h // // Popup message dialog with a notification text and a choice of one, diff --git a/es-core/src/guis/GuiTextEditKeyboardPopup.cpp b/es-core/src/guis/GuiTextEditKeyboardPopup.cpp index 43a5dfeed..4611adced 100644 --- a/es-core/src/guis/GuiTextEditKeyboardPopup.cpp +++ b/es-core/src/guis/GuiTextEditKeyboardPopup.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiTextEditKeyboardPopup.cpp // // Text edit popup with a virtual keyboard. @@ -378,15 +378,15 @@ bool GuiTextEditKeyboardPopup::input(InputConfig* config, Input input) "", nullptr, nullptr, true)); } else { + if (mText->isEditing()) + mText->stopEditing(); delete this; return true; } } - if (mText->isEditing() && config->isMappedLike("down", input) && input.value) { - mText->stopEditing(); + if (mText->isEditing() && config->isMappedLike("down", input) && input.value) mGrid.setCursorTo(mGrid.getSelectedComponent()); - } // Left trigger button outside text editing field toggles Shift key. if (!mText->isEditing() && config->isMappedLike("lefttrigger", input) && input.value) diff --git a/es-core/src/guis/GuiTextEditKeyboardPopup.h b/es-core/src/guis/GuiTextEditKeyboardPopup.h index 5f6e4e208..b7708b353 100644 --- a/es-core/src/guis/GuiTextEditKeyboardPopup.h +++ b/es-core/src/guis/GuiTextEditKeyboardPopup.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiTextEditKeyboardPopup.h // // Text edit popup with a virtual keyboard. diff --git a/es-core/src/guis/GuiTextEditPopup.cpp b/es-core/src/guis/GuiTextEditPopup.cpp index 1565d23f1..55b1c22d0 100644 --- a/es-core/src/guis/GuiTextEditPopup.cpp +++ b/es-core/src/guis/GuiTextEditPopup.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiTextEditPopup.cpp // // Text edit popup. @@ -97,8 +97,13 @@ GuiTextEditPopup::GuiTextEditPopup(const HelpStyle& helpstyle, float textHeight = mText->getFont()->getHeight(); +#if defined(__ANDROID__) + if (multiLine) + textHeight *= 2.0f; +#else if (multiLine) textHeight *= 6.0f; +#endif mText->setSize(0.0f, textHeight); @@ -115,16 +120,27 @@ GuiTextEditPopup::GuiTextEditPopup(const HelpStyle& helpstyle, setSize(windowWidth, mTitle->getFont()->getHeight() + textHeight + mButtonGrid->getSize().y + mButtonGrid->getSize().y * 1.85f); +#if defined(__ANDROID__) + setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f, + Font::get(FONT_SIZE_LARGE_FIXED)->getLetterHeight()); +#else setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f, (Renderer::getScreenHeight() - mSize.y) / 2.0f); +#endif } else { float width = glm::clamp(0.54f * aspectValue, 0.20f, 0.70f) * Renderer::getScreenWidth(); setSize(width, mTitle->getFont()->getHeight() + textHeight + mButtonGrid->getSize().y + mButtonGrid->getSize().y / 2.0f); + +#if defined(__ANDROID__) + setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f, + Font::get(FONT_SIZE_LARGE_FIXED)->getLetterHeight()); +#else setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f, (Renderer::getScreenHeight() - mSize.y) / 2.0f); +#endif } if (!multiLine) @@ -189,15 +205,15 @@ bool GuiTextEditPopup::input(InputConfig* config, Input input) "", nullptr, nullptr, true)); } else { + if (mText->isEditing()) + mText->stopEditing(); delete this; return true; } } - if (mText->isEditing() && config->isMappedLike("down", input) && input.value) { - mText->stopEditing(); + if (mText->isEditing() && config->isMappedLike("down", input) && input.value) mGrid.setCursorTo(mGrid.getSelectedComponent()); - } // Left shoulder button deletes a character (backspace). if (config->isMappedTo("leftshoulder", input)) { diff --git a/es-core/src/guis/GuiTextEditPopup.h b/es-core/src/guis/GuiTextEditPopup.h index f215b74b2..d1f29ca8c 100644 --- a/es-core/src/guis/GuiTextEditPopup.h +++ b/es-core/src/guis/GuiTextEditPopup.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiTextEditPopup.h // // Text edit popup. diff --git a/es-core/src/renderers/Renderer.cpp b/es-core/src/renderers/Renderer.cpp index ce60b5c94..33624d07c 100644 --- a/es-core/src/renderers/Renderer.cpp +++ b/es-core/src/renderers/Renderer.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Renderer.cpp // // Generic rendering functions. @@ -163,7 +163,7 @@ bool Renderer::createWindow() sScreenHeight = tempVal; } - if (sScreenHeight > sScreenWidth) + if (sScreenHeight >= sScreenWidth) sIsVerticalOrientation = true; else sIsVerticalOrientation = false; @@ -172,7 +172,7 @@ bool Renderer::createWindow() // games or when manually switching windows using the task switcher). SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); -#if defined(__unix__) +#if defined(__unix__) && !defined(__ANDROID__) // Disabling desktop composition can lead to better framerates and a more fluid user // interface, but with some drivers it can cause strange behaviors when returning to // the desktop. @@ -221,10 +221,9 @@ bool Renderer::createWindow() windowFlags = SDL_WINDOW_OPENGL; #endif - if ((mSDLWindow = - SDL_CreateWindow("EmulationStation", SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), - SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), mWindowWidth, - mWindowHeight, windowFlags)) == nullptr) { + if ((mSDLWindow = SDL_CreateWindow("ES-DE", SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), + SDL_WINDOWPOS_UNDEFINED_DISPLAY(displayIndex), mWindowWidth, + mWindowHeight, windowFlags)) == nullptr) { LOG(LogError) << "Couldn't create SDL window. " << SDL_GetError(); return false; } @@ -250,7 +249,7 @@ bool Renderer::createWindow() << std::to_string(displayMode.w * scaleFactor) << "x" << std::to_string(displayMode.h * scaleFactor) << ")"; LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz"; - LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(sScreenWidth) << "x" + LOG(LogInfo) << "Application resolution: " << std::to_string(sScreenWidth) << "x" << std::to_string(sScreenHeight) << " (physical resolution " << std::to_string(sScreenWidth * scaleFactor) << "x" << std::to_string(sScreenHeight * scaleFactor) << ")"; @@ -268,7 +267,7 @@ bool Renderer::createWindow() LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x" << std::to_string(displayMode.h); LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz"; - LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(sScreenWidth) << "x" + LOG(LogInfo) << "Application resolution: " << std::to_string(sScreenWidth) << "x" << std::to_string(sScreenHeight); #endif @@ -306,10 +305,12 @@ bool Renderer::createWindow() setIcon(); setSwapInterval(); -#if defined(_WIN64) +#if defined(_WIN64) || defined(__ANDROID__) // It seems as if Windows needs this to avoid a brief white screen flash on startup. // Possibly this is driver-specific rather than OS-specific. There is additional code // in init() to work around the white screen flash issue on all operating systems. + // On Android the swap is also necessary to avoid displaying random garbage when + // the rendering starts. swapBuffers(); #endif diff --git a/es-core/src/renderers/Renderer.h b/es-core/src/renderers/Renderer.h index feb958962..4ec4d1dfa 100644 --- a/es-core/src/renderers/Renderer.h +++ b/es-core/src/renderers/Renderer.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Renderer.h // // Generic rendering functions. @@ -55,7 +55,8 @@ public: CLIPPING = 0x00000008, ROTATED = 0x00000010, // Screen rotated 90 or 270 degrees. ROUNDED_CORNERS = 0x00000020, - ROUNDED_CORNERS_NO_AA = 0x00000040 + ROUNDED_CORNERS_NO_AA = 0x00000040, + CONVERT_PIXEL_FORMAT = 0x00000080 }; // clang-format on diff --git a/es-core/src/renderers/RendererOpenGL.cpp b/es-core/src/renderers/RendererOpenGL.cpp index 8f62b705b..5f1c00003 100644 --- a/es-core/src/renderers/RendererOpenGL.cpp +++ b/es-core/src/renderers/RendererOpenGL.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // RendererOpenGL.cpp // // OpenGL / OpenGL ES renderering functions. @@ -112,7 +112,7 @@ GLenum RendererOpenGL::convertTextureType(const TextureType type) #else case TextureType::BGRA: { return GL_BGRA; } break; #endif -#if defined(__EMSCRIPTEN__) +#if defined(__EMSCRIPTEN__) || defined(__ANDROID__) case TextureType::RED: { return GL_LUMINANCE; } break; #else case TextureType::RED: { return GL_RED; } break; @@ -241,15 +241,13 @@ bool RendererOpenGL::createContext() #endif #if defined(USE_OPENGLES) - LOG(LogInfo) << "EmulationStation renderer: OpenGL ES " << mMajorGLVersion << "." - << mMinorGLVersion; + LOG(LogInfo) << "Application renderer: OpenGL ES " << mMajorGLVersion << "." << mMinorGLVersion; #else #if defined(_WIN64) - LOG(LogInfo) << "EmulationStation renderer: OpenGL " << mMajorGLVersion << "." - << mMinorGLVersion << " with GLEW"; + LOG(LogInfo) << "Application renderer: OpenGL " << mMajorGLVersion << "." << mMinorGLVersion + << " with GLEW"; #else - LOG(LogInfo) << "EmulationStation renderer: OpenGL " << mMajorGLVersion << "." - << mMinorGLVersion; + LOG(LogInfo) << "Application renderer: OpenGL " << mMajorGLVersion << "." << mMinorGLVersion; #endif #endif @@ -439,8 +437,16 @@ unsigned int RendererOpenGL::createTexture(const unsigned int texUnit, static_cast(GL_NEAREST))); #if defined(USE_OPENGLES) - GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType, - GL_UNSIGNED_BYTE, data)); + if (mipmapping) { + // This is required as not all mobile GPUs support mipmapping when using the BGRA + // pixel format. + GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, data)); + } + else { + GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType, + GL_UNSIGNED_BYTE, data)); + } #else GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, textureType, GL_UNSIGNED_BYTE, data)); @@ -644,6 +650,13 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders, vertices->blurStrength = parameters.blurStrength; vertices->shaderFlags = ShaderFlags::POST_PROCESSING | ShaderFlags::PREMULTIPLIED; +#if defined(USE_OPENGLES) + // This is required as not all mobile GPUs support the glReadPixels() function when using + // the BGRA pixel format. + if (textureRGBA) + vertices->shaderFlags |= ShaderFlags::CONVERT_PIXEL_FORMAT; +#endif + if (screenRotation == 90 || screenRotation == 270) vertices->shaderFlags |= ShaderFlags::ROTATED; @@ -774,10 +787,10 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders, #if defined(USE_OPENGLES) if (screenRotation == 0 || screenRotation == 180) GL_CHECK_ERROR( - glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, textureRGBA)); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA)); else GL_CHECK_ERROR( - glReadPixels(0, 0, height, width, GL_BGRA_EXT, GL_UNSIGNED_BYTE, textureRGBA)); + glReadPixels(0, 0, height, width, GL_RGBA, GL_UNSIGNED_BYTE, textureRGBA)); #else if (screenRotation == 0 || screenRotation == 180) GL_CHECK_ERROR( diff --git a/es-core/src/renderers/RendererOpenGL.h b/es-core/src/renderers/RendererOpenGL.h index 416b4d89d..ad8bf44a4 100644 --- a/es-core/src/renderers/RendererOpenGL.h +++ b/es-core/src/renderers/RendererOpenGL.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // RendererOpenGL.h // // OpenGL / OpenGL ES renderering functions. diff --git a/es-core/src/renderers/ShaderOpenGL.cpp b/es-core/src/renderers/ShaderOpenGL.cpp index ffa4fe519..e2f7df5d4 100644 --- a/es-core/src/renderers/ShaderOpenGL.cpp +++ b/es-core/src/renderers/ShaderOpenGL.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ShaderOpenGL.cpp // // OpenGL / OpenGL ES shader functions. diff --git a/es-core/src/renderers/ShaderOpenGL.h b/es-core/src/renderers/ShaderOpenGL.h index 5216b9c9f..d94e3ab79 100644 --- a/es-core/src/renderers/ShaderOpenGL.h +++ b/es-core/src/renderers/ShaderOpenGL.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ShaderOpenGL.h // // OpenGL / OpenGL ES shader functions. diff --git a/es-core/src/resources/Font.cpp b/es-core/src/resources/Font.cpp index 0329cb057..5e6c3e00c 100644 --- a/es-core/src/resources/Font.cpp +++ b/es-core/src/resources/Font.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Font.h // // Loading, unloading, caching and rendering of fonts. @@ -648,8 +648,10 @@ void Font::rebuildTextures() static_cast(it->second.texSize.y * tex->textureSize.y)}; // Upload to texture. - mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, cursor.y, - glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); + if (glyphSize.x > 0 && glyphSize.y > 0) { + mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, + cursor.y, glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); + } } } @@ -768,8 +770,10 @@ Font::Glyph* Font::getGlyph(const unsigned int id) glyph.rows = glyphSize.y; // Upload glyph bitmap to texture. - mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, cursor.y, - glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); + if (glyphSize.x > 0 && glyphSize.y > 0) { + mRenderer->updateTexture(tex->textureId, 0, Renderer::TextureType::RED, cursor.x, cursor.y, + glyphSize.x, glyphSize.y, glyphSlot->bitmap.buffer); + } return &glyph; } diff --git a/es-core/src/resources/Font.h b/es-core/src/resources/Font.h index 6e2b3a573..b46d37290 100644 --- a/es-core/src/resources/Font.h +++ b/es-core/src/resources/Font.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Font.h // // Loading, unloading, caching and rendering of fonts. diff --git a/es-core/src/resources/ResourceManager.cpp b/es-core/src/resources/ResourceManager.cpp index b14e11a4f..5041193e7 100644 --- a/es-core/src/resources/ResourceManager.cpp +++ b/es-core/src/resources/ResourceManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ResourceManager.cpp // // Handles the application resources (fonts, graphics, sounds etc.). @@ -28,8 +28,7 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi if ((path[0] == ':') && (path[1] == '/')) { // Check under the home directory. - std::string testHome {Utils::FileSystem::getHomePath() + "/.emulationstation/resources/" + - &path[2]}; + std::string testHome {Utils::FileSystem::getAppDataDirectory() + "/resources/" + &path[2]}; if (Utils::FileSystem::exists(testHome)) return testHome; @@ -41,15 +40,22 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi if (Utils::FileSystem::exists(applePackagePath)) { return applePackagePath; } -#elif defined(__unix__) && !defined(APPIMAGE_BUILD) - // Check under the data installation directory (Unix only). +#elif (defined(__unix__) && !defined(APPIMAGE_BUILD)) || defined(__ANDROID__) + // Check in the program data directory. std::string testDataPath {Utils::FileSystem::getProgramDataPath() + "/resources/" + &path[2]}; - - if (Utils::FileSystem::exists(testDataPath)) { + if (Utils::FileSystem::exists(testDataPath)) return testDataPath; - } #endif +#if defined(__ANDROID__) + // Check in the assets directory using AssetManager. + SDL_RWops* resFile {SDL_RWFromFile(path.substr(2).c_str(), "rb")}; + if (resFile != nullptr) { + SDL_RWclose(resFile); + return path.substr(2); + } + else { +#else // Check under the ES executable directory. std::string testExePath {Utils::FileSystem::getExePath() + "/resources/" + &path[2]}; @@ -57,9 +63,10 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi return testExePath; } // For missing resources, log an error and terminate the application. This should - // indicate that we have a broken EmulationStation installation. If the argument + // indicate that we have a broken ES-DE installation. If the argument // terminateOnFailure is set to false though, then skip this step. else { +#endif if (terminateOnFailure) { LOG(LogError) << "Program resource missing: " << path; LOG(LogError) << "Tried to find the resource in the following locations:"; @@ -69,8 +76,10 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi #elif defined(__unix__) && !defined(APPIMAGE_BUILD) LOG(LogError) << testDataPath; #endif +#if !defined(__ANDROID__) LOG(LogError) << testExePath; - LOG(LogError) << "Has EmulationStation been properly installed?"; +#endif + LOG(LogError) << "Has ES-DE been properly installed?"; Utils::Platform::emergencyShutdown(); } else { @@ -88,10 +97,20 @@ const ResourceData ResourceManager::getFileData(const std::string& path) const // Check if its a resource. const std::string respath {getResourcePath(path)}; +#if defined(__ANDROID__) + // Check in the assets directory using AssetManager. + SDL_RWops* resFile {SDL_RWFromFile(respath.c_str(), "rb")}; + if (resFile != nullptr) { + ResourceData data {loadFile(resFile)}; + SDL_RWclose(resFile); + return data; + } +#else if (Utils::FileSystem::exists(respath)) { ResourceData data {loadFile(respath)}; return data; } +#endif // If the file doesn't exist, return an "empty" ResourceData. ResourceData data {nullptr, 0}; @@ -107,7 +126,7 @@ ResourceData ResourceManager::loadFile(const std::string& path) const #endif stream.seekg(0, stream.end); - size_t size {static_cast(stream.tellg())}; + const size_t size {static_cast(stream.tellg())}; stream.seekg(0, stream.beg); // Supply custom deleter to properly free array. @@ -120,6 +139,17 @@ ResourceData ResourceManager::loadFile(const std::string& path) const return ret; } +ResourceData ResourceManager::loadFile(SDL_RWops* resFile) const +{ + const size_t size {static_cast(SDL_RWsize(resFile))}; + std::shared_ptr data {new unsigned char[size], + [](unsigned char* p) { delete[] p; }}; + SDL_RWread(resFile, reinterpret_cast(data.get()), 1, size); + + ResourceData ret {data, size}; + return ret; +} + bool ResourceManager::fileExists(const std::string& path) const { // If it exists as a resource file, return true. diff --git a/es-core/src/resources/ResourceManager.h b/es-core/src/resources/ResourceManager.h index 1f41e864a..835f7af21 100644 --- a/es-core/src/resources/ResourceManager.h +++ b/es-core/src/resources/ResourceManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ResourceManager.h // // Handles the application resources (fonts, graphics, sounds etc.). @@ -14,6 +14,8 @@ #include #include +#include + // The ResourceManager exists to: // Allow loading resources embedded into the executable like an actual file. // Allow embedded resources to be optionally remapped to actual files for further customization. @@ -49,9 +51,10 @@ public: private: ResourceManager() noexcept {} - std::list> mReloadables; - ResourceData loadFile(const std::string& path) const; + ResourceData loadFile(SDL_RWops* resFile) const; + + std::list> mReloadables; }; #endif // ES_CORE_RESOURCES_RESOURCE_MANAGER_H diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp index b0caf0559..2ae4bd0b8 100644 --- a/es-core/src/resources/TextureData.cpp +++ b/es-core/src/resources/TextureData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureData.cpp // // Low-level texture data functions. diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h index 1443c999c..e86f7a692 100644 --- a/es-core/src/resources/TextureData.h +++ b/es-core/src/resources/TextureData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureData.h // // Low-level texture data functions. diff --git a/es-core/src/resources/TextureDataManager.cpp b/es-core/src/resources/TextureDataManager.cpp index 321159321..4848d99c1 100644 --- a/es-core/src/resources/TextureDataManager.cpp +++ b/es-core/src/resources/TextureDataManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureDataManager.cpp // // Loading and unloading of texture data. diff --git a/es-core/src/resources/TextureDataManager.h b/es-core/src/resources/TextureDataManager.h index 2a26de6ba..4b62e2a19 100644 --- a/es-core/src/resources/TextureDataManager.h +++ b/es-core/src/resources/TextureDataManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureDataManager.h // // Loading and unloading of texture data. diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index dd9e1d5e4..dfc36f1b1 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureResource.cpp // // Handles textures including loading, unloading and cache management. diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h index 2a23cbf6b..76ce69e5c 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TextureResource.h // // Handles textures including loading, unloading and cache management. diff --git a/es-core/src/utils/CImgUtil.cpp b/es-core/src/utils/CImgUtil.cpp index b46106abe..80c0bd0e3 100644 --- a/es-core/src/utils/CImgUtil.cpp +++ b/es-core/src/utils/CImgUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CImgUtil.cpp // // Utility functions using the CImg image processing library. diff --git a/es-core/src/utils/CImgUtil.h b/es-core/src/utils/CImgUtil.h index 50b975958..29c36ea1e 100644 --- a/es-core/src/utils/CImgUtil.h +++ b/es-core/src/utils/CImgUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CImgUtil.h // // Utility functions using the CImg image processing library. diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index accc3df82..588d5ca77 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSystemUtil.cpp // // Low-level filesystem functions. @@ -8,9 +8,9 @@ // remove files etc. // -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && \ - !defined(__NetBSD__) && !defined(__EMSCRIPTEN__) -#define _FILE_OFFSET_BITS 64 +#if defined(__ANDROID__) +#include "utils/PlatformUtilAndroid.h" +#include #endif #if defined(__APPLE__) @@ -176,6 +176,11 @@ namespace Utils if (homePath.length()) return homePath; +#if defined(__ANDROID__) + homePath = FileSystemVariables::sAppDataDirectory; + return homePath; +#endif + #if defined(_WIN64) // On Windows we need to check HOMEDRIVE and HOMEPATH. if (!homePath.length()) { @@ -241,6 +246,36 @@ namespace Utils return ""; } + std::string getAppDataDirectory() + { +#if defined(__ANDROID__) + return getHomePath(); +#else + if (FileSystemVariables::sAppDataDirectory.empty()) { + if (Utils::FileSystem::exists(getHomePath() + "/ES-DE")) { + FileSystemVariables::sAppDataDirectory = getHomePath() + "/ES-DE"; + } + else if (Utils::FileSystem::exists(getHomePath() + "/.emulationstation")) { + FileSystemVariables::sAppDataDirectory = getHomePath() + "/.emulationstation"; + } + else { + FileSystemVariables::sAppDataDirectory = getHomePath() + "/ES-DE"; + } + } + + return FileSystemVariables::sAppDataDirectory; +#endif + } + + std::string getInternalAppDataDirectory() + { +#if defined(__ANDROID__) + return AndroidVariables::sExternalDataDirectory; +#else + return ""; +#endif + } + std::string getCWDPath() { // Return current working directory. @@ -275,8 +310,8 @@ namespace Utils // Using a temporary file is the only viable solution I've found to communicate // between the sandbox and the outside world. - const std::string& tempFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" + - ".flatpak_emulator_binary_path.tmp"}; + const std::string& tempFile {Utils::FileSystem::getAppDataDirectory() + + "/.flatpak_emulator_binary_path.tmp"}; std::string emulatorPath; @@ -365,10 +400,12 @@ namespace Utils std::string getProgramDataPath() { -#if defined(__unix__) - return installPrefix + "/share/emulationstation"; +#if defined(__ANDROID__) + return AndroidVariables::sInternalDataDirectory; +#elif defined(__unix__) + return installPrefix + "/share/es-de"; #else - return ""; + return ""; #endif } diff --git a/es-core/src/utils/FileSystemUtil.h b/es-core/src/utils/FileSystemUtil.h index fc3353553..24a2a247e 100644 --- a/es-core/src/utils/FileSystemUtil.h +++ b/es-core/src/utils/FileSystemUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSystemUtil.h // // Low-level filesystem functions. @@ -15,6 +15,12 @@ #include #include +class FileSystemVariables +{ +public: + static inline std::string sAppDataDirectory; +}; + namespace Utils { namespace FileSystem @@ -26,6 +32,8 @@ namespace Utils StringList getPathList(const std::string& path); void setHomePath(const std::string& path); std::string getHomePath(); + std::string getAppDataDirectory(); + std::string getInternalAppDataDirectory(); std::string getSystemHomeDirectory(); std::string getCWDPath(); std::string getPathToBinary(const std::string& executable); diff --git a/es-core/src/utils/MathUtil.cpp b/es-core/src/utils/MathUtil.cpp index 9749f2c68..e7f65fe3b 100644 --- a/es-core/src/utils/MathUtil.cpp +++ b/es-core/src/utils/MathUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MathUtil.cpp // // Math utility functions. diff --git a/es-core/src/utils/MathUtil.h b/es-core/src/utils/MathUtil.h index 9a18e046a..f4d70c973 100644 --- a/es-core/src/utils/MathUtil.h +++ b/es-core/src/utils/MathUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MathUtil.h // // Math utility functions. diff --git a/es-core/src/utils/PlatformUtil.cpp b/es-core/src/utils/PlatformUtil.cpp index af8dd9e5a..a36213539 100644 --- a/es-core/src/utils/PlatformUtil.cpp +++ b/es-core/src/utils/PlatformUtil.cpp @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition -// Platform.cpp +// ES-DE +// PlatformUtil.cpp // // Platform utility functions. // @@ -330,7 +330,7 @@ namespace Utils { sQuitMode = mode; - SDL_Event quit; + SDL_Event quit {}; quit.type = SDL_QUIT; SDL_PushEvent(&quit); return 0; diff --git a/es-core/src/utils/PlatformUtil.h b/es-core/src/utils/PlatformUtil.h index 6ff1b550e..c1e839571 100644 --- a/es-core/src/utils/PlatformUtil.h +++ b/es-core/src/utils/PlatformUtil.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition -// Platform.h +// ES-DE +// PlatformUtil.h // // Platform utility functions. // diff --git a/es-core/src/utils/StringUtil.cpp b/es-core/src/utils/StringUtil.cpp index 543ac26da..756ceafb3 100644 --- a/es-core/src/utils/StringUtil.cpp +++ b/es-core/src/utils/StringUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // StringUtil.cpp // // Low-level string functions. @@ -569,6 +569,13 @@ namespace Utils return line; } + std::string filterUtf8(const std::string& stringArg) + { + std::string tempString; + utf8::replace_invalid(stringArg.begin(), stringArg.end(), back_inserter(tempString)); + return tempString; + } + std::string trim(const std::string& stringArg) { std::string trimString = stringArg; diff --git a/es-core/src/utils/StringUtil.h b/es-core/src/utils/StringUtil.h index 00aa3e5f1..4284cab3f 100644 --- a/es-core/src/utils/StringUtil.h +++ b/es-core/src/utils/StringUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // StringUtil.h // // Low-level string functions. @@ -14,6 +14,8 @@ #include #include +#include "utf8.h" + namespace Utils { namespace String @@ -28,6 +30,7 @@ namespace Utils std::string toLower(const std::string& stringArg); std::string toUpper(const std::string& stringArg); std::string toCapitalized(const std::string& stringArg); + std::string filterUtf8(const std::string& stringArg); std::string trim(const std::string& stringArg); std::string replace(const std::string& stringArg, const std::string& from, diff --git a/es-core/src/utils/TimeUtil.cpp b/es-core/src/utils/TimeUtil.cpp index 291e0c7dc..57600a48c 100644 --- a/es-core/src/utils/TimeUtil.cpp +++ b/es-core/src/utils/TimeUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TimeUtil.cpp // // Low-level date and time functions. diff --git a/es-core/src/utils/TimeUtil.h b/es-core/src/utils/TimeUtil.h index 644bdf49f..01089718b 100644 --- a/es-core/src/utils/TimeUtil.h +++ b/es-core/src/utils/TimeUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // TimeUtil.h // // Low-level date and time functions. diff --git a/es-pdf-converter/CMakeLists.txt b/es-pdf-converter/CMakeLists.txt index 242efa8ad..3857bdd47 100644 --- a/es-pdf-converter/CMakeLists.txt +++ b/es-pdf-converter/CMakeLists.txt @@ -10,24 +10,33 @@ project(es-pdf-convert) if(WIN32) set(POPPLER_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler/Library/include/poppler/cpp) - if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/poppler-cpp.lib) - # Disable DLL interface warnings. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") - else() - set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/libpoppler-cpp-0.dll) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") - endif() + set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/poppler-cpp.lib) + # Disable DLL interface warnings. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") elseif(APPLE) set(POPPLER_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler/cpp ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler/build/cpp) set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../libpoppler-cpp.0.dylib) +elseif(ANDROID) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -llog") + set(POPPLER_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler/cpp ${CMAKE_CURRENT_SOURCE_DIR}/../external/poppler/build/cpp) + set(POPPLER_CPP_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../android/libs/${ANDROID_CPU_ARCH}/libpoppler-cpp.so) else() find_package(Poppler REQUIRED COMPONENTS cpp) endif() include_directories(${POPPLER_CPP_INCLUDE_DIR}) -add_executable(es-pdf-convert WIN32 ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) -target_link_libraries(es-pdf-convert ${POPPLER_CPP_LIBRARY}) +if (ANDROID) + set(CONVERTER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/ConvertPDF.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ConvertPDF.h) + add_library(es-pdf-convert SHARED ${CONVERTER_SOURCE_FILES}) +else() + set(CONVERTER_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ConvertPDF.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ConvertPDF.h) + add_executable(es-pdf-convert WIN32 ${CONVERTER_SOURCE_FILES}) +endif() +target_link_libraries(es-pdf-convert PRIVATE ${POPPLER_CPP_LIBRARY}) if(WIN32) set_target_properties(es-pdf-convert PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/es-pdf-converter" INSTALL_RPATH_USE_LINK_PATH TRUE) diff --git a/es-pdf-converter/src/ConvertPDF.cpp b/es-pdf-converter/src/ConvertPDF.cpp new file mode 100644 index 000000000..6d9a7b93f --- /dev/null +++ b/es-pdf-converter/src/ConvertPDF.cpp @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// ES-DE +// ConvertPDF.cpp +// +// Converts PDF document pages to raw ARGB32 pixel data for maximum performance. +// This needs to be separated into its own binary to get around the restrictive GPL +// license used by the Poppler PDF rendering library. +// + +#include "ConvertPDF.h" + +#include "poppler-document.h" +#include "poppler-image.h" +#include "poppler-page-renderer.h" +#include "poppler-page.h" + +#include +#include +#include + +#if defined(__ANDROID__) +#include +#endif + +#if defined(_WIN64) +#include +#include +#include +#endif + +#if defined(_WIN64) +int ConvertPDF::processFile( + const std::wstring path, const std::wstring mode, int pageNum, int width, int height) +#elif defined(__ANDROID__) +int ConvertPDF::processFile(const std::string path, + const std::string mode, + int pageNum, + int width, + int height, + std::string& result) +#else +int ConvertPDF::processFile( + const std::string path, const std::string mode, int pageNum, int width, int height) +#endif +{ + std::ifstream file; + + file.open(path.c_str(), std::ifstream::binary); + if (file.fail()) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Couldn't open PDF file, permission problems?"); +#else + std::cerr << "Error: Couldn't open PDF file, permission problems?" << std::endl; +#endif + return (-1); + } + + file.seekg(0, std::ios::end); + const long fileLength {static_cast(file.tellg())}; + file.seekg(0, std::ios::beg); + std::vector fileData(fileLength); + file.read(&fileData[0], fileLength); + file.close(); + + const poppler::document* document { + poppler::document::load_from_raw_data(&fileData[0], fileLength)}; + + if (document == nullptr) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Couldn't open document, invalid PDF file?"); +#else + std::cerr << "Error: Couldn't open document, invalid PDF file?" << std::endl; +#endif + return (-1); + } + + const int pageCount {document->pages()}; +#if defined(_WIN64) + if (mode == L"-fileinfo") { +#else + if (mode == "-fileinfo") { +#endif + std::vector pageInfo; + for (int i {0}; i < pageCount; ++i) { + std::string pageRow; + const poppler::page* page {document->create_page(i)}; + if (page == nullptr) { + if (page == nullptr) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Couldn't read page %i", i + 1); +#else + std::cerr << "Error: Couldn't read page " << i + 1 << std::endl; +#endif + return (-1); + } + } + + std::string orientation; + if (page->orientation() == poppler::page::portrait) + orientation = "portrait"; + else if (page->orientation() == poppler::page::upside_down) + orientation = "upside_down"; + else if (page->orientation() == poppler::page::seascape) + orientation = "seascape"; + else + orientation = "landscape"; + + const poppler::rectf pageRect {page->page_rect()}; + pageRow.append(std::to_string(i + 1)) + .append(";") + .append(orientation) + .append(";") + .append(std::to_string(pageRect.width())) + .append(";") + .append(std::to_string(pageRect.height())); + pageInfo.emplace_back(pageRow); + } + for (auto& row : pageInfo) { +#if defined(__ANDROID__) + result.append(row).append("\n"); +#else + std::cout << row << std::endl; +#endif + } + return (0); + } + + if (pageNum < 1 || pageNum > pageCount) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Requested page %i does not exist in document", pageNum); +#else + std::cerr << "Error: Requested page " << pageNum << " does not exist in document" + << std::endl; +#endif + return (-1); + } + + const poppler::page* page {document->create_page(pageNum - 1)}; + + if (page == nullptr) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, + "Error: Couldn't read page %i", pageNum); +#else + std::cerr << "Error: Couldn't read page " << pageNum << std::endl; +#endif + return (-1); + } + + poppler::page_renderer pageRenderer; + + pageRenderer.set_render_hint(poppler::page_renderer::text_antialiasing); + pageRenderer.set_render_hint(poppler::page_renderer::antialiasing); + // pageRenderer.set_render_hint(poppler::page_renderer::text_hinting); + + const poppler::rectf pageRect {page->page_rect()}; + const bool rotate {page->orientation() == poppler::page::portrait || + page->orientation() == poppler::page::upside_down}; + const double pageHeight {pageRect.height()}; + const double sizeFactor {static_cast(rotate ? height : width) / pageHeight}; + + poppler::image image { + pageRenderer.render_page(page, 72.0 * sizeFactor, 72.0 * sizeFactor, 0, 0, width, height)}; + + if (!image.is_valid()) { +#if defined(__ANDROID__) + __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, "Rendered image is invalid"); +#else + std::cerr << "Rendered image is invalid" << std::endl; +#endif + return (-1); + } + +#if defined(__ANDROID__) + result.insert(0, std::move(image.data()), width * height * 4); +#else + // Necessary as the image data stream may contain null characters. + std::string imageARGB32; + imageARGB32.insert(0, std::move(image.data()), width * height * 4); + + std::cout << imageARGB32; +#endif + + return 0; +} \ No newline at end of file diff --git a/es-pdf-converter/src/ConvertPDF.h b/es-pdf-converter/src/ConvertPDF.h new file mode 100644 index 000000000..8f9a33bfb --- /dev/null +++ b/es-pdf-converter/src/ConvertPDF.h @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// ES-DE +// ConvertPDF.h +// +// Converts PDF document pages to raw ARGB32 pixel data for maximum performance. +// This needs to be separated into its own binary to get around the restrictive GPL +// license used by the Poppler PDF rendering library. +// + +#include + +#ifndef ES_PDF_CONVERTER_CONVERT_PDF_H +#define ES_PDF_CONVERTER_CONVERT_PDF_H + +class ConvertPDF +{ +public: +#if defined(_WIN64) + static int processFile( + const std::wstring path, const std::wstring mode, int pageNum, int width, int height); +#elif defined(__ANDROID__) + __attribute__((visibility("default"))) static int processFile(const std::string path, + const std::string mode, + int pageNum, + int width, + int height, + std::string& result); +#else + static int processFile( + const std::string path, const std::string mode, int pageNum, int width, int height); +#endif +}; + +#endif // ES_PDF_CONVERTER_CONVERT_PDF_H diff --git a/es-pdf-converter/src/main.cpp b/es-pdf-converter/src/main.cpp index 8418fb5d9..65df7085d 100644 --- a/es-pdf-converter/src/main.cpp +++ b/es-pdf-converter/src/main.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // -// EmulationStation Desktop Edition (ES-DE) PDF converter +// ES-DE PDF converter // main.cpp // // Converts PDF document pages to raw ARGB32 pixel data for maximum performance. @@ -11,13 +11,8 @@ // All ES-DE C++ source code is formatted using clang-format. // -#include "poppler-document.h" -#include "poppler-image.h" -#include "poppler-page-renderer.h" -#include "poppler-page.h" +#include "ConvertPDF.h" -#include -#include #include #if defined(_WIN64) @@ -53,7 +48,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd validArguments = false; if (!validArguments) { - std::cout << "This binary is only intended to be executed by EmulationStation.exe (ES-DE)" + std::cout << "This binary is only intended to be executed by ES-DE.exe" << std::endl; exit(-1); } @@ -84,9 +79,9 @@ int main(int argc, char* argv[]) if (!validArguments) { #if defined(__APPLE__) - std::cout << "This binary is only intended to be executed by EmulationStation (ES-DE)" + std::cout << "This binary is only intended to be executed by ES-DE" #else - std::cout << "This binary is only intended to be executed by emulationstation (ES-DE)" + std::cout << "This binary is only intended to be executed by es-de" #endif << std::endl; exit(-1); @@ -101,7 +96,7 @@ int main(int argc, char* argv[]) pageNum = atoi(argv[3]); width = atoi(argv[4]); height = atoi(argv[5]); -#endif +#endif // _WIN64 if (width < 1 || width > 7680) { std::cerr << "Invalid horizontal resolution defined: " << argv[3] << std::endl; exit(-1); @@ -116,107 +111,5 @@ int main(int argc, char* argv[]) // << width << "x" << height << " pixels" << std::endl; } - std::ifstream file; - - file.open(path.c_str(), std::ifstream::binary); - if (file.fail()) { - std::cerr << "Error: Couldn't open PDF file, permission problems?" << std::endl; - exit(-1); - } - - file.seekg(0, std::ios::end); - const long fileLength {static_cast(file.tellg())}; - file.seekg(0, std::ios::beg); - std::vector fileData(fileLength); - file.read(&fileData[0], fileLength); - file.close(); - - const poppler::document* document { - poppler::document::load_from_raw_data(&fileData[0], fileLength)}; - - if (document == nullptr) { - std::cerr << "Error: Couldn't open document, invalid PDF file?" << std::endl; - exit(-1); - } - - const int pageCount {document->pages()}; -#if defined(_WIN64) - if (mode == L"-fileinfo") { -#else - if (mode == "-fileinfo") { -#endif - std::vector pageInfo; - for (int i {0}; i < pageCount; ++i) { - std::string pageRow; - const poppler::page* page {document->create_page(i)}; - if (page == nullptr) { - if (page == nullptr) { - std::cerr << "Error: Couldn't read page " << i + 1 << std::endl; - exit(-1); - } - } - std::string orientation; - if (page->orientation() == poppler::page::portrait) - orientation = "portrait"; - else if (page->orientation() == poppler::page::upside_down) - orientation = "upside_down"; - else if (page->orientation() == poppler::page::seascape) - orientation = "seascape"; - else - orientation = "landscape"; - - const poppler::rectf pageRect {page->page_rect()}; - pageRow.append(std::to_string(i + 1)) - .append(";") - .append(orientation) - .append(";") - .append(std::to_string(pageRect.width())) - .append(";") - .append(std::to_string(pageRect.height())); - pageInfo.emplace_back(pageRow); - } - for (auto& row : pageInfo) - std::cout << row << std::endl; - exit(0); - } - - if (pageNum < 1 || pageNum > pageCount) { - std::cerr << "Error: Requested page " << pageNum << " does not exist in document" - << std::endl; - exit(-1); - } - - const poppler::page* page {document->create_page(pageNum - 1)}; - - if (page == nullptr) { - std::cerr << "Error: Couldn't read page " << pageNum << std::endl; - exit(-1); - } - - poppler::page_renderer pageRenderer; - - pageRenderer.set_render_hint(poppler::page_renderer::text_antialiasing); - pageRenderer.set_render_hint(poppler::page_renderer::antialiasing); - // pageRenderer.set_render_hint(poppler::page_renderer::text_hinting); - - const poppler::rectf pageRect {page->page_rect()}; - const bool rotate {page->orientation() == poppler::page::portrait || - page->orientation() == poppler::page::upside_down}; - const double pageHeight {pageRect.height()}; - const double sizeFactor {static_cast(rotate ? height : width) / pageHeight}; - - poppler::image image { - pageRenderer.render_page(page, 72.0 * sizeFactor, 72.0 * sizeFactor, 0, 0, width, height)}; - - if (!image.is_valid()) { - std::cerr << "Rendered image is invalid" << std::endl; - exit(-1); - } - - // Necessary as the image data stream may contain null characters. - std::string imageARGB32; - imageARGB32.insert(0, std::move(image.data()), width * height * 4); - - std::cout << imageARGB32; - return 0; + return ConvertPDF::processFile(path, mode, pageNum, width, height); } diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index e6056f6ce..be7268087 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt (external) # # CMake configuration for bundled dependencies built in-tree. @@ -27,11 +27,6 @@ endif() unset(CMAKE_CXX_FLAGS) unset(CMAKE_EXE_LINKER_FLAGS) -# Strip the DLL files when building with MinGW. -if(WIN32 AND NOT CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s") -endif() - if (WIN32) set(BUILD_SHARED_LIBS ON) else() @@ -45,6 +40,16 @@ if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) target_compile_options(lunasvg PRIVATE "/wd4251" "/wd4267") endif() +if(ANDROID) + if(ANDROID_LITE_RELEASE) + set_target_properties(lunasvg PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/android_lite_${ANDROID_ABI}) + else() + set_target_properties(lunasvg PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/android_${ANDROID_ABI}) + endif() +endif() + # Disable threading support for rlottie as this functionality actually leads to far worse # performance. As well there is a bug on Windows that makes rlottie hang forever on application # shutdown if compiled using MinGW with threading support enabled. @@ -65,5 +70,15 @@ else() target_compile_options(rlottie PRIVATE "-w") endif() +if(ANDROID) + if(ANDROID_LITE_RELEASE) + set_target_properties(rlottie PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/android_lite_${ANDROID_ABI}) + else() + set_target_properties(rlottie PROPERTIES ARCHIVE_OUTPUT_DIRECTORY + ${PROJECT_SOURCE_DIR}/android_${ANDROID_ABI}) + endif() +endif() + # Build LunaSVG before rlottie. add_dependencies(rlottie lunasvg) diff --git a/external/utfcpp/.github/workflows/cmake-multi-platform.yml b/external/utfcpp/.github/workflows/cmake-multi-platform.yml new file mode 100644 index 000000000..3ffcf0ca9 --- /dev/null +++ b/external/utfcpp/.github/workflows/cmake-multi-platform.yml @@ -0,0 +1,75 @@ +# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. +# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml +name: CMake on multiple platforms + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + # Set up a matrix to run the following 3 configurations: + # 1. + # 2. + # 3. + # + # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. + matrix: + os: [ubuntu-latest, windows-latest] + build_type: [Release] + c_compiler: [gcc, clang, cl] + include: + - os: windows-latest + c_compiler: cl + cpp_compiler: cl + - os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + - os: ubuntu-latest + c_compiler: clang + cpp_compiler: clang++ + exclude: + - os: windows-latest + c_compiler: gcc + - os: windows-latest + c_compiler: clang + - os: ubuntu-latest + c_compiler: cl + + steps: + - uses: actions/checkout@v4 + + - name: Set reusable strings + # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. + id: strings + shell: bash + run: | + echo "build-output-dir=${{ github.workspace }}/tests/build" >> "$GITHUB_OUTPUT" + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} + -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + -S ${{ github.workspace }} + + - name: Build + # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). + run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} + + - name: Test + working-directory: ${{ steps.strings.outputs.build-output-dir }} + # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + run: ctest -VV --build-config ${{ matrix.build_type }} diff --git a/external/utfcpp/.gitignore b/external/utfcpp/.gitignore new file mode 100644 index 000000000..488d51dd9 --- /dev/null +++ b/external/utfcpp/.gitignore @@ -0,0 +1,4 @@ +# VS Code: +.vscode/ +# Often used by CMake +build/ \ No newline at end of file diff --git a/external/utfcpp/.gitmodules b/external/utfcpp/.gitmodules new file mode 100644 index 000000000..424f86b76 --- /dev/null +++ b/external/utfcpp/.gitmodules @@ -0,0 +1,3 @@ +[submodule "extern/ftest"] + path = extern/ftest + url = https://github.com/nemtrif/ftest diff --git a/external/utfcpp/CMakeLists.txt b/external/utfcpp/CMakeLists.txt new file mode 100644 index 000000000..f24f9b659 --- /dev/null +++ b/external/utfcpp/CMakeLists.txt @@ -0,0 +1,53 @@ +# This file is deprecated and will be removed in a future release +# Please see the instructions for installation in README.md file + +cmake_minimum_required (VERSION 3.14...3.27) +project (utf8cpp + VERSION 4.0.4 + LANGUAGES CXX + DESCRIPTION "C++ portable library for working with utf-8 encoding") + +add_library(${PROJECT_NAME} INTERFACE) + +include(GNUInstallDirs) + +target_include_directories(utf8cpp INTERFACE + "$" + $ +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion + ARCH_INDEPENDENT +) + +install(TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION include COMPONENT Development + BUNDLE DESTINATION bin COMPONENT Runtime +) + +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake +) + +install(EXPORT ${PROJECT_NAME}Targets + FILE ${PROJECT_NAME}Targets.cmake + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) + +install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) + +install(FILES ${PROJECT_SOURCE_DIR}/source/utf8.h DESTINATION include/utf8cpp) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/source/utf8 DESTINATION + include/utf8cpp) diff --git a/external/utfcpp/LICENSE b/external/utfcpp/LICENSE new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/external/utfcpp/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/external/utfcpp/README.md b/external/utfcpp/README.md new file mode 100644 index 000000000..37f3de739 --- /dev/null +++ b/external/utfcpp/README.md @@ -0,0 +1,2131 @@ + + +# UTF8-CPP: UTF-8 with C++ in a Portable Way + + + +## Introduction + +C++ developers still miss an easy and portable way of handling Unicode encoded strings. The original C++ standard (known as C++98 or C++03) is Unicode agnostic. Some progress has been made in the later editions of the standard, but it is still hard to work with Unicode using only the standard facilities. + +I came up with a small, C++98 compatible generic library in order to handle UTF-8 encoded strings. For anybody used to work with STL algorithms and iterators, it should be easy and natural to use. The code is freely available for any purpose - check out the [license](./LICENSE). The library has been used a lot since the first release in 2006 both in commercial and open-source projects and proved to be stable and useful. + +## Table of Contents + +- [UTF8-CPP: UTF-8 with C++ in a Portable Way](#utf8-cpp-utf-8-with-c-in-a-portable-way) + * [Introduction](#introduction) + * [Installation](#installation) + * [Examples of use](#examples-of-use) + + [Introductory Sample](#introductory-sample) + + [Checking if a file contains valid UTF-8 text](#checking-if-a-file-contains-valid-utf-8-text) + + [Ensure that a string contains valid UTF-8 text](#ensure-that-a-string-contains-valid-utf-8-text) + * [Points of interest](#points-of-interest) + - [Design goals and decisions](#design-goals-and-decisions) + - [Alternatives](#alternatives) + * [Reference](#reference) + + [Functions From utf8 Namespace](#functions-from-utf8-namespace) + - [utf8::append](#utf8append) + * [octet_iterator append(utfchar32_t cp, octet_iterator result)](#octet_iterator-appendutfchar32_t-cp-octet_iterator-result) + * [void append(utfchar32_t cp, std::string& s);](#void-appendutfchar32_t-cp-stdstring-s) + - [utf8::append16](#utf8append16) + * [word_iterator append16(utfchar32_t cp, word_iterator result)](#word_iterator-append16utfchar32_t-cp-word_iterator-result) + * [void append(utfchar32_t cp, std::u16string& s)](#void-appendutfchar32_t-cp-stdu16string-s) + - [utf8::next](#utf8next) + - [utf8::next16](#utf8next16) + - [utf8::peek_next](#utf8peek_next) + - [utf8::prior](#utf8prior) + - [utf8::advance](#utf8advance) + - [utf8::distance](#utf8distance) + - [utf8::utf16to8](#utf8utf16to8) + * [octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)](#octet_iterator-utf16to8-u16bit_iterator-start-u16bit_iterator-end-octet_iterator-result) + * [std::string utf16to8(const std::u16string& s)](#stdstring-utf16to8const-stdu16string-s) + * [std::string utf16to8(std::u16string_view s)](#stdstring-utf16to8stdu16string_view-s) + - [utf8::utf16tou8](#utf8utf16tou8) + * [std::u8string utf16tou8(const std::u16string& s)](#stdu8string-utf16tou8const-stdu16string-s) + * [std::u8string utf16tou8(const std::u16string_view& s)](#stdu8string-utf16tou8const-stdu16string_view-s) + - [utf8::utf8to16](#utf8utf8to16) + * [u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)](#u16bit_iterator-utf8to16-octet_iterator-start-octet_iterator-end-u16bit_iterator-result) + * [std::u16string utf8to16(const std::string& s)](#stdu16string-utf8to16const-stdstring-s) + * [std::u16string utf8to16(std::string_view s)](#stdu16string-utf8to16stdstring_view-s) + * [std::u16string utf8to16(std::u8string& s)](#stdu16string-utf8to16stdu8string-s) + * [std::u16string utf8to16(std::u8string_view& s)](#stdu16string-utf8to16stdu8string_view-s) + - [utf8::utf32to8](#utf8utf32to8) + * [octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)](#octet_iterator-utf32to8-u32bit_iterator-start-u32bit_iterator-end-octet_iterator-result) + * [std::string utf32to8(const std::u32string& s)](#stdstring-utf32to8const-stdu32string-s) + * [std::u8string utf32to8(const std::u32string& s)](#stdu8string-utf32to8const-stdu32string-s) + * [std::u8string utf32to8(const std::u32string_view& s)](#stdu8string-utf32to8const-stdu32string_view-s) + * [std::string utf32to8(const std::u32string& s)](#stdstring-utf32to8const-stdu32string-s-1) + * [std::string utf32to8(std::u32string_view s)](#stdstring-utf32to8stdu32string_view-s) + - [utf8::utf8to32](#utf8utf8to32) + * [u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)](#u32bit_iterator-utf8to32-octet_iterator-start-octet_iterator-end-u32bit_iterator-result) + * [std::u32string utf8to32(const std::u8string& s)](#stdu32string-utf8to32const-stdu8string-s) + * [std::u32string utf8to32(const std::u8string_view& s)](#stdu32string-utf8to32const-stdu8string_view-s) + * [std::u32string utf8to32(const std::string& s)](#stdu32string-utf8to32const-stdstring-s) + * [std::u32string utf8to32(std::string_view s)](#stdu32string-utf8to32stdstring_view-s) + - [utf8::find_invalid](#utf8find_invalid) + * [octet_iterator find_invalid(octet_iterator start, octet_iterator end)](#octet_iterator-find_invalidoctet_iterator-start-octet_iterator-end) + * [const char* find_invalid(const char* str)](#const-char-find_invalidconst-char-str) + * [std::size_t find_invalid(const std::string& s)](#stdsize_t-find_invalidconst-stdstring-s) + * [std::size_t find_invalid(std::string_view s)](#stdsize_t-find_invalidstdstring_view-s) + - [utf8::is_valid](#utf8is_valid) + * [bool is_valid(octet_iterator start, octet_iterator end)](#bool-is_validoctet_iterator-start-octet_iterator-end) + * [bool is_valid(const char* str)](#bool-is_validconst-char-str) + * [bool is_valid(const std::string& s)](#bool-is_validconst-stdstring-s) + * [bool is_valid(std::string_view s)](#bool-is_validstdstring_view-s) + - [utf8::replace_invalid](#utf8replace_invalid) + * [output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement)](#output_iterator-replace_invalidoctet_iterator-start-octet_iterator-end-output_iterator-out-utfchar32_t-replacement) + * [std::string replace_invalid(const std::string& s, utfchar32_t replacement)](#stdstring-replace_invalidconst-stdstring-s-utfchar32_t-replacement) + * [std::string replace_invalid(std::string_view s, char32_t replacement)](#stdstring-replace_invalidstdstring_view-s-char32_t-replacement) + - [utf8::starts_with_bom](#utf8starts_with_bom) + * [bool starts_with_bom (octet_iterator it, octet_iterator end)](#bool-starts_with_bom-octet_iterator-it-octet_iterator-end) + * [bool starts_with_bom(const std::string& s)](#bool-starts_with_bomconst-stdstring-s) + * [bool starts_with_bom(std::string_view s)](#bool-starts_with_bomstdstring_view-s) + + [Types From utf8 Namespace](#types-from-utf8-namespace) + - [utf8::exception](#utf8exception) + - [utf8::invalid_code_point](#utf8invalid_code_point) + - [utf8::invalid_utf8](#utf8invalid_utf8) + - [utf8::invalid_utf16](#utf8invalid_utf16) + - [utf8::not_enough_room](#utf8not_enough_room) + - [utf8::iterator](#utf8iterator) + * [Member functions](#member-functions) + + [Functions From utf8::unchecked Namespace](#functions-from-utf8unchecked-namespace) + - [utf8::unchecked::append](#utf8uncheckedappend) + - [utf8::unchecked::append16](#utf8uncheckedappend16) + - [utf8::unchecked::next](#utf8uncheckednext) + - [utf8::next16](#utf8next16-1) + - [utf8::unchecked::peek_next](#utf8uncheckedpeek_next) + - [utf8::unchecked::prior](#utf8uncheckedprior) + - [utf8::unchecked::advance](#utf8uncheckedadvance) + - [utf8::unchecked::distance](#utf8uncheckeddistance) + - [utf8::unchecked::utf16to8](#utf8uncheckedutf16to8) + - [utf8::unchecked::utf8to16](#utf8uncheckedutf8to16) + - [utf8::unchecked::utf32to8](#utf8uncheckedutf32to8) + - [utf8::unchecked::utf8to32](#utf8uncheckedutf8to32) + - [utf8::unchecked::replace_invalid](#utf8uncheckedreplace_invalid) + + [Types From utf8::unchecked Namespace](#types-from-utf8unchecked-namespace) + - [utf8::iterator](#utf8iterator-1) + * [Member functions](#member-functions-1) + + + + + +## Installation + +This is a header-only library and the supported way of deploying it is: +- Download a release from https://github.com/nemtrif/utfcpp/releases into a temporary directory +- Unzip the release +- Copy the content of utfcpp/source file into the directory where you keep include files for your project + + +The CMakeList.txt file was originally made for testing purposes only, but unfortunately over time I accepted contributions that added install target. *This is not a supported way of installing the utfcpp library* and I am considering removing the CMakeList.txt in a future release. + + +## Examples of use + + +### Introductory Sample + +To illustrate the use of the library, let's start with a small but complete program that opens a file containing UTF-8 encoded text, reads it line by line, checks each line for invalid UTF-8 byte sequences, and converts it to UTF-16 encoding and back to UTF-8: + +```cpp +#include +#include +#include +#include +#include "utf8.h" +using namespace std; +int main(int argc, char** argv) +{ + if (argc != 2) { + cout << "\nUsage: docsample filename\n"; + return 0; + } + const char* test_file_path = argv[1]; + // Open the test file (must be UTF-8 encoded) + ifstream fs8(test_file_path); + if (!fs8.is_open()) { + cout << "Could not open " << test_file_path << endl; + return 0; + } + + unsigned line_count = 1; + string line; + // Play with all the lines in the file + while (getline(fs8, line)) { + // check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function) +#if __cplusplus >= 201103L // C++ 11 or later + auto end_it = utf8::find_invalid(line.begin(), line.end()); +#else + string::iterator end_it = utf8::find_invalid(line.begin(), line.end()); +#endif // C++ 11 + if (end_it != line.end()) { + cout << "Invalid UTF-8 encoding detected at line " << line_count << "\n"; + cout << "This part is fine: " << string(line.begin(), end_it) << "\n"; + } + // Get the line length (at least for the valid part) + int length = utf8::distance(line.begin(), end_it); + cout << "Length of line " << line_count << " is " << length << "\n"; + + // Convert it to utf-16 +#if __cplusplus >= 201103L // C++ 11 or later + u16string utf16line = utf8::utf8to16(line); +#else + vector utf16line; + utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line)); +#endif // C++ 11 + // And back to utf-8; +#if __cplusplus >= 201103L // C++ 11 or later + string utf8line = utf8::utf16to8(utf16line); +#else + string utf8line; + utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line)); +#endif // C++ 11 + // Confirm that the conversion went OK: + if (utf8line != string(line.begin(), end_it)) + cout << "Error in UTF-16 conversion at line: " << line_count << "\n"; + + line_count++; + } + + return 0; +} +``` + +In the previous code sample, for each line we performed a detection of invalid UTF-8 sequences with `find_invalid`; the number of characters (more precisely - the number of Unicode code points, including the end of line and even BOM if there is one) in each line was determined with a use of `utf8::distance`; finally, we have converted each line to UTF-16 encoding with `utf8to16` and back to UTF-8 with `utf16to8`. + +Note a different pattern of usage for old compilers. For instance, this is how we convert +a UTF-8 encoded string to a UTF-16 encoded one with a pre - C++11 compiler: +```cpp + vector utf16line; + utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line)); +``` + +With a more modern compiler, the same operation would look like: +```cpp + u16string utf16line = utf8::utf8to16(line); +``` +If `__cplusplus` macro points to a C++ 11 or later, the library exposes API that takes into +account C++ standard Unicode strings and move semantics. With an older compiler, it is still +possible to use the same functionality, just in a little less convenient way + +In case you do not trust the `__cplusplus` macro or, for instance, do not want to include +the C++ 11 helper functions even with a modern compiler, define `UTF_CPP_CPLUSPLUS` macro +before including `utf8.h` and assign it a value for the standard you want to use - the values are the same as for the `__cplusplus` macro. This can be also useful with compilers that are conservative in setting the `__cplusplus` macro even if they have a good support for a recent standard edition - Microsoft's Visual C++ is one example. + + +### Checking if a file contains valid UTF-8 text + +Here is a function that checks whether the content of a file is valid UTF-8 encoded text without reading the content into the memory: + +```cpp +bool valid_utf8_file(const char* file_name) +{ + ifstream ifs(file_name); + if (!ifs) + return false; // even better, throw here + + istreambuf_iterator it(ifs.rdbuf()); + istreambuf_iterator eos; + + return utf8::is_valid(it, eos); +} +``` + +Because the function `utf8::is_valid()` works with input iterators, we were able to pass an `istreambuf_iterator` to `it` and read the content of the file directly without loading it to the memory first. + +Note that other functions that take input iterator arguments can be used in a similar way. For instance, to read the content of a UTF-8 encoded text file and convert the text to UTF-16, just do something like: + +```cpp + utf8::utf8to16(it, eos, back_inserter(u16string)); +``` + + +### Ensure that a string contains valid UTF-8 text + +If we have some text that "probably" contains UTF-8 encoded text and we want to replace any invalid UTF-8 sequence with a replacement character, something like the following function may be used: + +```cpp +void fix_utf8_string(std::string& str) +{ + std::string temp; + utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp)); + str = temp; +} +``` + +The function will replace any invalid UTF-8 sequence with a Unicode replacement character. There is an overloaded function that enables the caller to supply their own replacement character. + + + +## Points of interest + + +#### Design goals and decisions + +The library was designed to be: + +1. Generic: for better or worse, there are many C++ string classes out there, and the library should work with as many of them as possible. +2. Portable: the library should be portable both across different platforms and compilers. The only non-portable code is a small section that declares unsigned integers of different sizes: three typedefs. They can be changed by the users of the library if they don't match their platform. The default setting should work for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives. Support for post C++03 language features is included for modern compilers at API level only, so the library should work even with pretty old compilers. +3. Lightweight: follow the "pay only for what you use" guideline. +4. Unintrusive: avoid forcing any particular design or even programming style on the user. This is a library, not a framework. + + +#### Alternatives + +For alternatives and comparisons, I recommend the following article: [The Wonderfully Terrible World of C and C++ Encoding APIs (with Some Rust)](https://thephd.dev/the-c-c++-rust-string-text-encoding-api-landscape), by JeanHeyd Meneide. In the article, this library is compared with: + +- [simdutf](https://github.com/simdutf/simdutf) +- [iconv](https://www.gnu.org/software/libiconv/) +- [boost.text](https://github.com/tzlaine/text) +- [ICU](https://unicode-org.github.io/icu/userguide/conversion/converters.html) +- [encoding_rs](https://github.com/hsivonen/encoding_rs) +- [Windows API functions for converting text between encodings](https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/) +- [ztd.text](https://github.com/soasis/text/) + +The article presents author's view of the quality of the API design, but also some speed benchmarks. + + +## Reference + + +### Functions From utf8 Namespace + + +#### utf8::append + + +##### octet_iterator append(utfchar32_t cp, octet_iterator result) + +Available in version 1.0 and later. + +Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string. + +```cpp +template +octet_iterator append(utfchar32_t cp, octet_iterator result); +``` + +`octet_iterator`: an output iterator. +`cp`: a 32 bit integer representing a code point to append to the sequence. +`result`: an output iterator to the place in the sequence where to append the code point. +Return value: an iterator pointing to the place after the newly appended sequence. + +Example of use: + +```cpp +unsigned char u[5] = {0,0,0,0,0}; +unsigned char* end = append(0x0448, u); +assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0); +``` + +Note that `append` does not allocate any memory - it is the burden of the caller to make sure there is enough memory allocated for the operation. To make things more interesting, `append` can add anywhere between 1 and 4 octets to the sequence. In practice, you would most often want to use `std::back_inserter` to ensure that the necessary memory is allocated. + +In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown. + + + +##### void append(utfchar32_t cp, std::string& s); + +Available in version 3.0 and later. Prior to 4.0 it required a C++ 11 compiler; the requirement is lifted with 4.0. + +Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string. + +```cpp +void append(utfchar32_t cp, std::string& s); +``` + +`cp`: a code point to append to the string. +`s`: a utf-8 encoded string to append the code point to. + +Example of use: + +```cpp +std::string u; +append(0x0448, u); +assert (u[0] == char(0xd1) && u[1] == char(0x88) && u.length() == 2); +``` + +In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown. + + +#### utf8::append16 + +##### word_iterator append16(utfchar32_t cp, word_iterator result) + +Available in version 4.0 and later. + +Encodes a 32 bit code point as a UTF-16 sequence of words and appends the sequence to a UTF-16 string. + +```cpp +template +word_iterator append16(utfchar32_t cp, word_iterator result); +``` + +`word_iterator`: an output iterator. +`cp`: a 32 bit integer representing a code point to append to the sequence. +`result`: an output iterator to the place in the sequence where to append the code point. +Return value: an iterator pointing to the place after the newly appended sequence. + +Example of use: + +```cpp +unsigned short u[2] = {0,0}; +unsigned short* end = append16(0x0448, u); +assert (u[0] == 0x0448 && u[1] == 0); +``` + +Note that `append16` does not allocate any memory - it is the burden of the caller to make sure there is enough memory allocated for the operation. To make things more interesting, `append16` can add either one or two words to the sequence. In practice, you would most often want to use `std::back_inserter` to ensure that the necessary memory is allocated. + +In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown. + + + +##### void append(utfchar32_t cp, std::u16string& s) + +Available in version 4.0 and later. Requires a C++11 compliant compiler. + +Encodes a 32 bit code point as a UTF-16 sequence of words and appends the sequence to a UTF-16 string. + +```cpp +void append(utfchar32_t cp, std::u16string& s); +``` + +`cp`: a code point to append to the string. +`s`: a utf-16 encoded string to append the code point to. + +Example of use: + +```cpp +std::u16string u; +append(0x0448, u); +assert (u[0] == 0x0448 && u.length() == 1); +``` + +In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown. + + + +#### utf8::next + +Available in version 1.0 and later. + +Given the iterator to the beginning of the UTF-8 sequence, it returns the code point and moves the iterator to the next position. + +```cpp +template +utfchar32_t next(octet_iterator& it, octet_iterator end); +``` + +`octet_iterator`: an input iterator. +`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point. +`end`: end of the UTF-8 sequence to be processed. If `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown. +Return value: the 32 bit representation of the processed UTF-8 code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars; +int cp = next(w, twochars + 6); +assert (cp == 0x65e5); +assert (w == twochars + 3); +``` + +This function is typically used to iterate through a UTF-8 encoded string. + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + +#### utf8::next16 + +Available in version 4.0 and later. + +Given the iterator to the beginning of the UTF-16 sequence, it returns the code point and moves the iterator to the next position. + +```cpp +template +utfchar32_t next16(word_iterator& it, word_iterator end); +``` + +`word_iterator`: an input iterator. +`it`: a reference to an iterator pointing to the beginning of an UTF-16 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point. +`end`: end of the UTF-16 sequence to be processed. If `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown. +Return value: the 32 bit representation of the processed UTF-16 code point. + +Example of use: + +```cpp +const unsigned short u[3] = {0x65e5, 0xd800, 0xdf46}; +const unsigned short* w = u; +int cp = next16(w, w + 3); +assert (cp, 0x65e5); +assert (w, u + 1); +``` + +This function is typically used to iterate through a UTF-16 encoded string. + +In case of an invalid UTF-16 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +#### utf8::peek_next + +Available in version 2.1 and later. + +Given the iterator to the beginning of the UTF-8 sequence, it returns the code point for the following sequence without changing the value of the iterator. + +```cpp +template +utfchar32_t peek_next(octet_iterator it, octet_iterator end); +``` + + +`octet_iterator`: an input iterator. +`it`: an iterator pointing to the beginning of an UTF-8 encoded code point. +`end`: end of the UTF-8 sequence to be processed. If `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown. +Return value: the 32 bit representation of the processed UTF-8 code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars; +int cp = peek_next(w, twochars + 6); +assert (cp == 0x65e5); +assert (w == twochars); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + +#### utf8::prior + +Available in version 1.02 and later. + +Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it decreases the iterator until it hits the beginning of the previous UTF-8 encoded code point and returns the 32 bits representation of the code point. + +```cpp +template +utfchar32_t prior(octet_iterator& it, octet_iterator start); +``` + +`octet_iterator`: a bidirectional iterator. +`it`: a reference pointing to an octet within a UTF-8 encoded string. After the function returns, it is decremented to point to the beginning of the previous code point. +`start`: an iterator to the beginning of the sequence where the search for the beginning of a code point is performed. It is a safety measure to prevent passing the beginning of the string in the search for a UTF-8 lead octet. + Return value: the 32 bit representation of the previous code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +unsigned char* w = twochars + 3; +int cp = prior (w, twochars); +assert (cp == 0x65e5); +assert (w == twochars); +``` + +This function has two purposes: one is two iterate backwards through a UTF-8 encoded string. Note that it is usually a better idea to iterate forward instead, since `utf8::next` is faster. The second purpose is to find a beginning of a UTF-8 sequence if we have a random position within a string. Note that in that case `utf8::prior` may not detect an invalid UTF-8 sequence in some scenarios: for instance if there are superfluous trail octets, it will just skip them. + +`it` will typically point to the beginning of a code point, and `start` will point to the beginning of the string to ensure we don't go backwards too far. `it` is decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence beginning with that octet is decoded to a 32 bit representation and returned. + +In case `start` is reached before a UTF-8 lead octet is hit, or if an invalid UTF-8 sequence is started by the lead octet, an `invalid_utf8` exception is thrown. + +In case `start` equals `it`, a `not_enough_room` exception is thrown. + + +#### utf8::advance +Available in version 1.0 and later. + +Advances an iterator by the specified number of code points within an UTF-8 sequence. + +```cpp +template +void advance (octet_iterator& it, distance_type n, octet_iterator end); +``` + +`octet_iterator`: an input iterator. +`distance_type`: an integral type convertible to `octet_iterator`'s difference type. +`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the nth following code point. +`n`: number of code points `it` should be advanced. A negative value means decrement. +`end`: limit of the UTF-8 sequence to be processed. If `n` is positive and `it` gets equal to `end` during the extraction of a code point, an `utf8::not_enough_room` exception is thrown. If `n` is negative and `it` reaches `end` while `it` points t a trail byte of a UTF-8 sequence, a `utf8::invalid_code_point` exception is thrown. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +unsigned char* w = twochars; +advance (w, 2, twochars + 6); +assert (w == twochars + 5); +advance (w, -2, twochars); +assert (w == twochars); +``` + +In case of an invalid code point, a `utf8::invalid_code_point` exception is thrown. + + +#### utf8::distance + +Available in version 1.0 and later. + +Given the iterators to two UTF-8 encoded code points in a sequence, returns the number of code points between them. + +```cpp +template +typename std::iterator_traits::difference_type distance (octet_iterator first, octet_iterator last); +``` + +`octet_iterator`: an input iterator. +`first`: an iterator to a beginning of a UTF-8 encoded code point. +`last`: an iterator to a "post-end" of the last UTF-8 encoded code point in the sequence we are trying to determine the length. It can be the beginning of a new code point, or not. + Return value the distance between the iterators, in code points. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +size_t dist = utf8::distance(twochars, twochars + 5); +assert (dist == 2); +``` + +This function is used to find the length (in code points) of a UTF-8 encoded string. The reason it is called _distance_, rather than, say, _length_ is mainly because developers are used that _length_ is an O(1) function. Computing the length of an UTF-8 string is a linear operation, and it looked better to model it after `std::distance` algorithm. + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. If `last` does not point to the past-of-end of a UTF-8 sequence, a `utf8::not_enough_room` exception is thrown. + + +#### utf8::utf16to8 + +##### octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + +Available in version 1.0 and later. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +template +octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result); +``` + +`u16bit_iterator`: an input iterator. +`octet_iterator`: an output iterator. +`start`: an iterator pointing to the beginning of the UTF-16 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-16 encoded string to convert. +`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-8 string. + +Example of use: + +```cpp +unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; +vector utf8result; +utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); +assert (utf8result.size() == 10); +``` + +In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown. + + + +##### std::string utf16to8(const std::u16string& s) + +Available in version 3.0 and later. Requires a C++ 11 compliant compiler. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +std::string utf16to8(const std::u16string& s); +``` + +`s`: a UTF-16 encoded string. +Return value: A UTF-8 encoded string. + +Example of use: + +```cpp + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string u = utf16to8(utf16string); + assert (u.size() == 10); +``` + +In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown. + + +##### std::string utf16to8(std::u16string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +std::string utf16to8(std::u16string_view s); +``` + +`s`: a UTF-16 encoded string. +Return value: A UTF-8 encoded string. + +Example of use: + +```cpp + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview(u16string); + string u = utf16to8(utf16string); + assert (u.size() == 10); +``` + +In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown. + + +#### utf8::utf16tou8 + +##### std::u8string utf16tou8(const std::u16string& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +std::u8string utf16tou8(const std::u16string& s); +``` + +`s`: a UTF-16 encoded string. +Return value: A UTF-8 encoded string. + +Example of use: + +```cpp + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u8string u = utf16tou8(utf16string); + assert (u.size() == 10); +``` + +In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown. + + +##### std::u8string utf16tou8(const std::u16string_view& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +std::u8string utf16tou8(const std::u16string_view& s); +``` + +`s`: a UTF-16 encoded string. +Return value: A UTF-8 encoded string. + +Example of use: + +```cpp + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview(u16string); + u8string u = utf16tou8(utf16string); + assert (u.size() == 10); +``` + +In case of invalid UTF-16 sequence, a `utf8::invalid_utf16` exception is thrown. + + +#### utf8::utf8to16 + +##### u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + +Available in version 1.0 and later. + +Converts an UTF-8 encoded string to UTF-16 + +```cpp +template +u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result); +``` + +`octet_iterator`: an input iterator. +`u16bit_iterator`: an output iterator. +`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert. +`result`: an output iterator to the place in the UTF-16 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-16 string. + +Example of use: + +```cpp +char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +vector utf16result; +utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); +assert (utf16result.size() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. If `end` does not point to the past-of-end of a UTF-8 sequence, a `utf8::not_enough_room` exception is thrown. + + + + +##### std::u16string utf8to16(const std::string& s) + +Available in version 3.0 and later. Requires a C++ 11 compliant compiler. + +Converts an UTF-8 encoded string to UTF-16. + +```cpp +std::u16string utf8to16(const std::string& s); +``` + +`s`: an UTF-8 encoded string to convert. +Return value: A UTF-16 encoded string + +Example of use: + +```cpp +string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +u16string utf16result = utf8to16(utf8_with_surrogates); +assert (utf16result.length() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +##### std::u16string utf8to16(std::string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Converts an UTF-8 encoded string to UTF-16. + +```cpp +std::u16string utf8to16(std::string_view s); +``` + +`s`: an UTF-8 encoded string to convert. +Return value: A UTF-16 encoded string + +Example of use: + +```cpp +string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +u16string utf16result = utf8to16(utf8_with_surrogates); +assert (utf16result.length() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +##### std::u16string utf8to16(std::u8string& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts an UTF-8 encoded string to UTF-16. + +```cpp +std::u16string utf8to16(std::u8string& s); +``` + +`s`: an UTF-8 encoded string to convert. +Return value: A UTF-16 encoded string + +Example of use: + +```cpp +std::u8string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +std::u16string utf16result = utf8to16(utf8_with_surrogates); +assert (utf16result.length() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +##### std::u16string utf8to16(std::u8string_view& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts an UTF-8 encoded string to UTF-16. + +```cpp +std::u16string utf8to16(std::u8string_view& s); +``` + +`s`: an UTF-8 encoded string to convert. +Return value: A UTF-16 encoded string + +Example of use: + +```cpp +std::u8string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +std::u8string_view utf8stringview {utf8_with_surrogates} +std::u16string utf16result = utf8to16(utf8stringview); +assert (utf16result.length() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + +#### utf8::utf32to8 + +##### octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + +Available in version 1.0 and later. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +template +octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result); +``` + +`octet_iterator`: an output iterator. +`u32bit_iterator`: an input iterator. +`start`: an iterator pointing to the beginning of the UTF-32 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-32 encoded string to convert. +`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-8 string. + +Example of use: + +```cpp +int utf32string[] = {0x448, 0x65E5, 0x10346, 0}; +vector utf8result; +utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + + +##### std::string utf32to8(const std::u32string& s) + +Available in version 3.0 and later. Requires a C++ 11 compliant compiler. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +std::string utf32to8(const std::u32string& s); +``` + +`s`: a UTF-32 encoded string. +Return value: a UTF-8 encoded string. + +Example of use: + +```cpp +u32string utf32string = {0x448, 0x65E5, 0x10346}; +string utf8result = utf32to8(utf32string); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + +##### std::u8string utf32to8(const std::u32string& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +std::u8string utf32to8(const std::u32string& s); +``` + +`s`: a UTF-32 encoded string. +Return value: a UTF-8 encoded string. + +Example of use: + +```cpp +u32string utf32string = {0x448, 0x65E5, 0x10346}; +u8string utf8result = utf32to8(utf32string); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + + +##### std::u8string utf32to8(const std::u32string_view& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +std::u8string utf32to8(const std::u32string_view& s); +``` + +`s`: a UTF-32 encoded string. +Return value: a UTF-8 encoded string. + +Example of use: + +```cpp +u32string utf32string = {0x448, 0x65E5, 0x10346}; +u32string_view utf32stringview(utf32string); +u8string utf8result = utf32to8(utf32stringview); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + + +##### std::string utf32to8(const std::u32string& s) + +Available in version 3.0 and later. Requires a C++ 11 compliant compiler. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +std::string utf32to8(const std::u32string& s); +``` + +`s`: a UTF-32 encoded string. +Return value: a UTF-8 encoded string. + +Example of use: + +```cpp +u32string utf32string = {0x448, 0x65E5, 0x10346}; +string utf8result = utf32to8(utf32string); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + +##### std::string utf32to8(std::u32string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +std::string utf32to8(std::u32string_view s); +``` + +`s`: a UTF-32 encoded string. +Return value: a UTF-8 encoded string. + +Example of use: + +```cpp +u32string utf32string = {0x448, 0x65E5, 0x10346}; +u32string_view utf32stringview(utf32string); +string utf8result = utf32to8(utf32stringview); +assert (utf8result.size() == 9); +``` + +In case of invalid UTF-32 string, a `utf8::invalid_code_point` exception is thrown. + + + +#### utf8::utf8to32 + +##### u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + +Available in version 1.0 and later. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +template +u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result); +``` + +`octet_iterator`: an input iterator. +`u32bit_iterator`: an output iterator. +`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert. +`result`: an output iterator to the place in the UTF-32 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-32 string. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +vector utf32result; +utf8to32(twochars, twochars + 5, back_inserter(utf32result)); +assert (utf32result.size() == 2); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. If `end` does not point to the past-of-end of a UTF-8 sequence, a `utf8::not_enough_room` exception is thrown. + + + + +##### std::u32string utf8to32(const std::u8string& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +std::u32string utf8to32(const std::u8string& s); +``` + +`s`: a UTF-8 encoded string. +Return value: a UTF-32 encoded string. + +Example of use: + +```cpp +const std::u8string* twochars = u8"\xe6\x97\xa5\xd1\x88"; +u32string utf32result = utf8to32(twochars); +assert (utf32result.size() == 2); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +##### std::u32string utf8to32(const std::u8string_view& s) + +Available in version 4.0 and later. Requires a C++ 20 compliant compiler. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +std::u32string utf8to32(const std::u8string_view& s); +``` + +`s`: a UTF-8 encoded string. +Return value: a UTF-32 encoded string. + +Example of use: + +```cpp +const u8string* twochars = u8"\xe6\x97\xa5\xd1\x88"; +const u8string_view stringview{twochars}; +u32string utf32result = utf8to32(stringview); +assert (utf32result.size() == 2); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + + +##### std::u32string utf8to32(const std::string& s) + +Available in version 3.0 and later. Requires a C++ 11 compliant compiler. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +std::u32string utf8to32(const std::string& s); +``` + +`s`: a UTF-8 encoded string. +Return value: a UTF-32 encoded string. + +Example of use: + +```cpp +const char* twochars = "\xe6\x97\xa5\xd1\x88"; +u32string utf32result = utf8to32(twochars); +assert (utf32result.size() == 2); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + +##### std::u32string utf8to32(std::string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +std::u32string utf8to32(std::string_view s); +``` + +`s`: a UTF-8 encoded string. +Return value: a UTF-32 encoded string. + +Example of use: + +```cpp +string_view twochars = "\xe6\x97\xa5\xd1\x88"; +u32string utf32result = utf8to32(twochars); +assert (utf32result.size() == 2); +``` + +In case of an invalid UTF-8 sequence, a `utf8::invalid_utf8` exception is thrown. + + +#### utf8::find_invalid + +##### octet_iterator find_invalid(octet_iterator start, octet_iterator end) + +Available in version 1.0 and later. + +Detects an invalid sequence within a UTF-8 string. + +```cpp +template +octet_iterator find_invalid(octet_iterator start, octet_iterator end); +``` + +`octet_iterator`: an input iterator. +`start`: an iterator pointing to the beginning of the UTF-8 string to test for validity. +`end`: an iterator pointing to pass-the-end of the UTF-8 string to test for validity. +Return value: an iterator pointing to the first invalid octet in the UTF-8 string. In case none were found, equals `end`. + +Example of use: + +```cpp +char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; +char* invalid = find_invalid(utf_invalid, utf_invalid + 6); +assert (invalid == utf_invalid + 5); +``` + +This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it. + + + +##### const char* find_invalid(const char* str) + +Available in version 4.0 and later. + +Detects an invalid sequence within a C-style UTF-8 string. + +```cpp +const char* find_invalid(const char* str); +``` + +`str`: a UTF-8 encoded string. +Return value: a pointer to the first invalid octet in the UTF-8 string. In case none were found, points to the trailing zero byte. + +Example of use: + +```cpp +const char* utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; +const char* invalid = find_invalid(utf_invalid); +assert ((invalid - utf_invalid) == 5); +``` + +This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it. + + +##### std::size_t find_invalid(const std::string& s) + +Available in version 3.0 and later. Prior to 4.0 it required a C++ 11 compiler; the requirement is lifted with 4.0 + +Detects an invalid sequence within a UTF-8 string. + +```cpp +std::size_t find_invalid(const std::string& s); +``` + +`s`: a UTF-8 encoded string. +Return value: the index of the first invalid octet in the UTF-8 string. In case none were found, equals `std::string::npos`. + +Example of use: + +```cpp +string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; +auto invalid = find_invalid(utf_invalid); +assert (invalid == 5); +``` + +This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it. + + +##### std::size_t find_invalid(std::string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Detects an invalid sequence within a UTF-8 string. + +```cpp +std::size_t find_invalid(std::string_view s); +``` + +`s`: a UTF-8 encoded string. +Return value: the index of the first invalid octet in the UTF-8 string. In case none were found, equals `std::string_view::npos`. + +Example of use: + +```cpp +string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; +auto invalid = find_invalid(utf_invalid); +assert (invalid == 5); +``` + +This function is typically used to make sure a UTF-8 string is valid before processing it with other functions. It is especially important to call it if before doing any of the _unchecked_ operations on it. + + +#### utf8::is_valid + +##### bool is_valid(octet_iterator start, octet_iterator end) + +Available in version 1.0 and later. + +Checks whether a sequence of octets is a valid UTF-8 string. + +```cpp +template +bool is_valid(octet_iterator start, octet_iterator end); +``` + +`octet_iterator`: an input iterator. +`start`: an iterator pointing to the beginning of the UTF-8 string to test for validity. +`end`: an iterator pointing to pass-the-end of the UTF-8 string to test for validity. +Return value: `true` if the sequence is a valid UTF-8 string; `false` if not. + +Example of use: + +```cpp +char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; +bool bvalid = is_valid(utf_invalid, utf_invalid + 6); +assert (bvalid == false); +``` + +`is_valid` is a shorthand for `find_invalid(start, end) == end;`. You may want to use it to make sure that a byte sequence is a valid UTF-8 string without the need to know where it fails if it is not valid. + + + +##### bool is_valid(const char* str) + +Available in version 4.0 and later. + +Checks whether a C-style string contains valid UTF-8 encoded text. + +```cpp +bool is_valid(const char* str); +``` + +`str`: a UTF-8 encoded string. +Return value: `true` if the string contains valid UTF-8 encoded text; `false` if not. + +Example of use: + +```cpp +char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; +bool bvalid = is_valid(utf_invalid); +assert (bvalid == false); +``` + +You may want to use `is_valid` to make sure that a string contains valid UTF-8 text without the need to know where it fails if it is not valid. + + + +##### bool is_valid(const std::string& s) + +Available in version 3.0 and later. Prior to 4.0 it required a C++ 11 compiler; the requirement is lifted with 4.0 + +Checks whether a string object contains valid UTF-8 encoded text. + +```cpp +bool is_valid(const std::string& s); +``` + +`s`: a UTF-8 encoded string. +Return value: `true` if the string contains valid UTF-8 encoded text; `false` if not. + +Example of use: + +```cpp +char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; +bool bvalid = is_valid(utf_invalid); +assert (bvalid == false); +``` + +You may want to use `is_valid` to make sure that a string contains valid UTF-8 text without the need to know where it fails if it is not valid. + + +##### bool is_valid(std::string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Checks whether a string object contains valid UTF-8 encoded text. + +```cpp +bool is_valid(std::string_view s); +``` + +`s`: a UTF-8 encoded string. +Return value: `true` if the string contains valid UTF-8 encoded text; `false` if not. + +Example of use: + +```cpp +string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; +bool bvalid = is_valid(utf_invalid); +assert (bvalid == false); +``` + +You may want to use `is_valid` to make sure that a string contains valid UTF-8 text without the need to know where it fails if it is not valid. + + +#### utf8::replace_invalid + +##### output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement) + +Available in version 2.0 and later. + +Replaces all invalid UTF-8 sequences within a string with a replacement marker. + +```cpp +template +output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement); +template +output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out); +``` + +`octet_iterator`: an input iterator. +`output_iterator`: an output iterator. +`start`: an iterator pointing to the beginning of the UTF-8 string to look for invalid UTF-8 sequences. +`end`: an iterator pointing to pass-the-end of the UTF-8 string to look for invalid UTF-8 sequences. +`out`: An output iterator to the range where the result of replacement is stored. +`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd` +Return value: An iterator pointing to the place after the UTF-8 string with replaced invalid sequences. + +Example of use: + +```cpp +char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; +vector replace_invalid_result; +replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), '?'); +bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); +assert (bvalid); +char* fixed_invalid_sequence = "a????z"; +assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence)); +``` + +`replace_invalid` does not perform in-place replacement of invalid sequences. Rather, it produces a copy of the original string with the invalid sequences replaced with a replacement marker. Therefore, `out` must not be in the `[start, end]` range. + + + +##### std::string replace_invalid(const std::string& s, utfchar32_t replacement) + +Available in version 3.0 and later. Prior to 4.0 it required a C++ 11 compiler; the requirement is lifted with 4.0 + +Replaces all invalid UTF-8 sequences within a string with a replacement marker. + +```cpp +std::string replace_invalid(const std::string& s, utfchar32_t replacement); +std::string replace_invalid(const std::string& s); +``` + +`s`: a UTF-8 encoded string. +`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd` +Return value: A UTF-8 encoded string with replaced invalid sequences. + +Example of use: + +```cpp +string invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; +string replace_invalid_result = replace_invalid(invalid_sequence, '?'); +bvalid = is_valid(replace_invalid_result); +assert (bvalid); +const string fixed_invalid_sequence = "a????z"; +assert (fixed_invalid_sequence == replace_invalid_result); +``` + + +##### std::string replace_invalid(std::string_view s, char32_t replacement) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Replaces all invalid UTF-8 sequences within a string with a replacement marker. + +```cpp +std::string replace_invalid(std::string_view s, char32_t replacement); +std::string replace_invalid(std::string_view s); +``` + +`s`: a UTF-8 encoded string. +`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd` +Return value: A UTF-8 encoded string with replaced invalid sequences. + +Example of use: + +```cpp +string_view invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; +string replace_invalid_result = replace_invalid(invalid_sequence, '?'); +bool bvalid = is_valid(replace_invalid_result); +assert (bvalid); +const string fixed_invalid_sequence = "a????z"; +assert(fixed_invalid_sequence, replace_invalid_result); +``` + + +#### utf8::starts_with_bom + +##### bool starts_with_bom (octet_iterator it, octet_iterator end) + +Available in version 2.3 and later. + +Checks whether an octet sequence starts with a UTF-8 byte order mark (BOM) + +```cpp +template +bool starts_with_bom (octet_iterator it, octet_iterator end); +``` + +`octet_iterator`: an input iterator. +`it`: beginning of the octet sequence to check +`end`: pass-end of the sequence to check +Return value: `true` if the sequence starts with a UTF-8 byte order mark; `false` if not. + +Example of use: + +```cpp +unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf}; +bool bbom = starts_with_bom(byte_order_mark, byte_order_mark + sizeof(byte_order_mark)); +assert (bbom == true); +``` + +The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text. + + + +##### bool starts_with_bom(const std::string& s) + +Available in version 3.0 and later. Prior to 4.0 it required a C++ 11 compiler; the requirement is lifted with 4.0 + +Checks whether a string starts with a UTF-8 byte order mark (BOM) + +```cpp +bool starts_with_bom(const std::string& s); +``` + +`s`: a UTF-8 encoded string. +Return value: `true` if the string starts with a UTF-8 byte order mark; `false` if not. + +Example of use: + +```cpp +string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; +bool bbom = starts_with_bom(byte_order_mark); +assert (bbom == true); +string threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; +bool no_bbom = starts_with_bom(threechars); +assert (no_bbom == false); + ``` + +The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text. + + + +##### bool starts_with_bom(std::string_view s) + +Available in version 3.2 and later. Requires a C++ 17 compliant compiler. + +Checks whether a string starts with a UTF-8 byte order mark (BOM) + +```cpp +bool starts_with_bom(std::string_view s); +``` + +`s`: a UTF-8 encoded string. +Return value: `true` if the string starts with a UTF-8 byte order mark; `false` if not. + +Example of use: + +```cpp +string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; +string_view byte_order_mark_view(byte_order_mark); +bool bbom = starts_with_bom(byte_order_mark_view); +assert (bbom); +string_view threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; +bool no_bbom = starts_with_bom(threechars); +assert (!no_bbom); + ``` + +The typical use of this function is to check the first three bytes of a file. If they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8 encoded text. + + + +### Types From utf8 Namespace + + +#### utf8::exception + +Available in version 2.3 and later. + +Base class for the exceptions thrown by UTF CPP library functions. + +```cpp +class exception : public std::exception {}; +``` + +Example of use: + +```cpp +try { + code_that_uses_utf_cpp_library(); +} +catch(const utf8::exception& utfcpp_ex) { + cerr << utfcpp_ex.what(); +} +``` + + +#### utf8::invalid_code_point + +Available in version 1.0 and later. + +Thrown by UTF8 CPP functions such as `advance` and `next` if an UTF-8 sequence represents and invalid code point. + +```cpp +class invalid_code_point : public exception { +public: + utfchar32_t code_point() const; +}; +``` + +Member function `code_point()` can be used to determine the invalid code point that caused the exception to be thrown. + + +#### utf8::invalid_utf8 + +Available in version 1.0 and later. + +Thrown by UTF8 CPP functions such as `next` and `prior` if an invalid UTF-8 sequence is detected during decoding. + +```cpp +class invalid_utf8 : public exception { +public: + utfchar8_t utf8_octet() const; +}; +``` + +Member function `utf8_octet()` can be used to determine the beginning of the byte sequence that caused the exception to be thrown. + + +#### utf8::invalid_utf16 + +Available in version 1.0 and later. + +Thrown by UTF8 CPP function `utf16to8` if an invalid UTF-16 sequence is detected during decoding. + +```cpp +class invalid_utf16 : public exception { +public: + utfchar16_t utf16_word() const; +}; +``` + +Member function `utf16_word()` can be used to determine the UTF-16 code unit that caused the exception to be thrown. + + +#### utf8::not_enough_room + +Available in version 1.0 and later. + +Thrown by UTF8 CPP functions such as `next` if the end of the decoded UTF-8 sequence was reached before the code point was decoded. + +```cpp +class not_enough_room : public exception {}; +``` + + +#### utf8::iterator + +Available in version 2.0 and later. + +Adapts the underlying octet iterator to iterate over the sequence of code points, rather than raw octets. + +```cpp +template +class iterator; +``` + + +##### Member functions + +`iterator();` the default constructor; the underlying octet_iterator is constructed with its default constructor. + +`explicit iterator (const octet_iterator& octet_it, const octet_iterator& range_start, const octet_iterator& range_end);` a constructor that initializes the underlying octet_iterator with octet_it and sets the range in which the iterator is considered valid. + +`octet_iterator base () const;` returns the underlying octet_iterator. + +`utfchar32_t operator * () const;` decodes the utf-8 sequence the underlying octet_iterator is pointing to and returns the code point. + +`bool operator == (const iterator& rhs) const;` returns `true` if the two underlying iterators are equal. + +`bool operator != (const iterator& rhs) const;` returns `true` if the two underlying iterators are not equal. + +`iterator& operator ++ ();` the prefix increment - moves the iterator to the next UTF-8 encoded code point. + +`iterator operator ++ (int);` the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one. + +`iterator& operator -- ();` the prefix decrement - moves the iterator to the previous UTF-8 encoded code point. + +`iterator operator -- (int);` the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one. + +Example of use: + +```cpp +char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; +utf8::iterator it(threechars, threechars, threechars + 9); +utf8::iterator it2 = it; +assert (it2 == it); +assert (*it == 0x10346); +assert (*(++it) == 0x65e5); +assert ((*it++) == 0x65e5); +assert (*it == 0x0448); +assert (it != it2); +utf8::iterator endit (threechars + 9, threechars, threechars + 9); +assert (++it == endit); +assert (*(--it) == 0x0448); +assert ((*it--) == 0x0448); +assert (*it == 0x65e5); +assert (--it == utf8::iterator(threechars, threechars, threechars + 9)); +assert (*it == 0x10346); +``` + +The purpose of `utf8::iterator` adapter is to enable easy iteration as well as the use of STL algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of `utf8::next()` and `utf8::prior()` functions. + +Note that `utf8::iterator` adapter is a checked iterator. It operates on the range specified in the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically, the range will be determined by sequence container functions `begin` and `end`, i.e.: + +```cpp +std::string s = "example"; +utf8::iterator i (s.begin(), s.begin(), s.end()); +``` + + +### Functions From utf8::unchecked Namespace + + +#### utf8::unchecked::append + +Available in version 1.0 and later. + +Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence to a UTF-8 string. + +```cpp +template +octet_iterator append(utfchar32_t cp, octet_iterator result); +``` + +`cp`: A 32 bit integer representing a code point to append to the sequence. +`result`: An output iterator to the place in the sequence where to append the code point. +Return value: An iterator pointing to the place after the newly appended sequence. + +Example of use: + +```cpp +unsigned char u[5] = {0,0,0,0,0}; +unsigned char* end = unchecked::append(0x0448, u); +assert (u[0] == 0xd1 && u[1] == 0x88 && u[2] == 0 && u[3] == 0 && u[4] == 0); +``` + +This is a faster but less safe version of `utf8::append`. It does not check for validity of the supplied code point, and may produce an invalid UTF-8 sequence. + + +#### utf8::unchecked::append16 + +Available in version 4.0 and later. + +Encodes a 32 bit code point as a UTF-16 sequence of words and appends the sequence to a UTF-16 string. + +```cpp +template +word_iterator append16(utfchar32_t cp, word_iterator result) +``` + +`cp`: A 32 bit integer representing a code point to append to the sequence. +`result`: An output iterator to the place in the sequence where to append the code point. +Return value: An iterator pointing to the place after the newly appended sequence. + +Example of use: + +```cpp +unsigned short u[5] = {0,0}; +utf8::unchecked::append16(0x0448, u); +assert(u[0], 0x0448); +assert(u[1], 0x0000); +``` + +This is a faster but less safe version of `utf8::append`. It does not check for validity of the supplied code point, and may produce an invalid UTF-8 sequence. + + + +#### utf8::unchecked::next + +Available in version 1.0 and later. + +Given the iterator to the beginning of a UTF-8 sequence, it returns the code point and moves the iterator to the next position. + +```cpp +template +utfchar32_t next(octet_iterator& it); +``` + +`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point. + Return value: the 32 bit representation of the processed UTF-8 code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars; +int cp = unchecked::next(w); +assert (cp == 0x65e5); +assert (w == twochars + 3); +``` + +This is a faster but less safe version of `utf8::next`. It does not check for validity of the supplied UTF-8 sequence. + + +#### utf8::next16 + +Available in version 4.0 and later. + +Given the iterator to the beginning of the UTF-16 sequence, it returns the code point and moves the iterator to the next position. + +```cpp +template +utfchar32_t next16(word_iterator& it); +``` + +`word_iterator`: an input iterator. +`it`: a reference to an iterator pointing to the beginning of an UTF-16 encoded code point. After the function returns, it is incremented to point to the beginning of the next code point. + +Return value: the 32 bit representation of the processed UTF-16 code point. + +Example of use: + +```cpp +const unsigned short u[3] = {0x65e5, 0xd800, 0xdf46}; +const unsigned short* w = u; +int cp = unchecked::next16(w); +assert (cp, 0x65e5); +assert (w, u + 1); +``` + +This function is typically used to iterate through a UTF-16 encoded string. + +This is a faster but less safe version of `utf8::next16`. It does not check for validity of the supplied UTF-8 sequence. + + + +#### utf8::unchecked::peek_next + +Available in version 2.1 and later. + +Given the iterator to the beginning of a UTF-8 sequence, it returns the code point. + +```cpp +template +utfchar32_t peek_next(octet_iterator it); +``` + +`it`: an iterator pointing to the beginning of an UTF-8 encoded code point. +Return value: the 32 bit representation of the processed UTF-8 code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars; +int cp = unchecked::peek_next(w); +assert (cp == 0x65e5); +assert (w == twochars); +``` + +This is a faster but less safe version of `utf8::peek_next`. It does not check for validity of the supplied UTF-8 sequence. + + +#### utf8::unchecked::prior + +Available in version 1.02 and later. + +Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it decreases the iterator until it hits the beginning of the previous UTF-8 encoded code point and returns the 32 bits representation of the code point. + +```cpp +template +utfchar32_t prior(octet_iterator& it); +``` + +`it`: a reference pointing to an octet within a UTF-8 encoded string. After the function returns, it is decremented to point to the beginning of the previous code point. + Return value: the 32 bit representation of the previous code point. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars + 3; +int cp = unchecked::prior (w); +assert (cp == 0x65e5); +assert (w == twochars); +``` + +This is a faster but less safe version of `utf8::prior`. It does not check for validity of the supplied UTF-8 sequence and offers no boundary checking. + + +#### utf8::unchecked::advance + +Available in version 1.0 and later. + +Advances an iterator by the specified number of code points within an UTF-8 sequence. + +```cpp +template +void advance (octet_iterator& it, distance_type n); +``` + +`it`: a reference to an iterator pointing to the beginning of an UTF-8 encoded code point. After the function returns, it is incremented to point to the nth following code point. +`n`: number of code points `it` should be advanced. A negative value means decrement. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +char* w = twochars; +unchecked::advance (w, 2); +assert (w == twochars + 5); +``` + +This is a faster but less safe version of `utf8::advance`. It does not check for validity of the supplied UTF-8 sequence and offers no boundary checking. + + +#### utf8::unchecked::distance + +Available in version 1.0 and later. + +Given the iterators to two UTF-8 encoded code points in a sequence, returns the number of code points between them. + +```cpp +template +typename std::iterator_traits::difference_type distance (octet_iterator first, octet_iterator last); +``` + +`first`: an iterator to a beginning of a UTF-8 encoded code point. +`last`: an iterator to a "post-end" of the last UTF-8 encoded code point in the sequence we are trying to determine the length. It can be the beginning of a new code point, or not. +Return value: the distance between the iterators, in code points. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +size_t dist = utf8::unchecked::distance(twochars, twochars + 5); +assert (dist == 2); +``` + +This is a faster but less safe version of `utf8::distance`. It does not check for validity of the supplied UTF-8 sequence. + + +#### utf8::unchecked::utf16to8 + +Available in version 1.0 and later. + +Converts a UTF-16 encoded string to UTF-8. + +```cpp +template +octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result); +``` + +`start`: an iterator pointing to the beginning of the UTF-16 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-16 encoded string to convert. +`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-8 string. + +Example of use: + +```cpp +unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; +vector utf8result; +unchecked::utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); +assert (utf8result.size() == 10); +``` + +This is a faster but less safe version of `utf8::utf16to8`. It does not check for validity of the supplied UTF-16 sequence. + + +#### utf8::unchecked::utf8to16 + +Available in version 1.0 and later. + +Converts an UTF-8 encoded string to UTF-16 + +```cpp +template +u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result); +``` + +`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert. +`result`: an output iterator to the place in the UTF-16 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-16 string. + +Example of use: + +```cpp +char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; +vector utf16result; +unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); +assert (utf16result.size() == 4); +assert (utf16result[2] == 0xd834); +assert (utf16result[3] == 0xdd1e); +``` + +This is a faster but less safe version of `utf8::utf8to16`. It does not check for validity of the supplied UTF-8 sequence. + + +#### utf8::unchecked::utf32to8 + +Available in version 1.0 and later. + +Converts a UTF-32 encoded string to UTF-8. + +```cpp +template +octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result); +``` + +`start`: an iterator pointing to the beginning of the UTF-32 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-32 encoded string to convert. +`result`: an output iterator to the place in the UTF-8 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-8 string. + +Example of use: + +```cpp +int utf32string[] = {0x448, 0x65e5, 0x10346, 0}; +vector utf8result; +utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); +assert (utf8result.size() == 9); +``` + +This is a faster but less safe version of `utf8::utf32to8`. It does not check for validity of the supplied UTF-32 sequence. + + +#### utf8::unchecked::utf8to32 + +Available in version 1.0 and later. + +Converts a UTF-8 encoded string to UTF-32. + +```cpp +template +u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result); +``` + +`start`: an iterator pointing to the beginning of the UTF-8 encoded string to convert. +`end`: an iterator pointing to pass-the-end of the UTF-8 encoded string to convert. +`result`: an output iterator to the place in the UTF-32 string where to append the result of conversion. +Return value: An iterator pointing to the place after the appended UTF-32 string. + +Example of use: + +```cpp +char* twochars = "\xe6\x97\xa5\xd1\x88"; +vector utf32result; +unchecked::utf8to32(twochars, twochars + 5, back_inserter(utf32result)); +assert (utf32result.size() == 2); +``` + +This is a faster but less safe version of `utf8::utf8to32`. It does not check for validity of the supplied UTF-8 sequence. + + +#### utf8::unchecked::replace_invalid + +Available in version 3.1 and later. + +Replaces all invalid UTF-8 sequences within a string with a replacement marker. + +```cpp +template +output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement); +template +output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out); +``` + +`octet_iterator`: an input iterator. +`output_iterator`: an output iterator. +`start`: an iterator pointing to the beginning of the UTF-8 string to look for invalid UTF-8 sequences. +`end`: an iterator pointing to pass-the-end of the UTF-8 string to look for invalid UTF-8 sequences. +`out`: An output iterator to the range where the result of replacement is stored. +`replacement`: A Unicode code point for the replacement marker. The version without this parameter assumes the value `0xfffd` +Return value: An iterator pointing to the place after the UTF-8 string with replaced invalid sequences. + +Example of use: + +```cpp +char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; +vector replace_invalid_result; +unchecked::replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), '?'); +bvalid = utf8::is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); +assert (bvalid); +char* fixed_invalid_sequence = "a????z"; +assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence)); +``` + +`replace_invalid` does not perform in-place replacement of invalid sequences. Rather, it produces a copy of the original string with the invalid sequences replaced with a replacement marker. Therefore, `out` must not be in the `[start, end]` range. + +Unlike `utf8::replace_invalid`, this function does not verify validity of the replacement marker. + + +### Types From utf8::unchecked Namespace + + +#### utf8::iterator + +Available in version 2.0 and later. + +Adapts the underlying octet iterator to iterate over the sequence of code points, rather than raw octets. + +```cpp +template +class iterator; +``` + + +##### Member functions + +`iterator();` the default constructor; the underlying octet_iterator is constructed with its default constructor. + +`explicit iterator (const octet_iterator& octet_it);` a constructor that initializes the underlying octet_iterator with `octet_it`. + +`octet_iterator base () const;` returns the underlying octet_iterator. + +`utfchar32_t operator * () const;` decodes the utf-8 sequence the underlying octet_iterator is pointing to and returns the code point. + +`bool operator == (const iterator& rhs) const;` returns `true` if the two underlying iterators are equal. + +`bool operator != (const iterator& rhs) const;` returns `true` if the two underlying iterators are not equal. + +`iterator& operator ++ ();` the prefix increment - moves the iterator to the next UTF-8 encoded code point. + +`iterator operator ++ (int);` the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one. + +`iterator& operator -- ();` the prefix decrement - moves the iterator to the previous UTF-8 encoded code point. + +`iterator operator -- (int);` the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one. + +Example of use: + +```cpp +char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; +utf8::unchecked::iterator un_it(threechars); +utf8::unchecked::iterator un_it2 = un_it; +assert (un_it2 == un_it); +assert (*un_it == 0x10346); +assert (*(++un_it) == 0x65e5); +assert ((*un_it++) == 0x65e5); +assert (*un_it == 0x0448); +assert (un_it != un_it2); +utf8::::unchecked::iterator un_endit (threechars + 9); +assert (++un_it == un_endit); +assert (*(--un_it) == 0x0448); +assert ((*un_it--) == 0x0448); +assert (*un_it == 0x65e5); +assert (--un_it == utf8::unchecked::iterator(threechars)); +assert (*un_it == 0x10346); +``` + +This is an unchecked version of `utf8::iterator`. It is faster in many cases, but offers no validity or range checks. + diff --git a/external/utfcpp/extern/ftest b/external/utfcpp/extern/ftest new file mode 160000 index 000000000..c4ad4af09 --- /dev/null +++ b/external/utfcpp/extern/ftest @@ -0,0 +1 @@ +Subproject commit c4ad4af0946b73ce1a40cbc72205d15d196c7e06 diff --git a/external/utfcpp/source/utf8.h b/external/utfcpp/source/utf8.h new file mode 100644 index 000000000..b51353093 --- /dev/null +++ b/external/utfcpp/source/utf8.h @@ -0,0 +1,46 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +/* +To control the C++ language version used by the library, you can define UTF_CPP_CPLUSPLUS macro +and set it to one of the values used by the __cplusplus predefined macro. + +For instance, + #define UTF_CPP_CPLUSPLUS 199711L +will cause the UTF-8 CPP library to use only types and language features available in the C++ 98 standard. +Some library features will be disabled. + +If you leave UTF_CPP_CPLUSPLUS undefined, it will be internally assigned to __cplusplus. +*/ + +#include "utf8/checked.h" +#include "utf8/unchecked.h" + +#endif // header guard diff --git a/external/utfcpp/source/utf8/checked.h b/external/utfcpp/source/utf8/checked.h new file mode 100644 index 000000000..98949f8bc --- /dev/null +++ b/external/utfcpp/source/utf8/checked.h @@ -0,0 +1,359 @@ +// Copyright 2006-2016 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" +#include + +namespace utf8 +{ + // Base for the exceptions that may be thrown from the library + class exception : public ::std::exception { + }; + + // Exceptions that may be thrown from the library functions. + class invalid_code_point : public exception { + utfchar32_t cp; + public: + invalid_code_point(utfchar32_t codepoint) : cp(codepoint) {} + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid code point"; } + utfchar32_t code_point() const {return cp;} + }; + + class invalid_utf8 : public exception { + utfchar8_t u8; + public: + invalid_utf8 (utfchar8_t u) : u8(u) {} + invalid_utf8 (char c) : u8(static_cast(c)) {} + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-8"; } + utfchar8_t utf8_octet() const {return u8;} + }; + + class invalid_utf16 : public exception { + utfchar16_t u16; + public: + invalid_utf16 (utfchar16_t u) : u16(u) {} + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-16"; } + utfchar16_t utf16_word() const {return u16;} + }; + + class not_enough_room : public exception { + public: + virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Not enough space"; } + }; + + /// The library API - functions intended to be called by the users + + template + octet_iterator append(utfchar32_t cp, octet_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + return internal::append(cp, result); + } + + inline void append(utfchar32_t cp, std::string& s) + { + append(cp, std::back_inserter(s)); + } + + template + word_iterator append16(utfchar32_t cp, word_iterator result) + { + if (!utf8::internal::is_code_point_valid(cp)) + throw invalid_code_point(cp); + + return internal::append16(cp, result); + } + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + out = utf8::append (replacement, out); + start = end; + break; + case internal::INVALID_LEAD: + out = utf8::append (replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + out = utf8::append (replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const utfchar32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::replace_invalid(start, end, out, replacement_marker); + } + + inline std::string replace_invalid(const std::string& s, utfchar32_t replacement) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::string replace_invalid(const std::string& s) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + template + utfchar32_t next(octet_iterator& it, octet_iterator end) + { + utfchar32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); + switch (err_code) { + case internal::UTF8_OK : + break; + case internal::NOT_ENOUGH_ROOM : + throw not_enough_room(); + case internal::INVALID_LEAD : + case internal::INCOMPLETE_SEQUENCE : + case internal::OVERLONG_SEQUENCE : + throw invalid_utf8(static_cast(*it)); + case internal::INVALID_CODE_POINT : + throw invalid_code_point(cp); + } + return cp; + } + + template + utfchar32_t next16(word_iterator& it, word_iterator end) + { + utfchar32_t cp = 0; + internal::utf_error err_code = utf8::internal::validate_next16(it, end, cp); + if (err_code == internal::NOT_ENOUGH_ROOM) + throw not_enough_room(); + return cp; + } + + template + utfchar32_t peek_next(octet_iterator it, octet_iterator end) + { + return utf8::next(it, end); + } + + template + utfchar32_t prior(octet_iterator& it, octet_iterator start) + { + // can't do much if it == start + if (it == start) + throw not_enough_room(); + + octet_iterator end = it; + // Go back until we hit either a lead octet or start + while (utf8::internal::is_trail(*(--it))) + if (it == start) + throw invalid_utf8(*it); // error - no lead byte in the sequence + return utf8::peek_next(it, end); + } + + template + void advance (octet_iterator& it, distance_type n, octet_iterator end) + { + const distance_type zero(0); + if (n < zero) { + // backward + for (distance_type i = n; i < zero; ++i) + utf8::prior(it, end); + } else { + // forward + for (distance_type i = zero; i < n; ++i) + utf8::next(it, end); + } + } + + template + typename std::iterator_traits::difference_type + distance (octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::next(first, last); + return dist; + } + + template + octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + utfchar32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + if (start != end) { + const utfchar32_t trail_surrogate = utf8::internal::mask16(*start++); + if (utf8::internal::is_trail_surrogate(trail_surrogate)) + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + else + throw invalid_utf16(static_cast(trail_surrogate)); + } + else + throw invalid_utf16(static_cast(cp)); + + } + // Lone trail surrogate + else if (utf8::internal::is_trail_surrogate(cp)) + throw invalid_utf16(static_cast(cp)); + + result = utf8::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start < end) { + const utfchar32_t cp = utf8::next(start, end); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = utf8::next(start, end); + + return result; + } + + // The iterator class + template + class iterator { + octet_iterator it; + octet_iterator range_start; + octet_iterator range_end; + public: + typedef utfchar32_t value_type; + typedef utfchar32_t* pointer; + typedef utfchar32_t& reference; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + iterator () {} + explicit iterator (const octet_iterator& octet_it, + const octet_iterator& rangestart, + const octet_iterator& rangeend) : + it(octet_it), range_start(rangestart), range_end(rangeend) + { + if (it < range_start || it > range_end) + throw std::out_of_range("Invalid utf-8 iterator position"); + } + // the default "big three" are OK + octet_iterator base () const { return it; } + utfchar32_t operator * () const + { + octet_iterator temp = it; + return utf8::next(temp, range_end); + } + bool operator == (const iterator& rhs) const + { + if (range_start != rhs.range_start || range_end != rhs.range_end) + throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + utf8::next(it, range_end); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + utf8::next(it, range_end); + return temp; + } + iterator& operator -- () + { + utf8::prior(it, range_start); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::prior(it, range_start); + return temp; + } + }; // class iterator + +} // namespace utf8 + +#if UTF_CPP_CPLUSPLUS >= 202002L // C++ 20 or later +#include "cpp20.h" +#elif UTF_CPP_CPLUSPLUS >= 201703L // C++ 17 or later +#include "cpp17.h" +#elif UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later +#include "cpp11.h" +#endif // C++ 11 or later + +#endif //header guard + diff --git a/external/utfcpp/source/utf8/core.h b/external/utfcpp/source/utf8/core.h new file mode 100644 index 000000000..4494c538e --- /dev/null +++ b/external/utfcpp/source/utf8/core.h @@ -0,0 +1,492 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include +#include +#include + +// Determine the C++ standard version. +// If the user defines UTF_CPP_CPLUSPLUS, use that. +// Otherwise, trust the unreliable predefined macro __cplusplus + +#if !defined UTF_CPP_CPLUSPLUS + #define UTF_CPP_CPLUSPLUS __cplusplus +#endif + +#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later + #define UTF_CPP_OVERRIDE override + #define UTF_CPP_NOEXCEPT noexcept +#else // C++ 98/03 + #define UTF_CPP_OVERRIDE + #define UTF_CPP_NOEXCEPT throw() +#endif // C++ 11 or later + + +namespace utf8 +{ +// The typedefs for 8-bit, 16-bit and 32-bit code units +#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later + #if UTF_CPP_CPLUSPLUS >= 202002L // C++ 20 or later + typedef char8_t utfchar8_t; + #else // C++ 11/14/17 + typedef unsigned char utfchar8_t; + #endif + typedef char16_t utfchar16_t; + typedef char32_t utfchar32_t; +#else // C++ 98/03 + typedef unsigned char utfchar8_t; + typedef unsigned short utfchar16_t; + typedef unsigned int utfchar32_t; +#endif // C++ 11 or later + +// Helper code - not intended to be directly called by the library users. May be changed at any time +namespace internal +{ + // Unicode constants + // Leading (high) surrogates: 0xd800 - 0xdbff + // Trailing (low) surrogates: 0xdc00 - 0xdfff + const utfchar16_t LEAD_SURROGATE_MIN = 0xd800u; + const utfchar16_t LEAD_SURROGATE_MAX = 0xdbffu; + const utfchar16_t TRAIL_SURROGATE_MIN = 0xdc00u; + const utfchar16_t TRAIL_SURROGATE_MAX = 0xdfffu; + const utfchar16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10) + const utfchar32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN + + // Maximum valid value for a Unicode code point + const utfchar32_t CODE_POINT_MAX = 0x0010ffffu; + + template + inline utfchar8_t mask8(octet_type oc) + { + return static_cast(0xff & oc); + } + template + inline utfchar16_t mask16(u16_type oc) + { + return static_cast(0xffff & oc); + } + + template + inline bool is_trail(octet_type oc) + { + return ((utf8::internal::mask8(oc) >> 6) == 0x2); + } + + inline bool is_lead_surrogate(utfchar32_t cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); + } + + inline bool is_trail_surrogate(utfchar32_t cp) + { + return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + inline bool is_surrogate(utfchar32_t cp) + { + return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); + } + + inline bool is_code_point_valid(utfchar32_t cp) + { + return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); + } + + inline bool is_in_bmp(utfchar32_t cp) + { + return cp < utfchar32_t(0x10000); + } + + template + int sequence_length(octet_iterator lead_it) + { + const utfchar8_t lead = utf8::internal::mask8(*lead_it); + if (lead < 0x80) + return 1; + else if ((lead >> 5) == 0x6) + return 2; + else if ((lead >> 4) == 0xe) + return 3; + else if ((lead >> 3) == 0x1e) + return 4; + else + return 0; + } + + inline bool is_overlong_sequence(utfchar32_t cp, int length) + { + if (cp < 0x80) { + if (length != 1) + return true; + } + else if (cp < 0x800) { + if (length != 2) + return true; + } + else if (cp < 0x10000) { + if (length != 3) + return true; + } + return false; + } + + enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; + + /// Helper for get_sequence_x + template + utf_error increase_safely(octet_iterator& it, const octet_iterator end) + { + if (++it == end) + return NOT_ENOUGH_ROOM; + + if (!utf8::internal::is_trail(*it)) + return INCOMPLETE_SEQUENCE; + + return UTF8_OK; + } + + #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} + + /// get_sequence_x functions decode utf-8 sequences of the length x + template + utf_error get_sequence_1(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + return UTF8_OK; + } + + template + utf_error get_sequence_2(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); + + return UTF8_OK; + } + + template + utf_error get_sequence_3(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + template + utf_error get_sequence_4(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + code_point = utf8::internal::mask8(*it); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; + + UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) + + code_point += (*it) & 0x3f; + + return UTF8_OK; + } + + #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR + + template + utf_error validate_next(octet_iterator& it, octet_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + + // Save the original value of it so we can go back in case of failure + // Of course, it does not make much sense with i.e. stream iterators + octet_iterator original_it = it; + + utfchar32_t cp = 0; + // Determine the sequence length based on the lead octet + const int length = utf8::internal::sequence_length(it); + + // Get trail octets and calculate the code point + utf_error err = UTF8_OK; + switch (length) { + case 0: + return INVALID_LEAD; + case 1: + err = utf8::internal::get_sequence_1(it, end, cp); + break; + case 2: + err = utf8::internal::get_sequence_2(it, end, cp); + break; + case 3: + err = utf8::internal::get_sequence_3(it, end, cp); + break; + case 4: + err = utf8::internal::get_sequence_4(it, end, cp); + break; + } + + if (err == UTF8_OK) { + // Decoding succeeded. Now, security checks... + if (utf8::internal::is_code_point_valid(cp)) { + if (!utf8::internal::is_overlong_sequence(cp, length)){ + // Passed! Return here. + code_point = cp; + ++it; + return UTF8_OK; + } + else + err = OVERLONG_SEQUENCE; + } + else + err = INVALID_CODE_POINT; + } + + // Failure branch - restore the original value of the iterator + it = original_it; + return err; + } + + template + inline utf_error validate_next(octet_iterator& it, octet_iterator end) { + utfchar32_t ignored; + return utf8::internal::validate_next(it, end, ignored); + } + + template + utf_error validate_next16(word_iterator& it, word_iterator end, utfchar32_t& code_point) + { + if (it == end) + return NOT_ENOUGH_ROOM; + // Save the original value of it so we can go back in case of failure + // Of course, it does not make much sense with i.e. stream iterators + word_iterator original_it = it; + + utf_error err = UTF8_OK; + + const utfchar16_t first_word = *it++; + if (!is_surrogate(first_word)) { + code_point = first_word; + return UTF8_OK; + } + else { + if (it == end) + err = NOT_ENOUGH_ROOM; + else if (is_lead_surrogate(first_word)) { + const utfchar16_t second_word = *it++; + if (is_trail_surrogate(second_word)) { + code_point = (first_word << 10) + second_word + SURROGATE_OFFSET; + return UTF8_OK; + } else + err = INCOMPLETE_SEQUENCE; + + } else { + err = INVALID_LEAD; + } + } + // error branch + it = original_it; + return err; + } + + // Internal implementation of both checked and unchecked append() function + // This function will be invoked by the overloads below, as they will know + // the octet_type. + template + octet_iterator append(utfchar32_t cp, octet_iterator result) { + if (cp < 0x80) // one octet + *(result++) = static_cast(cp); + else if (cp < 0x800) { // two octets + *(result++) = static_cast((cp >> 6) | 0xc0); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else if (cp < 0x10000) { // three octets + *(result++) = static_cast((cp >> 12) | 0xe0); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + else { // four octets + *(result++) = static_cast((cp >> 18) | 0xf0); + *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); + *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); + *(result++) = static_cast((cp & 0x3f) | 0x80); + } + return result; + } + + // One of the following overloads will be invoked from the API calls + + // A simple (but dangerous) case: the caller appends byte(s) to a char array + inline char* append(utfchar32_t cp, char* result) { + return append(cp, result); + } + + // Hopefully, most common case: the caller uses back_inserter + // i.e. append(cp, std::back_inserter(str)); + template + std::back_insert_iterator append + (utfchar32_t cp, std::back_insert_iterator result) { + return append, + typename container_type::value_type>(cp, result); + } + + // The caller uses some other kind of output operator - not covered above + // Note that in this case we are not able to determine octet_type + // so we assume it's utfchar8_t; that can cause a conversion warning if we are wrong. + template + octet_iterator append(utfchar32_t cp, octet_iterator result) { + return append(cp, result); + } + + // Internal implementation of both checked and unchecked append16() function + // This function will be invoked by the overloads below, as they will know + // the word_type. + template + word_iterator append16(utfchar32_t cp, word_iterator result) { + if (is_in_bmp(cp)) + *(result++) = static_cast(cp); + else { + // Code points from the supplementary planes are encoded via surrogate pairs + *(result++) = static_cast(LEAD_OFFSET + (cp >> 10)); + *(result++) = static_cast(TRAIL_SURROGATE_MIN + (cp & 0x3FF)); + } + return result; + } + + // Hopefully, most common case: the caller uses back_inserter + // i.e. append16(cp, std::back_inserter(str)); + template + std::back_insert_iterator append16 + (utfchar32_t cp, std::back_insert_iterator result) { + return append16, + typename container_type::value_type>(cp, result); + } + + // The caller uses some other kind of output operator - not covered above + // Note that in this case we are not able to determine word_type + // so we assume it's utfchar16_t; that can cause a conversion warning if we are wrong. + template + word_iterator append16(utfchar32_t cp, word_iterator result) { + return append16(cp, result); + } + +} // namespace internal + + /// The library API - functions intended to be called by the users + + // Byte order mark + const utfchar8_t bom[] = {0xef, 0xbb, 0xbf}; + + template + octet_iterator find_invalid(octet_iterator start, octet_iterator end) + { + octet_iterator result = start; + while (result != end) { + utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); + if (err_code != internal::UTF8_OK) + return result; + } + return result; + } + + inline const char* find_invalid(const char* str) + { + const char* end = str + std::strlen(str); + return find_invalid(str, end); + } + + inline std::size_t find_invalid(const std::string& s) + { + std::string::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string::npos : static_cast(invalid - s.begin()); + } + + template + inline bool is_valid(octet_iterator start, octet_iterator end) + { + return (utf8::find_invalid(start, end) == end); + } + + inline bool is_valid(const char* str) + { + return (*(utf8::find_invalid(str)) == '\0'); + } + + inline bool is_valid(const std::string& s) + { + return is_valid(s.begin(), s.end()); + } + + + + template + inline bool starts_with_bom (octet_iterator it, octet_iterator end) + { + return ( + ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && + ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && + ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) + ); + } + + inline bool starts_with_bom(const std::string& s) + { + return starts_with_bom(s.begin(), s.end()); + } +} // namespace utf8 + +#endif // header guard + + diff --git a/external/utfcpp/source/utf8/cpp11.h b/external/utfcpp/source/utf8/cpp11.h new file mode 100644 index 000000000..691633c84 --- /dev/null +++ b/external/utfcpp/source/utf8/cpp11.h @@ -0,0 +1,70 @@ +// Copyright 2018 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 +#define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1 + +#include "checked.h" + +namespace utf8 +{ + inline void append16(utfchar32_t cp, std::u16string& s) + { + append16(cp, std::back_inserter(s)); + } + + inline std::string utf16to8(const std::u16string& s) + { + std::string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(const std::string& s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::string utf32to8(const std::u32string& s) + { + std::string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(const std::string& s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } +} // namespace utf8 + +#endif // header guard + diff --git a/external/utfcpp/source/utf8/cpp17.h b/external/utfcpp/source/utf8/cpp17.h new file mode 100644 index 000000000..6e2fcc238 --- /dev/null +++ b/external/utfcpp/source/utf8/cpp17.h @@ -0,0 +1,96 @@ +// Copyright 2018 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 +#define UTF8_FOR_CPP_7e906c01_03a3_4daf_b420_ea7ea952b3c9 + +#include "cpp11.h" + +namespace utf8 +{ + inline std::string utf16to8(std::u16string_view s) + { + std::string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(std::string_view s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::string utf32to8(std::u32string_view s) + { + std::string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(std::string_view s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::size_t find_invalid(std::string_view s) + { + std::string_view::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string_view::npos : static_cast(invalid - s.begin()); + } + + inline bool is_valid(std::string_view s) + { + return is_valid(s.begin(), s.end()); + } + + inline std::string replace_invalid(std::string_view s, char32_t replacement) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::string replace_invalid(std::string_view s) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline bool starts_with_bom(std::string_view s) + { + return starts_with_bom(s.begin(), s.end()); + } + +} // namespace utf8 + +#endif // header guard + diff --git a/external/utfcpp/source/utf8/cpp20.h b/external/utfcpp/source/utf8/cpp20.h new file mode 100644 index 000000000..07b61d0fb --- /dev/null +++ b/external/utfcpp/source/utf8/cpp20.h @@ -0,0 +1,124 @@ +// Copyright 2022 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_207e906c01_03a3_4daf_b420_ea7ea952b3c9 +#define UTF8_FOR_CPP_207e906c01_03a3_4daf_b420_ea7ea952b3c9 + +#include "cpp17.h" + +namespace utf8 +{ + inline std::u8string utf16tou8(const std::u16string& s) + { + std::u8string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u8string utf16tou8(std::u16string_view s) + { + std::u8string result; + utf16to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(const std::u8string& s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u16string utf8to16(const std::u8string_view& s) + { + std::u16string result; + utf8to16(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u8string utf32tou8(const std::u32string& s) + { + std::u8string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u8string utf32tou8(const std::u32string_view& s) + { + std::u8string result; + utf32to8(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(const std::u8string& s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::u32string utf8to32(const std::u8string_view& s) + { + std::u32string result; + utf8to32(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline std::size_t find_invalid(const std::u8string& s) + { + std::u8string::const_iterator invalid = find_invalid(s.begin(), s.end()); + return (invalid == s.end()) ? std::string_view::npos : static_cast(invalid - s.begin()); + } + + inline bool is_valid(const std::u8string& s) + { + return is_valid(s.begin(), s.end()); + } + + inline std::u8string replace_invalid(const std::u8string& s, char32_t replacement) + { + std::u8string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::u8string replace_invalid(const std::u8string& s) + { + std::u8string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + inline bool starts_with_bom(const std::u8string& s) + { + return starts_with_bom(s.begin(), s.end()); + } + +} // namespace utf8 + +#endif // header guard + diff --git a/external/utfcpp/source/utf8/unchecked.h b/external/utfcpp/source/utf8/unchecked.h new file mode 100644 index 000000000..65d4948f2 --- /dev/null +++ b/external/utfcpp/source/utf8/unchecked.h @@ -0,0 +1,287 @@ +// Copyright 2006 Nemanja Trifunovic + +/* +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +*/ + + +#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "core.h" + +namespace utf8 +{ + namespace unchecked + { + template + octet_iterator append(utfchar32_t cp, octet_iterator result) + { + return internal::append(cp, result); + } + + template + word_iterator append16(utfchar32_t cp, word_iterator result) + { + return internal::append16(cp, result); + } + + template + output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, utfchar32_t replacement) + { + while (start != end) { + octet_iterator sequence_start = start; + internal::utf_error err_code = utf8::internal::validate_next(start, end); + switch (err_code) { + case internal::UTF8_OK : + for (octet_iterator it = sequence_start; it != start; ++it) + *out++ = *it; + break; + case internal::NOT_ENOUGH_ROOM: + out = utf8::unchecked::append(replacement, out); + start = end; + break; + case internal::INVALID_LEAD: + out = utf8::unchecked::append(replacement, out); + ++start; + break; + case internal::INCOMPLETE_SEQUENCE: + case internal::OVERLONG_SEQUENCE: + case internal::INVALID_CODE_POINT: + out = utf8::unchecked::append(replacement, out); + ++start; + // just one replacement mark for the sequence + while (start != end && utf8::internal::is_trail(*start)) + ++start; + break; + } + } + return out; + } + + template + inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) + { + static const utfchar32_t replacement_marker = utf8::internal::mask16(0xfffd); + return utf8::unchecked::replace_invalid(start, end, out, replacement_marker); + } + + inline std::string replace_invalid(const std::string& s, utfchar32_t replacement) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement); + return result; + } + + inline std::string replace_invalid(const std::string& s) + { + std::string result; + replace_invalid(s.begin(), s.end(), std::back_inserter(result)); + return result; + } + + template + utfchar32_t next(octet_iterator& it) + { + utfchar32_t cp = utf8::internal::mask8(*it); + switch (utf8::internal::sequence_length(it)) { + case 1: + break; + case 2: + it++; + cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); + break; + case 3: + ++it; + cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); + ++it; + cp += (*it) & 0x3f; + break; + case 4: + ++it; + cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); + ++it; + cp += (utf8::internal::mask8(*it) << 6) & 0xfff; + ++it; + cp += (*it) & 0x3f; + break; + } + ++it; + return cp; + } + + template + utfchar32_t peek_next(octet_iterator it) + { + return utf8::unchecked::next(it); + } + + template + utfchar32_t next16(word_iterator& it) + { + utfchar32_t cp = utf8::internal::mask16(*it++); + if (utf8::internal::is_lead_surrogate(cp)) + return (cp << 10) + *it++ + utf8::internal::SURROGATE_OFFSET; + return cp; + } + + template + utfchar32_t prior(octet_iterator& it) + { + while (utf8::internal::is_trail(*(--it))) ; + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + + template + void advance(octet_iterator& it, distance_type n) + { + const distance_type zero(0); + if (n < zero) { + // backward + for (distance_type i = n; i < zero; ++i) + utf8::unchecked::prior(it); + } else { + // forward + for (distance_type i = zero; i < n; ++i) + utf8::unchecked::next(it); + } + } + + template + typename std::iterator_traits::difference_type + distance(octet_iterator first, octet_iterator last) + { + typename std::iterator_traits::difference_type dist; + for (dist = 0; first < last; ++dist) + utf8::unchecked::next(first); + return dist; + } + + template + octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, octet_iterator result) + { + while (start != end) { + utfchar32_t cp = utf8::internal::mask16(*start++); + // Take care of surrogate pairs first + if (utf8::internal::is_lead_surrogate(cp)) { + if (start == end) + return result; + utfchar32_t trail_surrogate = utf8::internal::mask16(*start++); + cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; + } + result = utf8::unchecked::append(cp, result); + } + return result; + } + + template + u16bit_iterator utf8to16(octet_iterator start, octet_iterator end, u16bit_iterator result) + { + while (start < end) { + utfchar32_t cp = utf8::unchecked::next(start); + if (cp > 0xffff) { //make a surrogate pair + *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); + *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); + } + else + *result++ = static_cast(cp); + } + return result; + } + + template + octet_iterator utf32to8(u32bit_iterator start, u32bit_iterator end, octet_iterator result) + { + while (start != end) + result = utf8::unchecked::append(*(start++), result); + + return result; + } + + template + u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, u32bit_iterator result) + { + while (start < end) + (*result++) = utf8::unchecked::next(start); + + return result; + } + + // The iterator class + template + class iterator { + octet_iterator it; + public: + typedef utfchar32_t value_type; + typedef utfchar32_t* pointer; + typedef utfchar32_t& reference; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + iterator () {} + explicit iterator (const octet_iterator& octet_it): it(octet_it) {} + // the default "big three" are OK + octet_iterator base () const { return it; } + utfchar32_t operator * () const + { + octet_iterator temp = it; + return utf8::unchecked::next(temp); + } + bool operator == (const iterator& rhs) const + { + return (it == rhs.it); + } + bool operator != (const iterator& rhs) const + { + return !(operator == (rhs)); + } + iterator& operator ++ () + { + ::std::advance(it, utf8::internal::sequence_length(it)); + return *this; + } + iterator operator ++ (int) + { + iterator temp = *this; + ::std::advance(it, utf8::internal::sequence_length(it)); + return temp; + } + iterator& operator -- () + { + utf8::unchecked::prior(it); + return *this; + } + iterator operator -- (int) + { + iterator temp = *this; + utf8::unchecked::prior(it); + return temp; + } + }; // class iterator + + } // namespace utf8::unchecked +} // namespace utf8 + + +#endif // header guard + diff --git a/external/utfcpp/tests/CMakeLists.txt b/external/utfcpp/tests/CMakeLists.txt new file mode 100644 index 000000000..8a00a6a08 --- /dev/null +++ b/external/utfcpp/tests/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required (VERSION 3.5) +project(utfcpptests LANGUAGES CXX) +enable_testing() + +add_library(${PROJECT_NAME} INTERFACE) + +include_directories("${PROJECT_SOURCE_DIR}/../source") + +add_executable(negative negative.cpp) +add_executable(cpp11 test_cpp11.cpp) +add_executable(cpp17 test_cpp17.cpp) +add_executable(cpp20 test_cpp20.cpp) +add_executable(apitests apitests.cpp) + +add_executable(noexceptionstests noexceptionstests.cpp) + + + +target_compile_options(${PROJECT_NAME} INTERFACE + $<$:/W4> + $<$>:-Wall -Wextra -Wpedantic -Wconversion>) + +target_compile_options(noexceptionstests PUBLIC -fno-exceptions) + +set_target_properties(negative apitests noexceptionstests + PROPERTIES + CXX_STANDARD 98 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp11 + PROPERTIES + CXX_STANDARD 11 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp17 + PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + +set_target_properties(cpp20 + PROPERTIES + CXX_STANDARD 20 + CXX_STANDARD_REQUIRED YES + CXX_EXTENSIONS NO) + + +add_test(negative_test negative ${PROJECT_SOURCE_DIR}/test_data/utf8_invalid.txt) +add_test(cpp11_test cpp11) +add_test(cpp17_test cpp17) +add_test(cpp20_test cpp20) +add_test(api_test apitests) +add_test(noexceptions_test noexceptionstests) + diff --git a/external/utfcpp/tests/apitests.cpp b/external/utfcpp/tests/apitests.cpp new file mode 100644 index 000000000..083266d7d --- /dev/null +++ b/external/utfcpp/tests/apitests.cpp @@ -0,0 +1,6 @@ +#include "../extern/ftest/ftest.h" + +#include "test_checked_api.h" +#include "test_checked_iterator.h" +#include "test_unchecked_api.h" +#include "test_unchecked_iterator.h" diff --git a/external/utfcpp/tests/docker/Dockerfile b/external/utfcpp/tests/docker/Dockerfile new file mode 100644 index 000000000..dcdd47d1d --- /dev/null +++ b/external/utfcpp/tests/docker/Dockerfile @@ -0,0 +1,5 @@ +FROM gcc:12.2 + +RUN apt-get update \ + && apt-get install -y make g++ cmake git \ + && rm -rf /var/lib/apt/lists/* diff --git a/external/utfcpp/tests/negative.cpp b/external/utfcpp/tests/negative.cpp new file mode 100644 index 000000000..f1bcc993e --- /dev/null +++ b/external/utfcpp/tests/negative.cpp @@ -0,0 +1,59 @@ +#include "utf8.h" +using namespace utf8; + +#include +#include +#include +#include +using namespace std; + +const unsigned INVALID_LINES[] = { 75, 76, 83, 84, 85, 93, 102, 103, 105, 106, 107, 108, 109, 110, 114, 115, 116, 117, 124, 125, 130, 135, 140, 145, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 169, 175, 176, 177, 207, 208, 209, 210, 211, 220, 221, 222, 223, 224, 232, 233, 234, 235, 236, 247, 248, 249, 250, 251, 252, 253, 257, 258, 259, 260, 261, 262, 263, 264}; +const unsigned* INVALID_LINES_END = INVALID_LINES + sizeof(INVALID_LINES)/sizeof(unsigned); + +int main(int argc, char** argv) +{ + string test_file_path; + if (argc == 2) + test_file_path = argv[1]; + else { + cout << "Wrong number of arguments" << endl; + return 1; + } + // Open the test file + ifstream fs8(test_file_path.c_str()); + if (!fs8.is_open()) { + cout << "Could not open " << test_file_path << endl; + return 1; + } + + // Read it line by line + unsigned int line_count = 0; + char byte; + while (!fs8.eof()) { + string line; + while ((byte = static_cast(fs8.get())) != '\n' && !fs8.eof()) + line.push_back(byte); + + line_count++; + bool expected_valid = (find(INVALID_LINES, INVALID_LINES_END, line_count) == INVALID_LINES_END); + // Print out lines that contain unexpected invalid UTF-8 + if (!is_valid(line.begin(), line.end())) { + if (expected_valid) { + cout << "Unexpected invalid utf-8 at line " << line_count << '\n'; + return 1; + } + + // try fixing it: + string fixed_line; + replace_invalid(line.begin(), line.end(), back_inserter(fixed_line)); + if (!is_valid(fixed_line.begin(), fixed_line.end())) { + cout << "replace_invalid() resulted in an invalid utf-8 at line " << line_count << '\n'; + return 1; + } + } + else if (!expected_valid) { + cout << "Invalid utf-8 NOT detected at line " << line_count << '\n'; + return 1; + } + } +} diff --git a/external/utfcpp/tests/noexceptionstests.cpp b/external/utfcpp/tests/noexceptionstests.cpp new file mode 100644 index 000000000..108ee750c --- /dev/null +++ b/external/utfcpp/tests/noexceptionstests.cpp @@ -0,0 +1,4 @@ +#include "../extern/ftest/ftest.h" + +#include "test_unchecked_api.h" +#include "test_unchecked_iterator.h" diff --git a/external/utfcpp/tests/test_checked_api.h b/external/utfcpp/tests/test_checked_api.h new file mode 100644 index 000000000..54e9cf8f0 --- /dev/null +++ b/external/utfcpp/tests/test_checked_api.h @@ -0,0 +1,233 @@ +#ifndef UTF8_FOR_CPP_TEST_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8.h" + +#include +#include +using namespace utf8; +using namespace std; + + +TEST(CheckedAPITests, test_append) +{ + unsigned char u[5] = {0,0,0,0,0}; + append(0x0448, u); + EXPECT_EQ (u[0], 0xd1); + EXPECT_EQ (u[1], 0x88); + EXPECT_EQ (u[2], 0); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x65e5, u); + EXPECT_EQ (u[0], 0xe6); + EXPECT_EQ (u[1], 0x97); + EXPECT_EQ (u[2], 0xa5); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x3044, u); + EXPECT_EQ (u[0], 0xe3); + EXPECT_EQ (u[1], 0x81); + EXPECT_EQ (u[2], 0x84); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + append(0x10346, u); + EXPECT_EQ (u[0], 0xf0); + EXPECT_EQ (u[1], 0x90); + EXPECT_EQ (u[2], 0x8d); + EXPECT_EQ (u[3], 0x86); + EXPECT_EQ (u[4], 0); + + // Ensure no warnings with plain char + char c[2] = {0,0}; + append('a', c); + EXPECT_EQ (c[0], 'a'); + EXPECT_EQ (c[1], 0); +} + +TEST(CheckedAPITests, test_append16) +{ + utfchar16_t u[5] = {0,0}; + append16(0x0448, u); + EXPECT_EQ (u[0], 0x0448); + EXPECT_EQ (u[1], 0x0000); + + append16(0x65e5, u); + EXPECT_EQ (u[0], 0x65e5); + EXPECT_EQ (u[1], 0x0000); + + append16(0x10346, u); + EXPECT_EQ (u[0], 0xd800); + EXPECT_EQ (u[1], 0xdf46); +} + +TEST(CheckedAPITests, test_next) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars; + unsigned int cp = next(w, twochars + 6); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars + 3); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars; + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars + 4); + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 7); + + cp = next(w, threechars + 9); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 9); +} + +TEST(CheckedAPITests, test_next16) +{ + const utfchar16_t u[3] = {0x65e5, 0xd800, 0xdf46}; + const utfchar16_t* w = u; + utf8::utfchar32_t cp = next16(w, w + 3); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, u + 1); + + cp = next16(w, w + 2); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, u + 3); +} + +TEST(CheckedAPITests, test_peek_next) +{ + const char* const cw = "\xe6\x97\xa5\xd1\x88"; + unsigned int cp = peek_next(cw, cw + 6); + EXPECT_EQ (cp, 0x65e5); +} + +TEST(CheckedAPITests, test_prior) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars + 3; + unsigned int cp = prior (w, twochars); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars + 9; + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 7); + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 4); + cp = prior(w, threechars); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars); +} + +TEST(CheckedAPITests, test_advance) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + const char* w = threechars; + advance(w, 2, threechars + 9); + EXPECT_EQ(w, threechars + 7); + advance(w, -2, threechars); + EXPECT_EQ(w, threechars); + advance(w, 3, threechars + 9); + EXPECT_EQ(w, threechars + 9); + advance(w, -2, threechars); + EXPECT_EQ(w, threechars + 4); + advance(w, -1, threechars); + EXPECT_EQ(w, threechars); +} + +TEST(CheckedAPITests, test_distance) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + size_t dist = static_cast(utf8::distance(twochars, twochars + 5)); + EXPECT_EQ (dist, 2); +} + +TEST(CheckedAPITests, test_utf32to8) +{ + unsigned int utf32string[] = {0x448, 0x65E5, 0x10346, 0}; + string utf8result; + utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CheckedAPITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + vector utf32result; + utf8to32(twochars, twochars + 5, back_inserter(utf32result)); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CheckedAPITests, test_utf16to8) +{ + unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string utf8result; + utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 10); +} + +TEST(CheckedAPITests, test_utf8to16) +{ + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + vector utf16result; + utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CheckedAPITests, test_replace_invalid) +{ + char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + vector replace_invalid_result; + replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?'); + bool bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); + EXPECT_TRUE (bvalid); + const char fixed_invalid_sequence[] = "a????z"; + EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size()); + EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence)); +} + +TEST(CheckedAPITests, test_find_invalid) +{ + char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; + const char* invalid = find_invalid(utf_invalid, utf_invalid + 6); + EXPECT_EQ (invalid, utf_invalid + 5); + invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, utf_invalid + 5); +} + +TEST(CheckedAPITests, test_is_valid) +{ + char utf_invalid[] = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid, utf_invalid + 6); + EXPECT_FALSE (bvalid); + bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates, utf8_with_surrogates + 9); + EXPECT_TRUE (bvalid); + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CheckedAPITests, test_starts_with_bom) +{ + unsigned char byte_order_mark[] = {0xef, 0xbb, 0xbf}; + bool bbom = starts_with_bom(byte_order_mark, byte_order_mark + sizeof(byte_order_mark)); + EXPECT_TRUE (bbom); + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars, threechars + sizeof(threechars)); + EXPECT_FALSE (no_bbom); +} + +#endif diff --git a/external/utfcpp/tests/test_checked_iterator.h b/external/utfcpp/tests/test_checked_iterator.h new file mode 100644 index 000000000..2829a734e --- /dev/null +++ b/external/utfcpp/tests/test_checked_iterator.h @@ -0,0 +1,35 @@ +#ifndef UTF8_FOR_CPP_TEST_CHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_CHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8.h" + +using namespace utf8; + + +TEST(CheckedIteratrTests, test_increment) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::iterator it(threechars, threechars, threechars + 9); + utf8::iterator it2 = it; + EXPECT_EQ (it2, it); + EXPECT_EQ (*it, 0x10346); + EXPECT_EQ (*(++it), 0x65e5); + EXPECT_EQ ((*it++), 0x65e5); + EXPECT_EQ (*it, 0x0448); + EXPECT_NE (it, it2); + utf8::iterator endit (threechars + 9, threechars, threechars + 9); + EXPECT_EQ (++it, endit); +} + +TEST(CheckedIteratrTests, test_decrement) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::iterator it(threechars+9, threechars, threechars + 9); + EXPECT_EQ (*(--it), 0x0448); + EXPECT_EQ ((*it--), 0x0448); + EXPECT_EQ (*it, 0x65e5); + EXPECT_EQ (--it, utf8::iterator(threechars, threechars, threechars + 9)); + EXPECT_EQ (*it, 0x10346); +} + +#endif diff --git a/external/utfcpp/tests/test_cpp11.cpp b/external/utfcpp/tests/test_cpp11.cpp new file mode 100644 index 000000000..e52196682 --- /dev/null +++ b/external/utfcpp/tests/test_cpp11.cpp @@ -0,0 +1,122 @@ +#include "../extern/ftest/ftest.h" +#include "utf8.h" +#include +using namespace utf8; +using namespace std; + +#if __cplusplus >= 201103L // C++ 11 or later + +TEST(CPP11APITests, test_append) +{ + string u; + append(0x0448, u); + EXPECT_EQ (u[0], char(0xd1)); + EXPECT_EQ (u[1], char(0x88)); + EXPECT_EQ (u.length(), 2); + + u.clear(); + append(0x65e5, u); + EXPECT_EQ (u[0], char(0xe6)); + EXPECT_EQ (u[1], char(0x97)); + EXPECT_EQ (u[2], char(0xa5)); + EXPECT_EQ (u.length(), 3); + + u.clear(); + append(0x3044, u); + EXPECT_EQ (u[0], char(0xe3)); + EXPECT_EQ (u[1], char(0x81)); + EXPECT_EQ (u[2], char(0x84)); + EXPECT_EQ (u.length(), 3); + + u.clear(); + append(0x10346, u); + EXPECT_EQ (u[0], char(0xf0)); + EXPECT_EQ (u[1], char(0x90)); + EXPECT_EQ (u[2], char(0x8d)); + EXPECT_EQ (u[3], char(0x86)); + EXPECT_EQ (u.length(), 4); +} + +TEST(CPP11APITests, test_append16) +{ + u16string u; + append16(0x0448, u); + EXPECT_EQ (u[0], char16_t(0x0448)); + EXPECT_EQ (u.length(), 1); +} + +TEST(CPP11APITests, test_utf16to8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string u = utf16to8(utf16string); + EXPECT_EQ (u.size(), 10); + + u16string h16 = u"h!"; + string h8; + utf8::unchecked::utf16to8(h16.begin(), h16.end(), std::back_inserter(h8)); + EXPECT_EQ (h8, "h!"); +} + +TEST(CPP11APITests, test_utf8to16) +{ + string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); + // Just to make sure it compiles with string literals + utf8to16(u8"simple"); + utf8to16("simple"); +} + +TEST(CPP11APITests, test_utf32to8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + string utf8result = utf32to8(utf32string); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP11APITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP11APITests, test_find_invalid) +{ + string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP11APITests, test_is_valid) +{ + string utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + string utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP11APITests, test_replace_invalid) +{ + string invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + string replace_invalid_result = replace_invalid(invalid_sequence, '?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const string fixed_invalid_sequence = "a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP11APITests, test_starts_with_bom) +{ + string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; + bool bbom = starts_with_bom(byte_order_mark); + EXPECT_TRUE (bbom); + string threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} +#endif // C++ 11 or later diff --git a/external/utfcpp/tests/test_cpp17.cpp b/external/utfcpp/tests/test_cpp17.cpp new file mode 100644 index 000000000..a38e6f716 --- /dev/null +++ b/external/utfcpp/tests/test_cpp17.cpp @@ -0,0 +1,88 @@ +#include "../extern/ftest/ftest.h" +#include "utf8.h" +#include +using namespace utf8; +using namespace std; + +#if __cplusplus >= 201703L // C++ 17 or later + + +TEST(CPP17APITests, test_utf16to8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview(utf16string); + string u = utf16to8(utf16stringview); + EXPECT_EQ (u.size(), 10); +} + +TEST(CPP17APITests, test_utf8to16) +{ + string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CPP17APITests, test_utf32to8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + u32string_view utf32stringview(utf32string); + string utf8result = utf32to8(utf32stringview); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP17APITests, test_utf8to32) +{ + string_view twochars = "\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP17APITests, test_find_invalid) +{ + string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP17APITests, test_is_valid) +{ + string_view utf_invalid = "\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + string_view utf8_with_surrogates = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP17APITests, test_replace_invalid) +{ + string_view invalid_sequence = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + string replace_invalid_result = replace_invalid(invalid_sequence, '?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const string fixed_invalid_sequence = "a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP17APITests, test_starts_with_bom) +{ + string byte_order_mark = {char(0xef), char(0xbb), char(0xbf)}; + string_view byte_order_mark_view(byte_order_mark); + bool bbom = starts_with_bom(byte_order_mark_view); + EXPECT_TRUE (bbom); + string_view threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} + +TEST(CPP17APITests, string_class_and_literals) +{ + const char* twochars = u8"ab"; + EXPECT_TRUE (is_valid(twochars)); + const string two_chars_string(twochars); + EXPECT_TRUE (is_valid(two_chars_string)); +} + +#endif // C++ 11 or later diff --git a/external/utfcpp/tests/test_cpp20.cpp b/external/utfcpp/tests/test_cpp20.cpp new file mode 100644 index 000000000..50dbe30ac --- /dev/null +++ b/external/utfcpp/tests/test_cpp20.cpp @@ -0,0 +1,77 @@ +#include "../extern/ftest/ftest.h" +#define UTF_CPP_CPLUSPLUS 202002L +#include "utf8.h" +#include +using namespace utf8; +using namespace std; + +TEST(CPP20APITests, test_utf16tou8) +{ + u16string utf16string = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + u16string_view utf16stringview{utf16string}; + u8string u = utf16tou8(utf16string); + EXPECT_EQ (u.size(), 10); + u = utf16tou8(utf16stringview); + EXPECT_EQ (u.size(), 10); +} + +TEST(CPP20APITests, tes20t_utf8to16) +{ + u8string utf8_with_surrogates{u8"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"}; + u16string utf16result = utf8to16(utf8_with_surrogates); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(CPP20APITests, test_utf32tou8) +{ + u32string utf32string = {0x448, 0x65E5, 0x10346}; + u32string_view utf32stringview{utf32string}; + u8string utf8result = utf32tou8(utf32stringview); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(CPP20APITests, test_utf8to32) +{ + u8string twochars = u8"\xe6\x97\xa5\xd1\x88"; + u32string utf32result = utf8to32(twochars); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(CPP20APITests, test_find_invalid) +{ + u8string utf_invalid = u8"\xe6\x97\xa5\xd1\x88\xfa"; + auto invalid = find_invalid(utf_invalid); + EXPECT_EQ (invalid, 5); +} + +TEST(CPP20APITests, test_is_valid) +{ + u8string utf_invalid = u8"\xe6\x97\xa5\xd1\x88\xfa"; + bool bvalid = is_valid(utf_invalid); + EXPECT_FALSE (bvalid); + u8string utf8_with_surrogates = u8"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + bvalid = is_valid(utf8_with_surrogates); + EXPECT_TRUE (bvalid); +} + +TEST(CPP20APITests, test_replace_invalid) +{ + u8string invalid_sequence = u8"a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + u8string replace_invalid_result = replace_invalid(invalid_sequence, u8'?'); + bool bvalid = is_valid(replace_invalid_result); + EXPECT_TRUE (bvalid); + const u8string fixed_invalid_sequence = u8"a????z"; + EXPECT_EQ(fixed_invalid_sequence, replace_invalid_result); +} + +TEST(CPP20APITests, test_starts_with_bom) +{ + u8string byte_order_mark = u8"\xef\xbb\xbf"; + bool bbom = starts_with_bom(byte_order_mark); + EXPECT_TRUE (bbom); + u8string threechars = u8"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + bool no_bbom = starts_with_bom(threechars); + EXPECT_FALSE (no_bbom); +} diff --git a/external/utfcpp/tests/test_data/utf8_invalid.txt b/external/utfcpp/tests/test_data/utf8_invalid.txt new file mode 100644 index 000000000..ae8315932 Binary files /dev/null and b/external/utfcpp/tests/test_data/utf8_invalid.txt differ diff --git a/external/utfcpp/tests/test_unchecked_api.h b/external/utfcpp/tests/test_unchecked_api.h new file mode 100644 index 000000000..aa0cf697b --- /dev/null +++ b/external/utfcpp/tests/test_unchecked_api.h @@ -0,0 +1,198 @@ +#ifndef UTF8_FOR_CPP_TEST_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/unchecked.h" + +#include +#include + +using namespace std; + +TEST(UnCheckedAPITests, test_append) +{ + unsigned char u[5] = {0,0,0,0,0}; + utf8::unchecked::append(0x0448, u); + EXPECT_EQ (u[0], 0xd1); + EXPECT_EQ (u[1], 0x88); + EXPECT_EQ (u[2], 0); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x65e5, u); + EXPECT_EQ (u[0], 0xe6); + EXPECT_EQ (u[1], 0x97); + EXPECT_EQ (u[2], 0xa5); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x3044, u); + EXPECT_EQ (u[0], 0xe3); + EXPECT_EQ (u[1], 0x81); + EXPECT_EQ (u[2], 0x84); + EXPECT_EQ (u[3], 0); + EXPECT_EQ (u[4], 0); + + utf8::unchecked::append(0x10346, u); + EXPECT_EQ (u[0], 0xf0); + EXPECT_EQ (u[1], 0x90); + EXPECT_EQ (u[2], 0x8d); + EXPECT_EQ (u[3], 0x86); + EXPECT_EQ (u[4], 0); +} + +TEST(UnCheckedAPITests, test_append16) +{ + unsigned short u[5] = {0,0}; + utf8::unchecked::append16(0x0448, u); + EXPECT_EQ (u[0], 0x0448); + EXPECT_EQ (u[1], 0x0000); + + utf8::unchecked::append16(0x65e5, u); + EXPECT_EQ (u[0], 0x65e5); + EXPECT_EQ (u[1], 0x0000); + + utf8::unchecked::append16(0x10346, u); + EXPECT_EQ (u[0], 0xd800); + EXPECT_EQ (u[1], 0xdf46); +} + +TEST(UnCheckedAPITests, test_next) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars; + unsigned int cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars + 3); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars; + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars + 4); + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 7); + + cp = utf8::unchecked::next(w); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 9); +} + +TEST(UnCheckedAPITests, test_next16) +{ + const utf8::utfchar16_t u[3] = {0x65e5, 0xd800, 0xdf46}; + const utf8::utfchar16_t* w = u; + utf8::utfchar32_t cp = utf8::unchecked::next16(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, u + 1); + + cp = utf8::unchecked::next16(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, u + 3); +} + +TEST(UnCheckedAPITests, test_peek_next) +{ + const char* const cw = "\xe6\x97\xa5\xd1\x88"; + unsigned int cp = utf8::unchecked::peek_next(cw); + EXPECT_EQ (cp, 0x65e5); +} + +TEST(UnCheckedAPITests, test_prior) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + const char* w = twochars + 3; + unsigned int cp = utf8::unchecked::prior (w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, twochars); + + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + w = threechars + 9; + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x0448); + EXPECT_EQ (w, threechars + 7); + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x65e5); + EXPECT_EQ (w, threechars + 4); + cp = utf8::unchecked::prior(w); + EXPECT_EQ (cp, 0x10346); + EXPECT_EQ (w, threechars); +} + +TEST(UnCheckedAPITests, test_advance) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + const char* w = threechars; + utf8::unchecked::advance(w, 2); + EXPECT_EQ(w, threechars + 7); + utf8::unchecked::advance(w, -2); + EXPECT_EQ(w, threechars); + utf8::unchecked::advance(w, 3); + EXPECT_EQ(w, threechars + 9); + utf8::unchecked::advance(w, -2); + EXPECT_EQ(w, threechars + 4); + utf8::unchecked::advance(w, -1); + EXPECT_EQ(w, threechars); +} + +TEST(UnCheckedAPITests, test_distance) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + size_t dist = static_cast(utf8::unchecked::distance(twochars, twochars + 5)); + EXPECT_EQ (dist, 2); +} + +TEST(UnCheckedAPITests, test_utf32to8) +{ + unsigned int utf32string[] = {0x448, 0x65E5, 0x10346, 0}; + string utf8result; + utf8::unchecked::utf32to8(utf32string, utf32string + 3, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 9); +} + +TEST(UnCheckedAPITests, test_utf8to32) +{ + const char* twochars = "\xe6\x97\xa5\xd1\x88"; + vector utf32result; + utf8::unchecked::utf8to32(twochars, twochars + 5, back_inserter(utf32result)); + EXPECT_EQ (utf32result.size(), 2); +} + +TEST(UnCheckedAPITests, test_utf16to8) +{ + unsigned short utf16string[] = {0x41, 0x0448, 0x65e5, 0xd834, 0xdd1e}; + string utf8result; + utf8::unchecked::utf16to8(utf16string, utf16string + 5, back_inserter(utf8result)); + EXPECT_EQ (utf8result.size(), 10); + + utf8result.clear(); + unsigned short highsurrogateonly[] = {0xd800}; + utf8::unchecked::utf16to8(highsurrogateonly, highsurrogateonly + 1, back_inserter(utf8result)); + EXPECT_TRUE(true); // we didn't crash +} + +TEST(UnCheckedAPITests, test_utf8to16) +{ + char utf8_with_surrogates[] = "\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"; + vector utf16result; + utf8::unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + 9, back_inserter(utf16result)); + EXPECT_EQ (utf16result.size(), 4); + EXPECT_EQ (utf16result[2], 0xd834); + EXPECT_EQ (utf16result[3], 0xdd1e); +} + +TEST(UnCheckedAPITests, test_replace_invalid) +{ + char invalid_sequence[] = "a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"; + vector replace_invalid_result; + utf8::unchecked::replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), std::back_inserter(replace_invalid_result), '?'); + bool bvalid = utf8::is_valid(replace_invalid_result.begin(), replace_invalid_result.end()); + EXPECT_TRUE (bvalid); + const char fixed_invalid_sequence[] = "a????z"; + EXPECT_EQ (sizeof(fixed_invalid_sequence), replace_invalid_result.size()); + EXPECT_TRUE (std::equal(replace_invalid_result.begin(), replace_invalid_result.begin() + sizeof(fixed_invalid_sequence), fixed_invalid_sequence)); +} + +#endif diff --git a/external/utfcpp/tests/test_unchecked_iterator.h b/external/utfcpp/tests/test_unchecked_iterator.h new file mode 100644 index 000000000..4294232d6 --- /dev/null +++ b/external/utfcpp/tests/test_unchecked_iterator.h @@ -0,0 +1,36 @@ +#ifndef UTF8_FOR_CPP_TEST_UNCHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 +#define UTF8_FOR_CPP_TEST_UNCHECKED_ITERATOR_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 + +#include "utf8/unchecked.h" + +using namespace utf8::unchecked; + + +TEST(UnCheckedIteratrTests, test_increment) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::unchecked::iterator it(threechars); + utf8::unchecked::iterator it2 = it; + EXPECT_EQ (it2, it); + EXPECT_EQ (*it, 0x10346); + EXPECT_EQ (*(++it), 0x65e5); + EXPECT_EQ ((*it++), 0x65e5); + EXPECT_EQ (*it, 0x0448); + EXPECT_NE (it, it2); + utf8::unchecked::iterator endit (threechars + 9); + EXPECT_EQ (++it, endit); +} + +TEST(UnCheckedIteratrTests, test_decrement) +{ + const char* threechars = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"; + utf8::unchecked::iterator it(threechars+9); + EXPECT_EQ (*(--it), 0x0448); + EXPECT_EQ ((*it--), 0x0448); + EXPECT_EQ (*it, 0x65e5); + EXPECT_EQ (--it, utf8::unchecked::iterator(threechars)); + EXPECT_EQ (*it, 0x10346); + +} + +#endif diff --git a/external/utfcpp/utf8cppConfig.cmake.in b/external/utfcpp/utf8cppConfig.cmake.in new file mode 100644 index 000000000..4bdb9c419 --- /dev/null +++ b/external/utfcpp/utf8cppConfig.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") + +if(NOT TARGET utf8::cpp) + add_library(utf8::cpp ALIAS utf8cpp::utf8cpp) +endif() diff --git a/images/es-de_application_updater.png b/images/es-de_application_updater.png index 7dec9b832..8ec997227 100644 Binary files a/images/es-de_application_updater.png and b/images/es-de_application_updater.png differ diff --git a/latest_release.json b/latest_release.json index 25e613549..5bf0b657e 100644 --- a/latest_release.json +++ b/latest_release.json @@ -24,15 +24,15 @@ { "name": "macOSApple", "filename": "EmulationStation-DE-2.2.1-arm64.dmg", - "url": "https://gitlab.com/es-de/emulationstation-de/-/package_files/101581889/download", - "md5": "999fa80d231ac00041e321685872b545", + "url": "https://gitlab.com/es-de/emulationstation-de/-/package_files/101732696/download", + "md5": "1aec895180c0e19a3d33ce6b6f267c0b", "message": "" }, { "name": "macOSIntel", "filename": "EmulationStation-DE-2.2.1-x64.dmg", - "url": "https://gitlab.com/es-de/emulationstation-de/-/package_files/101581898/download", - "md5": "70eb5456655d8902da79ea08b3efb9da", + "url": "https://gitlab.com/es-de/emulationstation-de/-/package_files/101732724/download", + "md5": "9c7f26773402afb3f8fcae79ac16a5fd", "message": "" }, { diff --git a/licenses/UTF8-CPP b/licenses/UTF8-CPP new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/licenses/UTF8-CPP @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/licenses/linear-es-de b/licenses/linear-es-de new file mode 100644 index 000000000..5ad1cf226 --- /dev/null +++ b/licenses/linear-es-de @@ -0,0 +1,20 @@ +Copyright (c) 2024 Leon Styhre +Copyright (c) 2023 Weestuarty + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/resources/certificates/curl-ca-bundle.crt b/resources/certificates/curl-ca-bundle.crt index 9551dfd83..d8fda7d1a 100644 --- a/resources/certificates/curl-ca-bundle.crt +++ b/resources/certificates/curl-ca-bundle.crt @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Aug 22 03:12:04 2023 GMT +## Certificate data from Mozilla as of: Tue Dec 12 04:12:04 2023 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 0ff137babc6a5561a9cfbe9f29558972e5b528202681b7d3803d03a3e82922bd +## SHA256: 1970dd65858925d68498d2356aea6d03f764422523c5887deca8ce3ba9e1f845 ## @@ -200,27 +200,6 @@ vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -Security Communication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP -U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw -8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM -DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX -5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd -DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 -JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g -0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a -mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ -s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ -6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi -FL39vmwLAw== ------END CERTIFICATE----- - XRamp Global CA Root ==================== -----BEGIN CERTIFICATE----- @@ -669,39 +648,6 @@ YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r kpeDMdmztcpHWD9f -----END CERTIFICATE----- -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud -EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH -DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA -bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx -ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx -51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk -R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP -T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f -Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl -osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR -crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR -saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD -KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi -6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - Izenpe.com ========== -----BEGIN CERTIFICATE----- @@ -3449,3 +3395,140 @@ TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W HYMfRsCbvUOZ58SWLs5fyQ== -----END CERTIFICATE----- + +TrustAsia Global Root CA G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG +A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM +G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw +MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu +MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz +lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ +Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V +P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag +dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm +9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc +D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg +WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea +mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF +TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj +7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 +D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T +G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj +duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl +cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys ++TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli +2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y +aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS +ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR +JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH +-----END CERTIFICATE----- + +TrustAsia Global Root CA G4 +=========================== +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE +BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry +dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa +MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw +IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 +m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ +pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA +bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk +dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNaFw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLx +eP0CflfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJEhRGnSjot +6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggqhkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2 +Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liW +pDVfG2XqYZpwI7UNo5uSUm9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +CommScope Public Trust ECC Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMwTjELMAkGA1UE +BhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBUcnVz +dCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRaFw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYT +AlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3Qg +RUNDIFJvb3QtMDIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/M +MDALj2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmUv4RDsNuE +SgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggqhkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9 +Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/nich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs7 +3u1Z/GtMMH9ZzkXpc2AVmkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-01 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45Ft +nYSkYZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslhsuitQDy6 +uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0alDrJLpA6lfO741GIDuZNq +ihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3OjWiE260f6GBfZumbCk6SP/F2krfxQapWs +vCQz0b2If4b19bJzKo98rwjyGpg/qYFlP8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/c +Zip8UlF1y5mO6D1cv547KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTif +BSeolz7pUcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/kQO9 +lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JOHg9O5j9ZpSPcPYeo +KFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkBEa801M/XrmLTBQe0MXXgDW1XT2mH ++VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6UCBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm4 +5P3luG0wDQYJKoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQnmhUQo8mUuJM +3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+QgvfKNmwrZggvkN80V4aCRck +jXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2vtrV0KnahP/t1MJ+UXjulYPPLXAziDslg+Mkf +Foom3ecnf+slpoq9uC02EJqxWE2aaE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/W +NyVntHKLr4W96ioDj8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+ +o/E4Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0wlREQKC6/ +oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHnYfkUyq+Dj7+vsQpZXdxc +1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVocicCMb3SgazNNtQEo/a2tiRc7ppqEvOuM +6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +CommScope Public Trust RSA Root-02 +================================== +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQELBQAwTjELMAkG +A1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29tbVNjb3BlIFB1YmxpYyBU +cnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNV +BAYTAlVTMRIwEAYDVQQKDAlDb21tU2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1 +c3QgUlNBIFJvb3QtMDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3V +rCLENQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0kyI9p+Kx +7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1CrWDaSWqVcN3SAOLMV2MC +e5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxzhkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2W +Wy09X6GDRl224yW4fKcZgBzqZUPckXk2LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rp +M9kzXzehxfCrPfp4sOcsn/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIf +hs1w/tkuFT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5kQMr +eyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3wNemKfrb3vOTlycE +VS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6vwQcQeKwRoi9C8DfF8rhW3Q5iLc4t +Vn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7Gx +cJXvYXowDQYJKoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3+VGXu6TwYofF +1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbymeAPnCKfWxkxlSaRosTKCL4BWa +MS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3NyqpgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xd +gSGn2rtO/+YHqP65DSdsu3BaVXoT6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2O +HG1QAk8mGEPej1WFsQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+Nm +YWvtPjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2dlklyALKr +dVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670v64fG9PiO/yzcnMcmyiQ +iRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17Org3bhzjlP1v9mxnhMUF6cKojawHhRUzN +lM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- diff --git a/resources/controllers/es_controller_mappings.cfg b/resources/controllers/es_controller_mappings.cfg index 5330c0fb6..a79dbe26b 100644 --- a/resources/controllers/es_controller_mappings.cfg +++ b/resources/controllers/es_controller_mappings.cfg @@ -1,5 +1,5 @@ # This file can be used to add mappings for controllers that are not supported by SDL by default. -# Don't edit this file at its default location, instead make a copy to ~/.emulationstation/ +# Don't edit this file at its default location, instead make a copy to ~/ES-DE/controllers/ # # Configuration entries should be in the format described at this URL: # https://github.com/gabomdq/SDL_GameControllerDB diff --git a/resources/graphics/help/dpad_all.svg b/resources/graphics/help/dpad_all.svg index 79c550fcb..043203b5b 100644 --- a/resources/graphics/help/dpad_all.svg +++ b/resources/graphics/help/dpad_all.svg @@ -11,71 +11,6 @@ id="defs15" /> - - - - - - - - + style="stroke:none;fill:#ffffff;fill-opacity:1" + d="M 26 2 A 4 4 0 0 0 22 6 L 22 22 L 6 22 A 4 4 0 0 0 2 26 L 2 38 A 4 4 0 0 0 6 42 L 22 42 L 22 58 A 4 4 0 0 0 26 62 L 38 62 A 4 4 0 0 0 42 58 L 42 42 L 58 42 A 4 4 0 0 0 62 38 L 62 26 A 4 4 0 0 0 58 22 L 42 22 L 42 6 A 4 4 0 0 0 38 2 L 26 2 z M 32 5.2011719 C 32.32252 5.2011719 32.645027 5.3534061 32.841797 5.6601562 L 37.841797 13.460938 C 38.267517 14.126373 37.79 14.999487 37 15 L 27 15 C 26.63474 14.999956 26.298557 14.800792 26.123047 14.480469 C 26.036697 14.323367 25.994 14.145954 26 13.966797 C 26.006 13.787018 26.060903 13.612262 26.158203 13.460938 L 31.158203 5.6601562 C 31.354973 5.3534062 31.67748 5.2011717 32 5.2011719 z M 13.966797 26 A 1.0001 1.0001 0 0 1 14.480469 26.123047 A 1.0001 1.0001 0 0 1 15 27 L 15 37 A 1.0001 1.0001 0 0 1 13.460938 37.841797 L 5.6601562 32.841797 A 1.0001 1.0001 0 0 1 5.6601562 31.158203 L 13.460938 26.158203 A 1.0001 1.0001 0 0 1 13.966797 26 z M 50.033203 26 A 1.0001 1.0001 0 0 1 50.539062 26.158203 L 58.339844 31.158203 A 1.0001 1.0001 0 0 1 58.339844 32.841797 L 50.539062 37.841797 A 1.0001 1.0001 0 0 1 49 37 L 49 27 A 1.0001 1.0001 0 0 1 49.519531 26.123047 A 1.0001 1.0001 0 0 1 50.033203 26 z M 27 49 L 37 49 C 37.79 49.000512 38.267517 49.873626 37.841797 50.539062 L 32.841797 58.339844 C 32.448267 58.953344 31.551733 58.953344 31.158203 58.339844 L 26.158203 50.539062 C 26.060903 50.38774 26.006 50.212982 26 50.033203 C 25.994 49.854046 26.036647 49.676634 26.123047 49.519531 C 26.298557 49.199208 26.63474 49.000044 27 49 z " /> diff --git a/resources/graphics/help/dpad_down.svg b/resources/graphics/help/dpad_down.svg index 84a41fc38..31d856a20 100644 --- a/resources/graphics/help/dpad_down.svg +++ b/resources/graphics/help/dpad_down.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/help/dpad_left.svg b/resources/graphics/help/dpad_left.svg index 1b018d69e..af1836c71 100644 --- a/resources/graphics/help/dpad_left.svg +++ b/resources/graphics/help/dpad_left.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/help/dpad_leftright.svg b/resources/graphics/help/dpad_leftright.svg index e18a6d725..2ce54284d 100644 --- a/resources/graphics/help/dpad_leftright.svg +++ b/resources/graphics/help/dpad_leftright.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/help/dpad_right.svg b/resources/graphics/help/dpad_right.svg index 228f5e044..a43e3f2c3 100644 --- a/resources/graphics/help/dpad_right.svg +++ b/resources/graphics/help/dpad_right.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/help/dpad_up.svg b/resources/graphics/help/dpad_up.svg index eb6dc0c9c..1eac2e7ef 100644 --- a/resources/graphics/help/dpad_up.svg +++ b/resources/graphics/help/dpad_up.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/help/dpad_updown.svg b/resources/graphics/help/dpad_updown.svg index 85116059c..fae555467 100644 --- a/resources/graphics/help/dpad_updown.svg +++ b/resources/graphics/help/dpad_updown.svg @@ -1,12 +1,16 @@ - - - - - - - - - - - + + + + diff --git a/resources/graphics/overlay/button_a.svg b/resources/graphics/overlay/button_a.svg new file mode 100644 index 000000000..7c61be77a --- /dev/null +++ b/resources/graphics/overlay/button_a.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/resources/graphics/overlay/button_b.svg b/resources/graphics/overlay/button_b.svg new file mode 100644 index 000000000..e1350b325 --- /dev/null +++ b/resources/graphics/overlay/button_b.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/resources/graphics/overlay/button_back.svg b/resources/graphics/overlay/button_back.svg new file mode 100644 index 000000000..4ef8da397 --- /dev/null +++ b/resources/graphics/overlay/button_back.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/resources/graphics/overlay/button_dpad.svg b/resources/graphics/overlay/button_dpad.svg new file mode 100644 index 000000000..25fa86f70 --- /dev/null +++ b/resources/graphics/overlay/button_dpad.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/resources/graphics/overlay/button_shoulder_l.svg b/resources/graphics/overlay/button_shoulder_l.svg new file mode 100644 index 000000000..9f69a46e4 --- /dev/null +++ b/resources/graphics/overlay/button_shoulder_l.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/resources/graphics/overlay/button_shoulder_r.svg b/resources/graphics/overlay/button_shoulder_r.svg new file mode 100644 index 000000000..504987886 --- /dev/null +++ b/resources/graphics/overlay/button_shoulder_r.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/resources/graphics/overlay/button_start.svg b/resources/graphics/overlay/button_start.svg new file mode 100644 index 000000000..b5db9697c --- /dev/null +++ b/resources/graphics/overlay/button_start.svg @@ -0,0 +1,39 @@ + + + + + + image/svg+xml + + + + + + + + diff --git a/resources/graphics/overlay/button_trigger_l.svg b/resources/graphics/overlay/button_trigger_l.svg new file mode 100644 index 000000000..c168f86ac --- /dev/null +++ b/resources/graphics/overlay/button_trigger_l.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/resources/graphics/overlay/button_trigger_r.svg b/resources/graphics/overlay/button_trigger_r.svg new file mode 100644 index 000000000..a4c082841 --- /dev/null +++ b/resources/graphics/overlay/button_trigger_r.svg @@ -0,0 +1,20 @@ + + + + + + diff --git a/resources/graphics/overlay/button_x.svg b/resources/graphics/overlay/button_x.svg new file mode 100644 index 000000000..8d46642f1 --- /dev/null +++ b/resources/graphics/overlay/button_x.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/resources/graphics/overlay/button_y.svg b/resources/graphics/overlay/button_y.svg new file mode 100644 index 000000000..9341aaffd --- /dev/null +++ b/resources/graphics/overlay/button_y.svg @@ -0,0 +1,22 @@ + + + + + + diff --git a/resources/graphics/splash.svg b/resources/graphics/splash.svg index b69352218..dfbaa17c9 100644 --- a/resources/graphics/splash.svg +++ b/resources/graphics/splash.svg @@ -2,14 +2,6 @@ image/svg+xml + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> @@ -104,27 +136,7 @@ - + @@ -132,216 +144,197 @@ - - - \ No newline at end of file + id="path42-4" + style="fill:#ffffff;fill-opacity:1" /> diff --git a/resources/shaders/glsl/blur_horizontal.glsl b/resources/shaders/glsl/blur_horizontal.glsl index e35b8cb04..438535efb 100644 --- a/resources/shaders/glsl/blur_horizontal.glsl +++ b/resources/shaders/glsl/blur_horizontal.glsl @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // blur_horizontal.glsl // // Horizontal gaussian blur. @@ -24,7 +24,7 @@ void main() #elif defined(FRAGMENT) #ifdef GL_ES -precision mediump float; +precision highp float; #endif uniform uint shaderFlags; @@ -41,6 +41,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { diff --git a/resources/shaders/glsl/blur_vertical.glsl b/resources/shaders/glsl/blur_vertical.glsl index e23d5e8e1..2a5a07fec 100644 --- a/resources/shaders/glsl/blur_vertical.glsl +++ b/resources/shaders/glsl/blur_vertical.glsl @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // blur_vertical.glsl // // Vertical gaussian blur. @@ -24,7 +24,7 @@ void main() #elif defined(FRAGMENT) #ifdef GL_ES -precision mediump float; +precision highp float; #endif uniform uint shaderFlags; @@ -41,6 +41,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { diff --git a/resources/shaders/glsl/core.glsl b/resources/shaders/glsl/core.glsl index 12587cfcf..e5372a65d 100644 --- a/resources/shaders/glsl/core.glsl +++ b/resources/shaders/glsl/core.glsl @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // core.glsl // // Core shader functionality. @@ -30,7 +30,7 @@ void main(void) #elif defined(FRAGMENT) #ifdef GL_ES -precision mediump float; +precision highp float; #endif in vec2 position; @@ -59,6 +59,7 @@ out vec4 FragColor; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { @@ -74,7 +75,14 @@ void main() discard; } - vec4 sampledColor = texture(textureSampler0, texCoord); + vec4 sampledColor; + + // Pixel format conversion is sometimes required as not all mobile GPUs support all + // OpenGL operations in BGRA format. + if (0x0u != (shaderFlags & 0x80u)) + sampledColor.bgra = texture(textureSampler0, texCoord); + else + sampledColor = texture(textureSampler0, texCoord); // Rounded corners. if (0x0u != (shaderFlags & 0x20u) || 0x0u != (shaderFlags & 0x40u)) { diff --git a/resources/shaders/glsl/scanlines.glsl b/resources/shaders/glsl/scanlines.glsl index a69725e75..5e0ff5120 100644 --- a/resources/shaders/glsl/scanlines.glsl +++ b/resources/shaders/glsl/scanlines.glsl @@ -24,7 +24,7 @@ #if defined(VERTEX) #ifdef GL_ES -precision mediump float; +precision highp float; #endif uniform mat4 MVPMatrix; @@ -53,7 +53,7 @@ void main() #elif defined(FRAGMENT) #ifdef GL_ES -precision mediump float; +precision highp float; #endif uniform vec2 texSize; @@ -102,6 +102,7 @@ uniform float OutputGamma; // 0x00000010 - Screen rotated 90 or 270 degrees // 0x00000020 - Rounded corners // 0x00000040 - Rounded corners with no anti-aliasing +// 0x00000080 - Convert pixel format void main() { diff --git a/resources/systems/android/es_find_rules.xml b/resources/systems/android/es_find_rules.xml new file mode 100644 index 000000000..ba5569eac --- /dev/null +++ b/resources/systems/android/es_find_rules.xml @@ -0,0 +1,308 @@ + + + + + + com.retroarch.aarch64/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch.ra32/com.retroarch.browser.retroactivity.RetroActivityFuture + com.retroarch/com.retroarch.browser.retroactivity.RetroActivityFuture + + + + + + com.explusalpha.A2600Emu/com.imagine.BaseActivity + + + + + + xyz.aethersx2.android/.EmulationActivity + + + + + + com.explusalpha.C64Emu/com.imagine.BaseActivity + + + + + + org.citra.citra_emu/.activities.EmulationActivity + org.citra.citra_emu/.ui.main.MainActivity + + + + + + org.citra.citra_emu.canary/org.citra.citra_emu.activities.EmulationActivity + + + + + + org.citra.emu/.ui.EmulationActivity + + + + + + com.fms.colem.deluxe/com.fms.emulib.TVActivity + com.fms.colem/com.fms.emulib.TVActivity + + + + + + org.dolphinemu.dolphinemu/.ui.main.TvMainActivity + + + + + + com.dsemu.drastic/.DraSticActivity + + + + + + com.github.stenzek.duckstation/.EmulationActivity + + + + + + com.github.eka2l1/.MainActivity + + + + + + com.epsxe.ePSXe/.ePSXe + + + + + + com.flycast.emulator/com.reicast.emulator.MainActivity + + + + + + com.fms.fmsx.deluxe/com.fms.emulib.TVActivity + com.fms.fmsx/com.fms.emulib.TVActivity + + + + + + com.emulator.fpse/.Main + + + + + + com.emulator.fpse64/.Main + + + + + + com.explusalpha.GbaEmu/com.imagine.BaseActivity + + + + + + com.explusalpha.GbcEmu/com.imagine.BaseActivity + + + + + + com.fms.ines.free/com.fms.emulib.TVActivity + + + + + + com.explusalpha.LynxEmu/com.imagine.BaseActivity + + + + + + org.mupen64plusae.v3.fzurita.pro/paulscode.android.mupen64plusae.SplashActivity + org.mupen64plusae.v3.fzurita/paulscode.android.mupen64plusae.SplashActivity + + + + + + com.seleuco.mame4droid/.MAME4droid + + + + + + com.seleuco.mame4d2024/com.seleuco.mame4droid.MAME4droid + + + + + + com.fms.mg/com.fms.emulib.TVActivity + + + + + + com.explusalpha.MdEmu/com.imagine.BaseActivity + + + + + + me.magnum.melonds/.ui.emulator.EmulatorActivity + + + + + + com.explusalpha.MsxEmu/com.imagine.BaseActivity + + + + + + com.fastemulator.gba/.EmulatorActivity + + + + + + com.fastemulator.gbc/.EmulatorActivity + + + + + + com.explusalpha.NeoEmu/com.imagine.BaseActivity + + + + + + com.explusalpha.NesEmu/com.imagine.BaseActivity + + + + + + com.androidemu.nes/.EmulatorActivity + + + + + + com.explusalpha.NgpEmu/com.imagine.BaseActivity + + + + + + org.openbor.engine/.GameActivity + + + + + + com.PceEmu/com.imagine.BaseActivity + + + + + + it.dbtecno.pizzaboygbapro/it.dbtecno.pizzaboygbapro.MainActivity + it.dbtecno.pizzaboygba/it.dbtecno.pizzaboygba.MainActivity + + + + + + it.dbtecno.pizzaboypro/it.dbtecno.pizzaboypro.MainActivity + it.dbtecno.pizzaboy/it.dbtecno.pizzaboy.MainActivity + + + + + + com.virtualapplications.play/.MainActivity + + + + + + org.ppsspp.ppssppgold/org.ppsspp.ppsspp.PpssppActivity + org.ppsspp.ppsspp/.PpssppActivity + + + + + + ru.vastness.altmer.real3doplayer/.EmulatorActivity + + + + + + io.recompiled.redream/.MainActivity + + + + + + rs.ruffle/.MainActivity + + + + + + com.explusalpha.SaturnEmu/com.imagine.BaseActivity + + + + + + com.explusalpha.Snes9xPlus/com.imagine.BaseActivity + + + + + + com.fms.speccy.deluxe/com.fms.emulib.TVActivity + com.fms.speccy/com.fms.emulib.TVActivity + + + + + + com.explusalpha.SwanEmu/com.imagine.BaseActivity + + + + + + org.vita3k.emulator/.Emulator + + + + + + org.yuzu.yuzu_emu.ea/org.yuzu.yuzu_emu.activities.EmulationActivity + org.yuzu.yuzu_emu/org.yuzu.yuzu_emu.activities.EmulationActivity + + + \ No newline at end of file diff --git a/resources/systems/android/es_systems.xml b/resources/systems/android/es_systems.xml new file mode 100644 index 000000000..768a96dad --- /dev/null +++ b/resources/systems/android/es_systems.xml @@ -0,0 +1,1990 @@ + + + + + 3do + 3DO Interactive Multiplayer + %ROMPATH%/3do + .bin .BIN .chd .CHD .cue .CUE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=opera_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_REAL3DOPLAYER% %DATA%=%ROMSAF% + 3do + 3do + + + adam + Coleco Adam + %ROMPATH%/adam + .1dd .1DD .bin .BIN .col .COL .cqi .CQI .cqm .CQM .d77 .D77 .d88 .D88 .ddp .DDP .dfi .DFI .dsk .DSK .hfe .HFE .imd .IMD .mfi .MFI .mfm .MFM .rom .ROM .td0 .TD0 .wav .WAV .7z .7Z .zip .ZIP + %EMULATOR_COLEM% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + adam + adam + + + ags + Adventure Game Studio Game Engine + %ROMPATH%/ags + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + ags + + + amiga + Commodore Amiga + %ROMPATH%/amiga + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae2021_libretro_android.so %EXTRA_ROM%=%ROM% + amiga + amiga + + + amiga1200 + Commodore Amiga 1200 + %ROMPATH%/amiga1200 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae2021_libretro_android.so %EXTRA_ROM%=%ROM% + amiga + amiga1200 + + + amiga600 + Commodore Amiga 600 + %ROMPATH%/amiga600 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae2021_libretro_android.so %EXTRA_ROM%=%ROM% + amiga + amiga600 + + + amigacd32 + Commodore Amiga CD32 + %ROMPATH%/amigacd32 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae2021_libretro_android.so %EXTRA_ROM%=%ROM% + amigacd32 + amigacd32 + + + amstradcpc + Amstrad CPC + %ROMPATH%/amstradcpc + .cdt .CDT .cpr .CPR .dsk .DSK .kcr .KCR .m3u .M3U .sna .SNA .tap .TAR .voc .VOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=cap32_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=crocods_libretro_android.so %EXTRA_ROM%=%ROM% + amstradcpc + amstradcpc + + + android + Google Android + %ROMPATH%/android + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + android + android + + + apple2 + Apple II + %ROMPATH%/apple2 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + apple2 + apple2 + + + apple2gs + Apple IIGS + %ROMPATH%/apple2gs + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + apple2gs + apple2gs + + + arcade + Arcade + %ROMPATH%/arcade + .cmd .CMD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_NEO-EMU% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + arcade + + + arcadia + Emerson Arcadia 2001 + %ROMPATH%/arcadia + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcadia + arcadia + + + archimedes + Acorn Archimedes + %ROMPATH%/archimedes + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + archimedes + archimedes + + + arduboy + Arduboy Miniature Game System + %ROMPATH%/arduboy + .hex .HEX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=arduous_libretro_android.so %EXTRA_ROM%=%ROM% + arduboy + arduboy + + + astrocde + Bally Astrocade + %ROMPATH%/astrocde + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + astrocde + astrocade + + + atari2600 + Atari 2600 + %ROMPATH%/atari2600 + .a26 .A26 .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=stella_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=stella2014_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_2600-EMU% %DATA%=%ROMPROVIDER% + atari2600 + atari2600 + + + atari5200 + Atari 5200 + %ROMPATH%/atari5200 + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .car .CAR .cas .CAS .cdm .CDM .rom .ROM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=a5200_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=atari800_libretro_android.so %EXTRA_ROM%=%ROM% + atari5200 + atari5200 + + + atari7800 + Atari 7800 ProSystem + %ROMPATH%/atari7800 + .a78 .A78 .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=prosystem_libretro_android.so %EXTRA_ROM%=%ROM% + atari7800 + atari7800 + + + atari800 + Atari 800 + %ROMPATH%/atari800 + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .car .CAR .cas .CAS .cdm .CDM .rom .ROM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=atari800_libretro_android.so %EXTRA_ROM%=%ROM% + atari800 + atari800 + + + atarijaguar + Atari Jaguar + %ROMPATH%/atarijaguar + .abs .ABS .bin .BIN .cdi .CDI .cof .COF .cue .CUE .j64 .J64 .jag .JAG .prg .PRG .rom .ROM .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=virtualjaguar_libretro_android.so %EXTRA_ROM%=%ROM% + atarijaguar + atarijaguar + + + atarijaguarcd + Atari Jaguar CD + %ROMPATH%/atarijaguarcd + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + atarijaguarcd + atarijaguarcd + + + atarilynx + Atari Lynx + %ROMPATH%/atarilynx + .lnx .LNX .o .O .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=handy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_lynx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_LYNX-EMU% %DATA%=%ROMPROVIDER% + atarilynx + atarilynx + + + atarist + Atari ST + %ROMPATH%/atarist + .st .ST .msa .MSA .stx .STX .dim .DIM .ipf .IPF .m3u .M3U .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=hatari_libretro_android.so %EXTRA_ROM%=%ROM% + atarist + atarist + + + atarixe + Atari XE + %ROMPATH%/atarixe + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .cas .CAS .cdm .CDM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=atari800_libretro_android.so %EXTRA_ROM%=%ROM% + atarixe + atarixe + + + atomiswave + Sammy Corporation Atomiswave + %ROMPATH%/atomiswave + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + atomiswave + + + bbcmicro + Acorn Computers BBC Micro + %ROMPATH%/bbcmicro + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + bbcmicro + bbcmicro + + + c64 + Commodore 64 + %ROMPATH%/c64 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_x64sc_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_x64_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_xscpu64_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_x128_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_C64-EMU% %DATA%=%ROMPROVIDER% + c64 + c64 + + + cdimono1 + Philips CD-i + %ROMPATH%/cdimono1 + .chd .CHD .cue .CUE .iso .ISO + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=same_cdi_libretro_android.so %EXTRA_ROM%=%ROM% + cdimono1 + cdimono1 + + + cdtv + Commodore CDTV + %ROMPATH%/cdtv + .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=puae2021_libretro_android.so %EXTRA_ROM%=%ROM% + cdtv + cdtv + + + chailove + ChaiLove Game Engine + %ROMPATH%/chailove + .chai .CHAI .chailove .CHAILOVE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=chailove_libretro_android.so %EXTRA_ROM%=%ROM% + love + chailove + + + channelf + Fairchild Channel F + %ROMPATH%/channelf + .bin .BIN .chf .CHF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=freechaf_libretro_android.so %EXTRA_ROM%=%ROM% + channelf + channelf + + + coco + Tandy Color Computer + %ROMPATH%/coco + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + coco + coco + + + colecovision + Coleco ColecoVision + %ROMPATH%/colecovision + .bin .BIN .cas .CAS .col .COL .cv .CV .dsk .DSK .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ri .RI .rom .ROM .sc .SC .sg .SG .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearcoleco_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MSX-EMU% %DATA%=%ROMSAF% + %EMULATOR_COLEM% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + colecovision + colecovision + + + consolearcade + Console Arcade Systems + %ROMPATH%/consolearcade + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + consolearcade + + + cps + Capcom Play System + %ROMPATH%/cps + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps1_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps2_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps3_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + cps + + + cps1 + Capcom Play System I + %ROMPATH%/cps1 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps1_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + cps1 + + + cps2 + Capcom Play System II + %ROMPATH%/cps2 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps2_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + cps2 + + + cps3 + Capcom Play System III + %ROMPATH%/cps3 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps3_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + cps3 + + + crvision + VTech CreatiVision + %ROMPATH%/crvision + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + crvision + crvision + + + daphne + Daphne Arcade LaserDisc Emulator + %ROMPATH%/daphne + .dirksimple .ogv .OGV + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dirksimple_libretro_android.so %EXTRA_ROM%=%ROM% + daphne, arcade + daphne + + + desktop + Desktop Applications + %ROMPATH%/desktop + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + desktop + + + doom + Doom + %ROMPATH%/doom + .iwad .IWAD .pwad .PWAD .wad .WAD + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=prboom_libretro_android.so %EXTRA_ROM%=%ROM% + pc, pcwindows + doom + + + dos + DOS (PC) + %ROMPATH%/dos + .bat .BAT .com .COM .conf .CONF .cue .CUE .dosz .DOSZ .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_pure_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_core_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_svn_libretro_android.so %EXTRA_ROM%=%ROM% + dos + dos + + + dragon32 + Dragon Data Dragon 32 + %ROMPATH%/dragon32 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + dragon32 + dragon32 + + + dreamcast + Sega Dreamcast + %ROMPATH%/dreamcast + .cdi .CDI .chd .CHD .cue .CUE .dat .DAT .elf .ELF .gdi .GDI .iso .ISO .lst .LST .m3u .M3U .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + %EMULATOR_REDREAM% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + dreamcast + dreamcast + + + easyrpg + EasyRPG Game Engine + %ROMPATH%/easyrpg + .easyrpg .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=easyrpg_libretro_android.so %EXTRA_ROM%=%ROM% + easyrpg + easyrpg + + + electron + Acorn Electron + %ROMPATH%/electron + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + electron + electron + + + emulators + Emulators + %ROMPATH%/emulators + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + emulators + + + epic + Epic Games Store + %ROMPATH%/epic + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + epic + + + famicom + Nintendo Family Computer + %ROMPATH%/famicom + .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/mesen_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/nestopia_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/fceumm_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/quicknes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NES-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_INES% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_NESOID% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + famicom + famicom + + + fba + FinalBurn Alpha + %ROMPATH%/fba + .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_neogeo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps1_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps2_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_cps3_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + fba + + + fbneo + FinalBurn Neo + %ROMPATH%/fbneo + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + fbneo + + + fds + Nintendo Famicom Disk System + %ROMPATH%/fds + .nes .NES .fds .FDS .unf .UNF .UNIF .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/mesen_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/nestopia_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/fceumm_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NES-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_INES% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_NESOID% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + fds + fds + + + flash + Adobe Flash + %ROMPATH%/flash + .swf .SWF + %EMULATOR_RUFFLE% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + flash + flash + + + fm7 + Fujitsu FM-7 + %ROMPATH%/fm7 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + fm7 + fm7 + + + fmtowns + Fujitsu FM Towns + %ROMPATH%/fmtowns + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + fmtowns + fmtowns + + + fpinball + Future Pinball + %ROMPATH%/fpinball + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + fpinball + fpinball + + + gamate + Bit Corporation Gamate + %ROMPATH%/gamate + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + gamate + gamate + + + gameandwatch + Nintendo Game and Watch + %ROMPATH%/gameandwatch + .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamemess_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gw_libretro_android.so %EXTRA_ROM%=%ROM% + gameandwatch + gameandwatch + + + gamecom + Tiger Electronics Game.com + %ROMPATH%/gamecom + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + gamecom + gamecom + + + gamegear + Sega Game Gear + %ROMPATH%/gamegear + .68k .68K .bin .BIN .bms .BMS .chd .CHD .col .COL .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearsystem_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=smsplus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MASTERGEAR% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + gamegear + gamegear + + + gb + Nintendo Game Boy + %ROMPATH%/gb + .bs .BS .cgb .CGB .dmg .DMG .gb .GB .gbc .GBC .sgb .SGB .sfc .SFC .smc .SMC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gambatte_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=sameboy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearboy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=tgbdual_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=DoubleCherryGB_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mgba_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vbam_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_GBC-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_MY-OLDBOY% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_PIZZA-BOY-GBC% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %EXTRA_rom_uri%=%ROM% + gb + gb + + + gba + Nintendo Game Boy Advance + %ROMPATH%/gba + .agb .AGB .bin .BIN .cgb .CGB .dmg .DMG .gb .GB .gba .GBA .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mgba_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vbam_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vba_next_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gpsp_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_GBA-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_MY-BOY% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_PIZZA-BOY-GBA% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %EXTRA_rom_uri%=%ROM% + gba + gba + + + gbc + Nintendo Game Boy Color + %ROMPATH%/gbc + .bs .BS .cgb .CGB .dmg .DMG .gb .GB .gbc .GBC .sgb .SGB .sfc .SFC .smc .SMC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gambatte_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=sameboy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearboy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=tgbdual_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=DoubleCherryGB_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mgba_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vbam_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_GBC-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_MY-OLDBOY% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_PIZZA-BOY-GBC% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %EXTRA_rom_uri%=%ROM% + gbc + gbc + + + gc + Nintendo GameCube + %ROMPATH%/gc + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/dolphin_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DOLPHIN% %ACTION%=android.intent.action.MAIN %CATEGORY%=android.intent.category.LEANBACK_LAUNCHER %EXTRA_AutoStartFile%=%ROMSAF% + gc + gc + + + genesis + Sega Genesis + %ROMPATH%/genesis + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + genesis + genesis + + + gmaster + Hartung Game Master + %ROMPATH%/gmaster + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + gmaster + gmaster + + + gx4000 + Amstrad GX4000 + %ROMPATH%/gx4000 + .bin .BIN .cdt .CDT .cpr .CPR .dsk .DSK .kcr .KCR .m3u .M3U .sna .SNA .tap .TAR .voc .VOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=cap32_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=crocods_libretro_android.so %EXTRA_ROM%=%ROM% + gx4000 + gx4000 + + + intellivision + Mattel Electronics Intellivision + %ROMPATH%/intellivision + .bin .BIN .int .INT .rom .ROM .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=freeintv_libretro_android.so %EXTRA_ROM%=%ROM% + intellivision + intellivision + + + j2me + Java 2 Micro Edition (J2ME) + %ROMPATH%/j2me + .jar .JAR .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=squirreljme_libretro_android.so %EXTRA_ROM%=%ROM% + android + j2me + + + kodi + Kodi Home Theatre Software + %ROMPATH%/kodi + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + kodi + + + laserdisc + LaserDisc Games + %ROMPATH%/laserdisc + .dirksimple .ogv .OGV + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dirksimple_libretro_android.so %EXTRA_ROM%=%ROM% + daphne, arcade + laserdisc + + + lcdgames + LCD Handheld Games + %ROMPATH%/lcdgames + .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamemess_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gw_libretro_android.so %EXTRA_ROM%=%ROM% + lcdgames, gameandwatch + lcdgames + + + lowresnx + LowRes NX Fantasy Console + %ROMPATH%/lowresnx + .nx .NX + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=lowresnx_libretro_android.so %EXTRA_ROM%=%ROM% + lowresnx + lowresnx + + + lutris + Lutris Open Gaming Platform + %ROMPATH%/lutris + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pc, pcwindows + lutris + + + lutro + Lutro Game Engine + %ROMPATH%/lutro + .lua .LUA .lutro .LUTRO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=lutro_libretro_android.so %EXTRA_ROM%=%ROM% + lutro + lutro + + + macintosh + Apple Macintosh + %ROMPATH%/macintosh + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + macintosh + macintosh + + + mame + Multiple Arcade Machine Emulator + %ROMPATH%/mame + .cmd .CMD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2003_plus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mame2000_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_NEO-EMU% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbalpha2012_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + mame + + + mame-advmame + AdvanceMAME + %ROMPATH%/mame-advmame + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + mame-advmame + + + mastersystem + Sega Master System + %ROMPATH%/mastersystem + .68k .68K .bin .BIN .bms .BMS .chd .CHD .col .COL .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=smsplus_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearsystem_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_MASTERGEAR% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + mastersystem + mastersystem + + + megacd + Sega Mega-CD + %ROMPATH%/megacd + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + segacd + megacd + + + megacdjp + Sega Mega-CD + %ROMPATH%/megacdjp + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + segacd + megacdjp + + + megadrive + Sega Mega Drive + %ROMPATH%/megadrive + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + megadrive + megadrive + + + megadrivejp + Sega Mega Drive + %ROMPATH%/megadrivejp + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + megadrive + megadrivejp + + + megaduck + Creatronic Mega Duck + %ROMPATH%/megaduck + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=sameduck_libretro_android.so %EXTRA_ROM%=%ROM% + megaduck + megaduck + + + mess + Multi Emulator Super System + %ROMPATH%/mess + .chd .CHD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamemess_libretro_android.so %EXTRA_ROM%=%ROM% + mess + mess + + + model2 + Sega Model 2 + %ROMPATH%/model2 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + arcade + model2 + + + model3 + Sega Model 3 + %ROMPATH%/model3 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + model3 + + + moto + Thomson MO/TO Series + %ROMPATH%/moto + .fd .FD .k7 .K7 .m5 .M5 .m7 .M7 .rom .ROM .sap .SAP .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=theodore_libretro_android.so %EXTRA_ROM%=%ROM% + moto + moto + + + msx + MSX + %ROMPATH%/msx + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fmsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FMSX% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_MSX-EMU% %DATA%=%ROMSAF% + msx + msx + + + msx1 + MSX1 + %ROMPATH%/msx1 + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fmsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FMSX% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_MSX-EMU% %DATA%=%ROMSAF% + msx + msx1 + + + msx2 + MSX2 + %ROMPATH%/msx2 + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fmsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FMSX% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_MSX-EMU% %DATA%=%ROMSAF% + msx2 + msx2 + + + msxturbor + MSX Turbo R + %ROMPATH%/msxturbor + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MSX-EMU% %DATA%=%ROMSAF% + msxturbor + msxturbor + + + mugen + M.U.G.E.N Game Engine + %ROMPATH%/mugen + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + mugen + mugen + + + multivision + Othello Multivision + %ROMPATH%/multivision + .bin .BIN .gg .GG .rom .ROM .sg .SG .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearsystem_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MASTERGEAR% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + sg-1000 + multivision + + + n3ds + Nintendo 3DS + %ROMPATH%/n3ds + .3ds .3DS .3dsx .3DSX .app .APP .axf .AXF .cci .CCI .cxi .CXI .elf .ELF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/citra_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_CITRA% %DATA%=%ROMSAF% + %EMULATOR_CITRA-CANARY% %DATA%=%ROMSAF% + %EMULATOR_CITRA-MMJ% %EXTRA_GamePath%=%ROM% + n3ds + n3ds + + + n64 + Nintendo 64 + %ROMPATH%/n64 + .bin .BIN .d64 .D64 .n64 .N64 .ndd .NDD .u1 .U1 .v64 .V64 .z64 .Z64 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mupen64plus_next_gles3_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_M64PLUS-FZ% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=parallel_n64_libretro_android.so %EXTRA_ROM%=%ROM% + n64 + n64 + + + n64dd + Nintendo 64DD + %ROMPATH%/n64dd + .bin .BIN .d64 .D64 .n64 .N64 .ndd .NDD .u1 .U1 .v64 .V64 .z64 .Z64 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mupen64plus_next_gles3_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_M64PLUS-FZ% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=parallel_n64_libretro_android.so %EXTRA_ROM%=%ROM% + n64 + n64dd + + + naomi + Sega NAOMI + %ROMPATH%/naomi + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + naomi + + + naomi2 + Sega NAOMI 2 + %ROMPATH%/naomi2 + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + naomi2 + + + naomigd + Sega NAOMI GD-ROM + %ROMPATH%/naomigd + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + arcade + naomigd + + + nds + Nintendo DS + %ROMPATH%/nds + .app .APP .bin .BIN .nds .NDS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=melondsds_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MELONDS% %ACTION%=me.magnum.melonds.LAUNCH_ROM %EXTRA_uri%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=desmume_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=desmume2015_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DRASTIC% %DATA%=%ROMSAF% + nds + nds + + + neogeo + SNK Neo Geo + %ROMPATH%/neogeo + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NEO-EMU% %DATA%=%ROMSAF% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + neogeo + neogeo + + + neogeocd + SNK Neo Geo CD + %ROMPATH%/neogeocd + .chd .CHD .cue .CUE + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=neocd_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + neogeocd + neogeocd + + + neogeocdjp + SNK Neo Geo CD + %ROMPATH%/neogeocdjp + .chd .CHD .cue .CUE + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=neocd_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fbneo_libretro_android.so %EXTRA_ROM%=%ROM% + neogeocd + neogeocdjp + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/mesen_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/nestopia_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/fceumm_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/quicknes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NES-EMU% %DATA%=%ROMPROVIDER% + %EMULATOR_INES% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + %EMULATOR_NESOID% %ACTION%=android.intent.action.VIEW %DATA%=%ROM% + nes + nes + + + ngage + Nokia N-Gage + %ROMPATH%/ngage + .ngage .zip .ZIP + %EMULATOR_EKA2L1% + ngage + ngage + + + ngp + SNK Neo Geo Pocket + %ROMPATH%/ngp + .ngc .NGC .ngp .NGP .ngpc .NGPC .npc .NPC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_ngp_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=race_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NGP-EMU% %DATA%=%ROMPROVIDER% + ngp + ngp + + + ngpc + SNK Neo Geo Pocket Color + %ROMPATH%/ngpc + .ngc .NGC .ngp .NGP .ngpc .NGPC .npc .NPC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_ngp_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=race_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_NGP-EMU% %DATA%=%ROMPROVIDER% + ngpc + ngpc + + + odyssey2 + Magnavox Odyssey 2 + %ROMPATH%/odyssey2 + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=o2em_libretro_android.so %EXTRA_ROM%=%ROM% + odyssey2 + odyssey2 + + + openbor + OpenBOR Game Engine + %ROMPATH%/openbor + .openbor + %EMULATOR_OPENBOR% %ACTION%=android.intent.action.MAIN + openbor + openbor + + + oric + Tangerine Computer Systems Oric + %ROMPATH%/oric + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + oric + oric + + + palm + Palm OS + %ROMPATH%/palm + .img .IMG .pqa .PQA .prc .PRC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mu_libretro_android.so %EXTRA_ROM%=%ROM% + palm + palm + + + pc + IBM PC + %ROMPATH%/pc + .bat .BAT .com .COM .conf .CONF .cue .CUE .dosz .DOSZ .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_pure_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_core_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_svn_libretro_android.so %EXTRA_ROM%=%ROM% + pc + pc + + + pc88 + NEC PC-8800 Series + %ROMPATH%/pc88 + .88d .88D .cmt .CMT .d88 .D88 .m3u .M3U .t88 .T88 .u88 .U88 + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=quasi88_libretro_android.so %EXTRA_ROM%=%ROM% + pc88 + pc88 + + + pc98 + NEC PC-9800 Series + %ROMPATH%/pc98 + .2hd .2HD .88d .88D .98d .98D .d88 .D88 .d98 .D98 .cmd .CMD .dup .DUP .fdd .FDD .fdi .FDI .hdd .HDD .hdi .HDI .hdm .HDM .hdn .HDN .m3u .M3U .nhd .NHD .tfd .TFD .thd .THD .xdf .XDF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=np2kai_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=nekop2_libretro_android.so %EXTRA_ROM%=%ROM% + pc98 + pc98 + + + pcarcade + PC Arcade Systems + %ROMPATH%/pcarcade + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + pcarcade + + + pcengine + NEC PC Engine + %ROMPATH%/pcengine + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_fast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PCE-EMU% %DATA%=%ROMPROVIDER% + pcengine + pcengine + + + pcenginecd + NEC PC Engine CD + %ROMPATH%/pcenginecd + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_fast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PCE-EMU% %DATA%=%ROMPROVIDER% + pcenginecd + pcenginecd + + + pcfx + NEC PC-FX + %ROMPATH%/pcfx + .ccd .CCD .chd .CHD .cue CUE .m3u .M3U .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pcfx_libretro_android.so %EXTRA_ROM%=%ROM% + pcfx + pcfx + + + pico8 + PICO-8 Fantasy Console + %ROMPATH%/pico8 + .p8 .P8 .png .PNG + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=libfake08-arm64.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=retro8_libretro_android.so %EXTRA_ROM%=%ROM% + pico8 + pico8 + + + plus4 + Commodore Plus/4 + %ROMPATH%/plus4 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_xplus4_libretro_android.so %EXTRA_ROM%=%ROM% + plus4 + plus4 + + + pokemini + Nintendo Pokémon Mini + %ROMPATH%/pokemini + .min .MIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=pokemini_libretro_android.so %EXTRA_ROM%=%ROM% + pokemini + pokemini + + + ports + Ports + %ROMPATH%/ports + .exe .EXE .game .GAME .phd .PHD .psx .PSX + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=ecwolf_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=nxengine_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=openlara_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=superbroswar_libretro_android.so %EXTRA_ROM%=%ROM% + pc, pcwindows + ports + + + ps2 + Sony PlayStation 2 + %ROMPATH%/ps2 + .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG + %EMULATOR_AETHERSX2% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMSAF% + %EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + ps2 + ps2 + + + ps3 + Sony PlayStation 3 + %ROMPATH%/ps3 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + ps3 + ps3 + + + ps4 + Sony PlayStation 4 + %ROMPATH%/ps4 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + ps4 + ps4 + + + psp + Sony PlayStation Portable + %ROMPATH%/psp + .chd .CHD .cso .CSO .elf .ELF .iso .ISO .pbp .PBP .prx .PRX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=ppsspp_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PPSSPP% %ACTION%=android.intent.action.VIEW %CATEGORY%=android.intent.category.DEFAULT %DATA%=%ROMSAF% + psp + psp + + + psvita + Sony PlayStation Vita + %ROMPATH%/psvita + .psvita + %EMULATOR_VITA3K% %EXTRAARRAY_AppStartParameters%=-r,%INJECT%=%BASENAME%.psvita + psvita + psvita + + + psx + Sony PlayStation + %ROMPATH%/psx + .bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_hw_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=pcsx_rearmed_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=swanstation_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DUCKSTATION% %EXTRABOOL_resumeState%=false %EXTRA_bootPath%=%ROMSAF% + %EMULATOR_EPSXE% %ACTION%=android.intent.action.MAIN %EXTRA_com.epsxe.ePSXe.isoName%=%ROMSAF% + %EMULATOR_FPSE-NG% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_FPSE% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + psx + psx + + + pv1000 + Casio PV-1000 + %ROMPATH%/pv1000 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pv1000 + pv1000 + + + quake + Quake + %ROMPATH%/quake + .pak .PAK .pk3 .PK3 + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=tyrquake_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vitaquake2_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vitaquake2-rogue_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vitaquake2-xatrix_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vitaquake2-zaero_libretro_android.so %EXTRA_ROM%=%ROM% + pc, pcwindows + quake + + + samcoupe + MGT SAM Coupé + %ROMPATH%/samcoupe + .dsk .DSK .mgt .MGT .sad .SAD .sbt .SBT .7z .7Z .zip .ZIP + %EMULATOR_SPECCY% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + samcoupe + samcoupe + + + satellaview + Nintendo Satellaview + %ROMPATH%/satellaview + .bml .BML .bs .BS .fig .FIG .sfc .SFC .smc .SMC .swc .SWC .st .ST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SNES9X-EXPLUS% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_hd_beta_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_mercury_accuracy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + satellaview + satellaview + + + saturn + Sega Saturn + %ROMPATH%/saturn + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_saturn_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=yabasanshiro_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=yabause_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SATURN-EMU% %DATA%=%ROMPROVIDER% + saturn + saturn + + + saturnjp + Sega Saturn + %ROMPATH%/saturnjp + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_saturn_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=yabasanshiro_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=yabause_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SATURN-EMU% %DATA%=%ROMPROVIDER% + saturn + saturnjp + + + scummvm + ScummVM Game Engine + %ROMPATH%/scummvm + .scummvm .SCUMMVM .svm .SVM + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=scummvm_libretro_android.so %EXTRA_ROM%=%ROM% + scummvm + scummvm + + + scv + Epoch Super Cassette Vision + %ROMPATH%/scv + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + scv + scv + + + sega32x + Sega Mega Drive 32X + %ROMPATH%/sega32x + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + sega32x + sega32x + + + sega32xjp + Sega Super 32X + %ROMPATH%/sega32xjp + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + sega32x + sega32xjp + + + sega32xna + Sega Genesis 32X + %ROMPATH%/sega32xna + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + sega32x + sega32xna + + + segacd + Sega CD + %ROMPATH%/segacd + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=picodrive_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MD-EMU% %DATA%=%ROMPROVIDER% + segacd + segacd + + + sfc + Nintendo SFC (Super Famicom) + %ROMPATH%/sfc + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SNES9X-EXPLUS% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_hd_beta_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_mercury_accuracy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_supafaust_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + snes + sfc + + + sg-1000 + Sega SG-1000 + %ROMPATH%/sg-1000 + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .ri .RI .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=genesis_plus_gx_wide_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=gearsystem_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MASTERGEAR% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + sg-1000 + sg-1000 + + + sgb + Nintendo Super Game Boy + %ROMPATH%/sgb + .gb .GB .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=sameboy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mgba_libretro_android.so %EXTRA_ROM%=%ROM% + sgb + sgb + + + snes + Nintendo SNES (Super Nintendo) + %ROMPATH%/snes + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SNES9X-EXPLUS% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_hd_beta_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_mercury_accuracy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_supafaust_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + snes + snes + + + snesna + Nintendo SNES (Super Nintendo) + %ROMPATH%/snesna + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SNES9X-EXPLUS% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_hd_beta_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_mercury_accuracy_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_supafaust_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mesen-s_libretro_android.so %EXTRA_ROM%=%ROM% + snes + snesna + + + solarus + Solarus Game Engine + %ROMPATH%/solarus + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + solarus + solarus + + + spectravideo + Spectravideo + %ROMPATH%/spectravideo + .cas .CAS .col .COL .dsk .DSK .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ri .RI .rom .ROM .sc .SC .sg .SG .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bluemsx_libretro_android.so %EXTRA_ROM%=%ROM% + spectravideo + spectravideo + + + steam + Valve Steam + %ROMPATH%/steam + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + steam + steam + + + stv + Sega Titan Video Game System + %ROMPATH%/stv + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mamearcade_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_MAME4DROID-2024% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + %EMULATOR_MAME4DROID% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER% + arcade + stv + + + sufami + Bandai SuFami Turbo + %ROMPATH%/sufami + .bml .BML .bs .BS .fig .FIG .sfc .SFC .smc .SMC .st .ST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=snes9x2010_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SNES9X-EXPLUS% %DATA%=%ROMSAF% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_hd_beta_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=bsnes_mercury_accuracy_libretro_android.so %EXTRA_ROM%=%ROM% + sufami + sufami + + + supergrafx + NEC SuperGrafx + %ROMPATH%/supergrafx + .ccd .CCD .chd .CHD .cue .CUE .pce .PCE .sgx .SGX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_supergrafx_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PCE-EMU% %DATA%=%ROMPROVIDER% + supergrafx + supergrafx + + + supervision + Watara Supervision + %ROMPATH%/supervision + .bin .BIN .sv .SV .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=potator_libretro_android.so %EXTRA_ROM%=%ROM% + supervision + supervision + + + supracan + Funtech Super A'Can + %ROMPATH%/supracan + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + supracan + supracan + + + switch + Nintendo Switch + %ROMPATH%/switch + .nca .NCA .nro .NRO .nso .NSO .nsp .NSP .xci .XCI + %EMULATOR_YUZU% %ACTION%=android.nfc.action.TECH_DISCOVERED %DATA%=%ROMPROVIDER% + switch + switch + + + symbian + Symbian + %ROMPATH%/symbian + .sis .SIS .sisx .SISX .symbian + %EMULATOR_EKA2L1% + ngage + symbian + + + tanodragon + Tano Dragon + %ROMPATH%/tanodragon + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + dragon32 + tanodragon + + + tg16 + NEC TurboGrafx-16 + %ROMPATH%/tg16 + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_fast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PCE-EMU% %DATA%=%ROMPROVIDER% + pcengine + tg16 + + + tg-cd + NEC TurboGrafx-CD + %ROMPATH%/tg-cd + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_pce_fast_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_PCE-EMU% %DATA%=%ROMPROVIDER% + pcenginecd + tg-cd + + + ti99 + Texas Instruments TI-99 + %ROMPATH%/ti99 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + ti99 + ti99 + + + tic80 + TIC-80 Fantasy Computer + %ROMPATH%/tic80 + .tic .TIC + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=tic80_libretro_android.so %EXTRA_ROM%=%ROM% + tic80 + tic80 + + + to8 + Thomson TO8 + %ROMPATH%/to8 + .fd .FD .k7 .K7 .m5 .M5 .m7 .M7 .rom .ROM .sap .SAP .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=theodore_libretro_android.so %EXTRA_ROM%=%ROM% + moto + to8 + + + triforce + Namco-Sega-Nintendo Triforce + %ROMPATH%/triforce + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + triforce + + + trs-80 + Tandy TRS-80 + %ROMPATH%/trs-80 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + trs-80 + trs-80 + + + type-x + Taito Type X + %ROMPATH%/type-x + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + arcade + type-x + + + uzebox + Uzebox Open Source Console + %ROMPATH%/uzebox + .uze .UZE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=uzem_libretro_android.so %EXTRA_ROM%=%ROM% + uzebox + uzebox + + + vectrex + GCE Vectrex + %ROMPATH%/vectrex + .bin .BIN .gam .GAM .vc .VC .vec .VEC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vecx_libretro_android.so %EXTRA_ROM%=%ROM% + vectrex + vectrex + + + vic20 + Commodore VIC-20 + %ROMPATH%/vic20 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=vice_xvic_libretro_android.so %EXTRA_ROM%=%ROM% + vic20 + vic20 + + + videopac + Philips Videopac G7000 + %ROMPATH%/videopac + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=o2em_libretro_android.so %EXTRA_ROM%=%ROM% + odyssey2 + videopac + + + virtualboy + Nintendo Virtual Boy + %ROMPATH%/virtualboy + .bin .BIN .vb .VB .vboy .VBOY .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_vb_libretro_android.so %EXTRA_ROM%=%ROM% + virtualboy + virtualboy + + + vpinball + Visual Pinball + %ROMPATH%/vpinball + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + vpinball + vpinball + + + vsmile + VTech V.Smile + %ROMPATH%/vsmile + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + vsmile + vsmile + + + wasm4 + WASM-4 Fantasy Console + %ROMPATH%/wasm4 + .wasm .WASM + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=wasm4_libretro_android.so %EXTRA_ROM%=%ROM% + wasm4 + wasm4 + + + wii + Nintendo Wii + %ROMPATH%/wii + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=/data/data/%ANDROIDPACKAGE%/cores/dolphin_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_DOLPHIN% %ACTION%=android.intent.action.MAIN %CATEGORY%=android.intent.category.LEANBACK_LAUNCHER %EXTRA_AutoStartFile%=%ROMSAF% + wii + wii + + + wiiu + Nintendo Wii U + %ROMPATH%/wiiu + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + wiiu + wiiu + + + windows + Microsoft Windows + %ROMPATH%/windows + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + pcwindows + windows + + + windows3x + Microsoft Windows 3.x + %ROMPATH%/windows3x + .bat .BAT .dosz .DOSZ .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_pure_libretro_android.so %EXTRA_ROM%=%ROM% + windows3x + windows3x + + + windows9x + Microsoft Windows 9x + %ROMPATH%/windows9x + .bat .BAT .dosz .DOSZ .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=dosbox_pure_libretro_android.so %EXTRA_ROM%=%ROM% + pcwindows + windows9x + + + wonderswan + Bandai WonderSwan + %ROMPATH%/wonderswan + .pc2 .PC2 .ws .WS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_wswan_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SWAN-EMU% %DATA%=%ROMPROVIDER% + wonderswan + wonderswan + + + wonderswancolor + Bandai WonderSwan Color + %ROMPATH%/wonderswancolor + .pc2 .PC2 .ws .WS .wsc .WSC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_wswan_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SWAN-EMU% %DATA%=%ROMPROVIDER% + wonderswancolor + wonderswancolor + + + x1 + Sharp X1 + %ROMPATH%/x1 + .2d .2D .2hd .2HD .88d .88D .cmd .CMD .d88 .D88 .dup .DUP .dx1 .DX1 .hdm .HDM .tap .TAP .tfd .TFD .xdf .XDF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=x1_libretro_android.so %EXTRA_ROM%=%ROM% + x1 + x1 + + + x68000 + Sharp X68000 + %ROMPATH%/x68000 + .2hd .2HD .88d .88D .cmd .CMD .d88 .D88 .dim .DIM .dup .DUP .hdf .HDF .hdm .HDM .img .IMG .m3u .M3U .xdf .XDF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=px68k_libretro_android.so %EXTRA_ROM%=%ROM% + x68000 + x68000 + + + xbox + Microsoft Xbox + %ROMPATH%/xbox + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + xbox + xbox + + + xbox360 + Microsoft Xbox 360 + %ROMPATH%/xbox360 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + xbox360 + xbox360 + + + zmachine + Infocom Z-machine + %ROMPATH%/zmachine + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + zmachine + zmachine + + + zx81 + Sinclair ZX81 + %ROMPATH%/zx81 + .p .P .tzx .TZX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=81_libretro_android.so %EXTRA_ROM%=%ROM% + zx81 + zx81 + + + zxnext + Sinclair ZX Spectrum Next + %ROMPATH%/zxnext + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + zxnext + zxnext + + + zxspectrum + Sinclair ZX Spectrum + %ROMPATH%/zxspectrum + .dsk .DSK .gz .GZ .img .IMG .mgt .MGT .rzx .RZX .scl .SCL .sh .SH .sna .SNA .szx .SZX .tap .TAP .trd .TRD .tzx .TZX .udi .UDI .z80 .Z80 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=fuse_libretro_android.so %EXTRA_ROM%=%ROM% + %EMULATOR_SPECCY% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF% + zxspectrum + zxspectrum + + \ No newline at end of file diff --git a/resources/systems/linux/es_find_rules.xml b/resources/systems/linux/es_find_rules.xml new file mode 100644 index 000000000..ca783ed4c --- /dev/null +++ b/resources/systems/linux/es_find_rules.xml @@ -0,0 +1,1084 @@ + + + + + + + bash + sh + + + + + retroarch + org.libretro.RetroArch + + + ~/Applications/RetroArch-Linux*.AppImage + ~/.local/share/applications/RetroArch-Linux*.AppImage + ~/.local/bin/RetroArch-Linux*.AppImage + ~/bin/RetroArch-Linux*.AppImage + /var/lib/flatpak/exports/bin/org.libretro.RetroArch + ~/.local/share/flatpak/exports/bin/org.libretro.RetroArch + + + + + + ~/.config/retroarch/cores + + ~/Applications/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores + ~/.local/share/applications/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores + ~/.local/bin/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores + ~/bin/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores + + ~/.var/app/org.libretro.RetroArch/config/retroarch/cores + + ~/snap/retroarch/current/.config/retroarch/cores + + /usr/lib/x86_64-linux-gnu/libretro + + /usr/lib64/libretro + + /usr/lib/libretro + + + + + + ~/Applications/3dSen/3dSen.exe + ~/.local/share/applications/3dSen/3dSen.exe + ~/.local/bin/3dSen/3dSen.exe + ~/bin/3dSen/3dSen.exe + + + + + + advmame + + + ~/Applications/advancemame/advmame + ~/.local/share/applications/advancemame/advmame + ~/.local/bin/advancemame/advmame + ~/bin/advancemame/advmame + + + + + + amiberry + + + ~/Applications/amiberry/amiberry + ~/.local/share/applications/amiberry/amiberry + ~/.local/bin/amiberry/amiberry + ~/bin/amiberry/amiberry + + + + + + ares + dev.ares.ares + + + /var/lib/flatpak/exports/bin/dev.ares.ares + ~/.local/share/flatpak/exports/bin/dev.ares.ares + + + + + + atari800 + atari800-jz.atari800 + + + + + + BasiliskII + net.cebix.basilisk + + + ~/Applications/BasiliskII*.AppImage + ~/.local/share/applications/BasiliskII*.AppImage + ~/.local/bin/BasiliskII*.AppImage + ~/bin/BasiliskII*.AppImage + /var/lib/flatpak/exports/bin/net.cebix.basilisk + ~/.local/share/flatpak/exports/bin/net.cebix.basilisk + + + + + + ~/Applications/BigPEmu/BigPEmu.exe + ~/.local/share/applications/BigPEmu/BigPEmu.exe + ~/.local/bin/BigPEmu/BigPEmu.exe + ~/bin/BigPEmu/BigPEmu.exe + + + + + + blastem + com.retrodev.blastem + + + /var/lib/flatpak/exports/bin/com.retrodev.blastem + ~/.local/share/flatpak/exports/bin/com.retrodev.blastem + + + + + + bsnes + dev.bsnes.bsnes + + + /var/lib/flatpak/exports/bin/dev.bsnes.bsnes + ~/.local/share/flatpak/exports/bin/dev.bsnes.bsnes + + + + + + cemu + Cemu + + + ~/Applications/Cemu*.AppImage + ~/.local/share/applications/Cemu*.AppImage + ~/.local/bin/Cemu*.AppImage + ~/bin/Cemu*.AppImage + ~/Applications/Cemu/Cemu + ~/.local/share/applications/Cemu/Cemu + ~/.local/bin/Cemu/Cemu + ~/bin/Cemu/Cemu + /var/lib/flatpak/exports/bin/info.cemu.Cemu + ~/.local/share/flatpak/exports/bin/info.cemu.Cemu + + + + + + citra + citra-emu.citra-nightly + org.citra_emu.citra + + + ~/Applications/citra-qt*.AppImage + ~/.local/share/applications/citra-qt*.AppImage + ~/.local/bin/citra-qt*.AppImage + ~/bin/citra-qt*.AppImage + ~/.citra/canary/citra-qt.AppImage + ~/.citra/nightly/citra-qt.AppImage + /var/lib/flatpak/exports/bin/org.citra_emu.citra + ~/.local/share/flatpak/exports/bin/org.citra_emu.citra + + + + + + cpcemu + + + ~/Applications/cpcemu/cpcemu + ~/.local/share/applications/cpcemu/cpcemu + ~/.local/bin/cpcemu/cpcemu + ~/bin/cpcemu/cpcemu + + + + + + ~/Applications/CSpect/CSpect.exe + ~/.local/share/applications/CSpect/CSpect.exe + ~/.local/bin/CSpect/CSpect.exe + ~/bin/CSpect/CSpect.exe + + + + + + ~/Applications/demul/demul.exe + ~/.local/share/applications/demul/demul.exe + ~/.local/bin/demul/demul.exe + ~/bin/demul/demul.exe + + + + + + desmume + org.desmume.DeSmuME + + + /var/lib/flatpak/exports/bin/org.desmume.DeSmuME + ~/.local/share/flatpak/exports/bin/org.desmume.DeSmuME + + + + + + dolphin-emu + dolphin-emulator.dolphin-emu + org.DolphinEmu.dolphin-emu + + + ~/Applications/Dolphin_Emulator*.AppImage + ~/.local/share/applications/Dolphin_Emulator*.AppImage + ~/.local/bin/Dolphin_Emulator*.AppImage + ~/bin/Dolphin_Emulator*.AppImage + /var/lib/flatpak/exports/bin/org.DolphinEmu.dolphin-emu + ~/.local/share/flatpak/exports/bin/org.DolphinEmu.dolphin-emu + + + + + + dosbox-staging + io.github.dosbox-staging + + + /var/lib/flatpak/exports/bin/io.github.dosbox-staging + ~/.local/share/flatpak/exports/bin/io.github.dosbox-staging + + + + + + dosbox-x + com.dosbox_x.DOSBox-X + + + /var/lib/flatpak/exports/bin/com.dosbox_x.DOSBox-X + ~/.local/share/flatpak/exports/bin/com.dosbox_x.DOSBox-X + + + + + + duckstation-nogui + duckstation-qt + org.duckstation.DuckStation + + + ~/Applications/DuckStation*.AppImage + ~/.local/share/applications/DuckStation*.AppImage + ~/.local/bin/DuckStation*.AppImage + ~/bin/DuckStation*.AppImage + ~/Applications/duckstation-nogui*.AppImage + ~/.local/share/applications/duckstation-nogui*.AppImage + ~/.local/bin/duckstation-nogui*.AppImage + ~/bin/duckstation-nogui*.AppImage + ~/Applications/duckstation-qt*.AppImage + ~/.local/share/applications/duckstation-qt*.AppImage + ~/.local/bin/duckstation-qt*.AppImage + ~/bin/duckstation-qt*.AppImage + /var/lib/flatpak/exports/bin/org.duckstation.DuckStation + ~/.local/share/flatpak/exports/bin/org.duckstation.DuckStation + + + + + + easyrpg-player + + + ~/Applications/easyrpg/easyrpg-player + ~/.local/share/applications/easyrpg/easyrpg-player + ~/.local/bin/easyrpg/easyrpg-player + ~/bin/easyrpg/easyrpg-player + + + + + + eka2l1_qt + + + ~/Applications/EKA2L1*.AppImage + ~/.local/share/applications/EKA2L1*.AppImage + ~/.local/bin/EKA2L1*.AppImage + ~/bin/EKA2L1*.AppImage + + + + + + ~/Applications/EKA2L1/eka2l1_qt.exe + ~/.local/share/applications/EKA2L1/eka2l1_qt.exe + ~/.local/bin/EKA2L1/eka2l1_qt.exe + ~/bin/EKA2L1/eka2l1_qt.exe + + + + + + fbneo + + + ~/Applications/fbneo/fbneo + ~/.local/share/applications/fbneo/fbneo + ~/.local/bin/fbneo/fbneo + ~/bin/fbneo/fbneo + + + + + + flycast + org.flycast.Flycast + + + ~/Applications/flycast-x86*.AppImage + ~/.local/share/applications/flycast-x86*.AppImage + ~/.local/bin/flycast-x86*.AppImage + ~/bin/flycast-x86*.AppImage + /var/lib/flatpak/exports/bin/org.flycast.Flycast + ~/.local/share/flatpak/exports/bin/org.flycast.Flycast + + + + + + flycast-dojo + + + ~/Applications/flycast-dojo*.AppImage + ~/.local/share/applications/flycast-dojo*.AppImage + ~/.local/bin/flycast-dojo*.AppImage + ~/bin/flycast-dojo*.AppImage + + + + + + fs-uae-launcher + fsuae.launcher + + + /var/lib/flatpak/exports/bin/net.fsuae.FS-UAE|flatpak run --command=fs-uae-launcher net.fsuae.FS-UAE + ~/.local/share/flatpak/exports/bin/net.fsuae.FS-UAE|flatpak run --command=fs-uae-launcher net.fsuae.FS-UAE + + + + + + fuse + net.sf.fuse_emulator + + + /var/lib/flatpak/exports/bin/net.sf.fuse_emulator + ~/.local/share/flatpak/exports/bin/net.sf.fuse_emulator + + + + + + gargoyle + io.github.garglk.Gargoyle + + + ~/Applications/Gargoyle*.AppImage + ~/.local/share/applications/Gargoyle*.AppImage + ~/.local/bin/Gargoyle*.AppImage + ~/bin/Gargoyle*.AppImage + /var/lib/flatpak/exports/bin/io.github.garglk.Gargoyle + ~/.local/share/flatpak/exports/bin/io.github.garglk.Gargoyle + + + + + + gearboy + + + ~/Applications/gearboy/gearboy + ~/.local/share/applications/gearboy/gearboy + ~/.local/bin/gearboy/gearboy + ~/bin/gearboy/gearboy + + + + + + ~/Applications/gopher2600/gopher2600_linux_amd64 + ~/.local/share/applications/gopher2600/gopher2600_linux_amd64 + ~/.local/bin/gopher2600/gopher2600_linux_amd64 + ~/bin/gopher2600/gopher2600_linux_amd64 + + + + + + hatari + org.tuxfamily.hatari + + + /var/lib/flatpak/exports/bin/org.tuxfamily.hatari + ~/.local/share/flatpak/exports/bin/org.tuxfamily.hatari + + + + + + hypseus.bin + + + ~/Applications/hypseus-singe/hypseus.bin + ~/.local/share/applications/hypseus-singe/hypseus.bin + ~/.local/bin/hypseus-singe/hypseus.bin + ~/bin/hypseus-singe/hypseus.bin + + + + + + lightspark + + + ~/Applications/lightspark/lightspark + ~/.local/share/applications/lightspark/lightspark + ~/.local/bin/lightspark/lightspark + ~/bin/lightspark/lightspark + + + + + + linapple + + + ~/Applications/linapple/linapple + ~/.local/share/applications/linapple/linapple + ~/.local/bin/linapple/linapple + ~/bin/linapple/linapple + + + + + + ~/Applications/m2emulator/EMULATOR.EXE + ~/.local/share/applications/m2emulator/EMULATOR.EXE + ~/.local/bin/m2emulator/EMULATOR.EXE + ~/bin/m2emulator/EMULATOR.EXE + + + + + + mame + org.mamedev.MAME + + + /var/lib/flatpak/exports/bin/org.mamedev.MAME + ~/.local/share/flatpak/exports/bin/org.mamedev.MAME + + + + + + mednafen + + + /var/lib/flatpak/exports/bin/com.github.AmatCoder.mednaffe|flatpak run --command=mednafen com.github.AmatCoder.mednaffe + ~/.local/share/flatpak/exports/bin/com.github.AmatCoder.mednaffe|flatpak run --command=mednafen com.github.AmatCoder.mednaffe + + + + + + melonds + melonDS + net.kuribo64.melonDS + + + /var/lib/flatpak/exports/bin/net.kuribo64.melonDS + ~/.local/share/flatpak/exports/bin/net.kuribo64.melonDS + + + + + + mesen2 + + + ~/Applications/Mesen*.AppImage + ~/.local/share/applications/Mesen*.AppImage + ~/.local/bin/Mesen*.AppImage + ~/bin/Mesen*.AppImage + + + + + + mgba + mgba-qt + io.mgba.mGBA + + + ~/Applications/mGBA*.AppImage + ~/.local/share/applications/mGBA*.AppImage + ~/.local/bin/mGBA*.AppImage + ~/bin/mGBA*.AppImage + /var/lib/flatpak/exports/bin/io.mgba.mGBA + ~/.local/share/flatpak/exports/bin/io.mgba.mGBA + + + + + + m64p + io.github.m64p.m64p + + + /var/lib/flatpak/exports/bin/io.github.m64p.m64p + ~/.local/share/flatpak/exports/bin/io.github.m64p.m64p + + + + + + nestopia + ca._0ldsk00l.Nestopia + + + /var/lib/flatpak/exports/bin/ca._0ldsk00l.Nestopia + ~/.local/share/flatpak/exports/bin/ca._0ldsk00l.Nestopia + + + + + + openmsx + org.openmsx.openMSX + + + /var/lib/flatpak/exports/bin/org.openmsx.openMSX + ~/.local/share/flatpak/exports/bin/org.openmsx.openMSX + + + + + + Oricutron + + + ~/Applications/oricutron/Oricutron + ~/.local/share/applications/oricutron/Oricutron + ~/.local/bin/oricutron/Oricutron + ~/bin/oricutron/Oricutron + + + + + + pcsx2-qt + net.pcsx2.PCSX2 + + + ~/Applications/pcsx2*.AppImage + ~/.local/share/applications/pcsx2*.AppImage + ~/.local/bin/pcsx2*.AppImage + ~/bin/pcsx2*.AppImage + /var/lib/flatpak/exports/bin/net.pcsx2.PCSX2 + ~/.local/share/flatpak/exports/bin/net.pcsx2.PCSX2 + + + + + + PCSX2 + pcsx2 + net.pcsx2.PCSX2 + + + /var/lib/flatpak/exports/bin/net.pcsx2.PCSX2 + ~/.local/share/flatpak/exports/bin/net.pcsx2.PCSX2 + + + + + + pico8 + + + ~/Applications/pico-8/pico8 + ~/.local/share/applications/pico-8/pico8 + ~/.local/bin/pico-8/pico8 + ~/bin/pico-8/pico8 + + + + + + org.purei.Play + + + ~/Applications/Play!*.AppImage + ~/.local/share/applications/Play!*.AppImage + ~/.local/bin/Play!*.AppImage + ~/bin/Play!*.AppImage + /var/lib/flatpak/exports/bin/org.purei.Play + ~/.local/share/flatpak/exports/bin/org.purei.Play + + + + + + ppsspp-emu.ppsspp-sdl + PPSSPPSDL + PPSSPPQt + org.ppsspp.PPSSPP + + + /var/lib/flatpak/exports/bin/org.ppsspp.PPSSPP + ~/.local/share/flatpak/exports/bin/org.ppsspp.PPSSPP + + + + + + prboom-plus + + + + + + primehack + io.github.shiiion.primehack + + + /var/lib/flatpak/exports/bin/io.github.shiiion.primehack + ~/.local/share/flatpak/exports/bin/io.github.shiiion.primehack + + + + + + ~/Applications/Proton/wine*.AppImage + ~/.local/share/applications/Proton/wine*.AppImage + ~/.local/bin/Proton/wine*.AppImage + ~/bin/Proton/wine*.AppImage + + + + + + punes + + + ~/Applications/punes/punes + ~/.local/share/applications/punes/punes + ~/.local/bin/punes/punes + ~/bin/punes/punes + /var/lib/flatpak/exports/bin/io.github.punesemu.puNES + ~/.local/share/flatpak/exports/bin/io.github.punesemu.puNES + + + + + + quasi88 + + + ~/Applications/quasi88/quasi88 + ~/.local/share/applications/quasi88/quasi88 + ~/.local/bin/quasi88/quasi88 + ~/bin/quasi88/quasi88 + + + + + + redream + + + ~/Applications/redream/redream + ~/.local/share/applications/redream/redream + ~/.local/bin/redream/redream + ~/bin/redream/redream + + + + + + RMG + com.github.Rosalie241.RMG + + + ~/Applications/RMG*.AppImage + ~/.local/share/applications/RMG*.AppImage + ~/.local/bin/RMG*.AppImage + ~/bin/RMG*.AppImage + /var/lib/flatpak/exports/bin/com.github.Rosalie241.RMG + ~/.local/share/flatpak/exports/bin/com.github.Rosalie241.RMG + + + + + + rpcs3 + rpcs3-emu.rpcs3 + net.rpcs3.RPCS3 + + + ~/Applications/rpcs3*.AppImage + ~/.local/share/applications/rpcs3*.AppImage + ~/.local/bin/rpcs3*.AppImage + ~/bin/rpcs3*.AppImage + /var/lib/flatpak/exports/bin/net.rpcs3.RPCS3 + ~/.local/share/flatpak/exports/bin/net.rpcs3.RPCS3 + + + + + + ruffle + + + ~/Applications/ruffle/ruffle + ~/.local/share/applications/ruffle/ruffle + ~/.local/bin/ruffle/ruffle + ~/bin/ruffle/ruffle + + + + + + Ryujinx + Ryujinx.Ava + org.ryujinx.Ryujinx + + + /var/lib/flatpak/exports/bin/org.ryujinx.Ryujinx + ~/.local/share/flatpak/exports/bin/org.ryujinx.Ryujinx + ~/Applications/publish/Ryujinx + ~/.local/share/applications/publish/Ryujinx + ~/.local/bin/publish/Ryujinx + ~/bin/publish/Ryujinx + ~/Applications/publish/Ryujinx.Ava + ~/.local/share/applications/publish/Ryujinx.Ava + ~/.local/bin/publish/Ryujinx.Ava + ~/bin/publish/Ryujinx.Ava + + + + + + sameboy + io.github.sameboy.SameBoy + + + /var/lib/flatpak/exports/bin/io.github.sameboy.SameBoy + ~/.local/share/flatpak/exports/bin/io.github.sameboy.SameBoy + + + + + + scummvm + org.scummvm.ScummVM + + + /var/lib/flatpak/exports/bin/org.scummvm.ScummVM + ~/.local/share/flatpak/exports/bin/org.scummvm.ScummVM + + + + + + sdl2trs + + + ~/Applications/sdl2trs/sdl2trs + ~/.local/share/applications/sdl2trs/sdl2trs + ~/.local/bin/sdl2trs/sdl2trs + ~/bin/sdl2trs/sdl2trs + + + + + + SheepShaver + + + ~/Applications/SheepShaver*.AppImage + ~/.local/share/applications/SheepShaver*.AppImage + ~/.local/bin/SheepShaver*.AppImage + ~/bin/SheepShaver*.AppImage + + + + + + simcoupe + + + ~/Applications/simcoupe/simcoupe + ~/.local/share/applications/simcoupe/simcoupe + ~/.local/bin/simcoupe/simcoupe + ~/bin/simcoupe/simcoupe + + + + + + simple64-gui + io.github.simple64.simple64 + + + /var/lib/flatpak/exports/bin/io.github.simple64.simple64 + ~/.local/share/flatpak/exports/bin/io.github.simple64.simple64 + + + + + + SkyEmu + + + ~/Applications/SkyEmu/SkyEmu + ~/.local/share/applications/SkyEmu/SkyEmu + ~/.local/bin/SkyEmu/SkyEmu + ~/bin/SkyEmu/SkyEmu + + + + + + snes9x + snes9x-gtk + com.snes9x.Snes9x + + + ~/Applications/Snes9x*.AppImage + ~/.local/share/applications/Snes9x*.AppImage + ~/.local/bin/Snes9x*.AppImage + ~/bin/Snes9x*.AppImage + /var/lib/flatpak/exports/bin/com.snes9x.Snes9x + ~/.local/share/flatpak/exports/bin/com.snes9x.Snes9x + + + + + + solarus-run + solarus.run + + + /var/lib/flatpak/exports/bin/org.solarus_games.solarus.Launcher|flatpak run --command=solarus-run org.solarus_games.solarus.Launcher + ~/.local/share/flatpak/exports/bin/org.solarus_games.solarus.Launcher|flatpak run --command=solarus-run org.solarus_games.solarus.Launcher + + + + + + steam + + + + + + stella + io.github.stella_emu.Stella + + + /var/lib/flatpak/exports/bin/io.github.stella_emu.Stella + ~/.local/share/flatpak/exports/bin/io.github.stella_emu.Stella + + + + + + supermodel + + + ~/Applications/Supermodel/supermodel + ~/.local/share/applications/Supermodel/supermodel + ~/.local/bin/Supermodel/supermodel + ~/bin/Supermodel/supermodel + /var/lib/flatpak/exports/bin/com.supermodel3.Supermodel + ~/.local/share/flatpak/exports/bin/com.supermodel3.Supermodel + + + + + + tic80 + com.tic80.TIC_80 + + + /var/lib/flatpak/exports/bin/com.tic80.TIC_80 + ~/.local/share/flatpak/exports/bin/com.tic80.TIC_80 + + + + + + dolphin-emu-triforce + + + ~/Applications/dolphin-emu-triforce*.AppImage + ~/.local/share/applications/dolphin-emu-triforce*.AppImage + ~/.local/bin/dolphin-emu-triforce*.AppImage + ~/bin/dolphin-emu-triforce*.AppImage + + + + + + ~/Applications/tsugaru/Tsugaru_CUI + ~/.local/share/applications/tsugaru/Tsugaru_CUI + ~/.local/bin/tsugaru/Tsugaru_CUI + ~/bin/tsugaru/Tsugaru_CUI + + + + + + visualboyadvance-m + + + + + + x64sc + vice-jz.x64sc + net.sf.VICE + + + /var/lib/flatpak/exports/bin/net.sf.VICE + ~/.local/share/flatpak/exports/bin/net.sf.VICE + + + + + + xplus4 + vice-jz.xplus4 + + + /var/lib/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xplus4 net.sf.VICE + ~/.local/share/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xplus4 net.sf.VICE + + + + + + xvic + vice-jz.xvic + + + /var/lib/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xvic net.sf.VICE + ~/.local/share/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xvic net.sf.VICE + + + + + + VPinballX_GL + + + ~/Applications/VPinballX/VPinballX_GL + ~/.local/share/applications/VPinballX/VPinballX_GL + ~/.local/bin/VPinballX/VPinballX_GL + ~/bin/VPinballX/VPinballX_GL + + + + + + vita3k + Vita3K + + + ~/Applications/Vita3K*.AppImage + ~/.local/share/applications/Vita3K*.AppImage + ~/.local/bin/Vita3K*.AppImage + ~/bin/Vita3K*.AppImage + ~/Applications/Vita3K/Vita3K + ~/.local/share/applications/Vita3K/Vita3K + ~/.local/bin/Vita3K/Vita3K + ~/bin/Vita3K/Vita3K + + + + + + xemu + app.xemu.xemu + + + ~/Applications/xemu*.AppImage + ~/.local/share/applications/xemu*.AppImage + ~/.local/bin/xemu*.AppImage + ~/bin/xemu*.AppImage + /var/lib/flatpak/exports/bin/app.xemu.xemu + ~/.local/share/flatpak/exports/bin/app.xemu.xemu + + + + + + ~/Applications/Wine/wine*.AppImage + ~/.local/share/applications/Wine/wine*.AppImage + ~/.local/bin/Wine/wine*.AppImage + ~/bin/Wine/wine*.AppImage + + + + + + ~/Applications/xenia/xenia.exe + ~/.local/share/applications/xenia/xenia.exe + ~/.local/bin/xenia/xenia.exe + ~/bin/xenia/xenia.exe + ~/Applications/xenia/xenia_canary.exe + ~/.local/share/applications/xenia/xenia_canary.exe + ~/.local/bin/xenia/xenia_canary.exe + ~/bin/xenia/xenia_canary.exe + + + + + + xroar + + + ~/Applications/xroar/xroar + ~/.local/share/applications/xroar/xroar + ~/.local/bin/xroar/xroar + ~/bin/xroar/xroar + + + + + + yuzu + org.yuzu_emu.yuzu + + + ~/Applications/yuzu*.AppImage + ~/.local/share/applications/yuzu*.AppImage + ~/.local/bin/yuzu*.AppImage + ~/bin/yuzu*.AppImage + /var/lib/flatpak/exports/bin/org.yuzu_emu.yuzu + ~/.local/share/flatpak/exports/bin/org.yuzu_emu.yuzu + + + + + + zesarux + + + ~/Applications/ZEsarUX/zesarux + ~/.local/share/applications/ZEsarUX/zesarux + ~/.local/bin/ZEsarUX/zesarux + ~/bin/ZEsarUX/zesarux + + + \ No newline at end of file diff --git a/resources/systems/linux/es_systems.xml b/resources/systems/linux/es_systems.xml new file mode 100644 index 000000000..c1085ec31 --- /dev/null +++ b/resources/systems/linux/es_systems.xml @@ -0,0 +1,2258 @@ + + + + + 3do + 3DO Interactive Multiplayer + %ROMPATH%/3do + .bin .BIN .chd .CHD .cue .CUE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/opera_libretro.so %ROM% + 3do + 3do + + + adam + Coleco Adam + %ROMPATH%/adam + .1dd .1DD .bin .BIN .col .COL .cqi .CQI .cqm .CQM .d77 .D77 .d88 .D88 .ddp .DDP .dfi .DFI .dsk .DSK .hfe .HFE .imd .IMD .mfi .MFI .mfm .MFM .rom .ROM .td0 .TD0 .wav .WAV .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/adam adam -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/adam adam -cass1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/adam adam -cart1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/adam adam %BASENAME% + adam + adam + + + ags + Adventure Game Studio Game Engine + %ROMPATH%/ags + .desktop .sh + %STARTDIR%=%GAMEDIR% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pcwindows + ags + + + amiga + Commodore Amiga + %ROMPATH%/amiga + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae2021_libretro.so %ROM% + %EMULATOR_FS-UAE% %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_AMIBERRY% --autoload %ROM% + amiga + amiga + + + amiga1200 + Commodore Amiga 1200 + %ROMPATH%/amiga1200 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae2021_libretro.so %ROM% + %EMULATOR_FS-UAE% %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_AMIBERRY% --autoload %ROM% + amiga + amiga1200 + + + amiga600 + Commodore Amiga 600 + %ROMPATH%/amiga600 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae2021_libretro.so %ROM% + %EMULATOR_FS-UAE% %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_AMIBERRY% --autoload %ROM% + amiga + amiga600 + + + amigacd32 + Commodore Amiga CD32 + %ROMPATH%/amigacd32 + .adf .ADF .adz .ADZ .ccd .CCD .chd .CHD .cue .CUE .dms .DMS .fdi .FDI .hdf .HDF .hdz .HDZ .ipf .IPF .iso .ISO .lha .LHA .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .uae .UAE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae2021_libretro.so %ROM% + %EMULATOR_FS-UAE% --config:amiga-model=CD32 %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_AMIBERRY% --model CD32 --autoload %ROM% + amigacd32 + amigacd32 + + + amstradcpc + Amstrad CPC + %ROMPATH%/amstradcpc + .cdt .CDT .cpr .CPR .dsk .DSK .kcr .KCR .m3u .M3U .sna .SNA .tap .TAR .voc .VOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/cap32_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/crocods_libretro.so %ROM% + %STARTDIR%=~/.CPCemu %EMULATOR_CPCEMU% %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/amstradcpc cpc6128 -flop1 %ROM% + amstradcpc + amstradcpc + + + android + Google Android + %ROMPATH%/android + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + android + android + + + apple2 + Apple II + %ROMPATH%/apple2 + .do .DO .dsk .DSK .nib .NIB .po .PO + %EMULATOR_LINAPPLE% -f -b --d1 %ROM% + %EMULATOR_MEDNAFEN% -force_module apple2 %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "apple2e -rompath \"%GAMEDIRRAW%;%ROMPATH%/apple2\" -flop1 \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/apple2 apple2e -flop1 %ROM% + apple2 + apple2 + + + apple2gs + Apple IIGS + %ROMPATH%/apple2gs + .2mg .2MG .7z .7z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "apple2gs -rompath \"%GAMEDIRRAW%;%ROMPATH%/apple2gs\" -flop3 \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/apple2gs apple2gs -flop3 %ROM% + apple2gs + apple2gs + + + arcade + Arcade + %ROMPATH%/arcade + .cmd .CMD .desktop .sh .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/arcade %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_SUPERMODEL% -log-output=%GAMEDIR%/Config/Supermodel.log %INJECT%=%BASENAME%.commands %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + arcade + arcade + + + arcadia + Emerson Arcadia 2001 + %ROMPATH%/arcadia + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "arcadia -rompath \"%GAMEDIRRAW%;%ROMPATH%/arcadia\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/arcadia arcadia -cart %ROM% + arcadia + arcadia + + + archimedes + Acorn Archimedes + %ROMPATH%/archimedes + .1dd .1DD .360 .adf .ADF .adl .ADL .adm .ADM .ads .ADS .apd .APD .bbc .BBC .chd .CHD .cqi .CQI .cqm .CQM .d77 .D77 .d88 .D88 .dfi .DFI .dsd .DSD .dsk .DSK .hfe .HFE .ima .IMA .imd .IMD .img .IMG .ipf .IPF .jfd .JFD .mfi .MFI .mfm .MFM .msa .MSA .ssd .SSD .st .ST .td0 .TD0 .ufi .UFI .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/archimedes aa4401 -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/archimedes aa3000 -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/archimedes aa310 -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/archimedes aa540 -flop1 %ROM% + archimedes + archimedes + + + arduboy + Arduboy Miniature Game System + %ROMPATH%/arduboy + .hex .HEX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/arduous_libretro.so %ROM% + arduboy + arduboy + + + astrocde + Bally Astrocade + %ROMPATH%/astrocde + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "astrocde -rompath \"%GAMEDIRRAW%;%ROMPATH%/astrocde\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/astrocde astrocde -cart %BASENAME% + astrocde + astrocade + + + atari2600 + Atari 2600 + %ROMPATH%/atari2600 + .a26 .A26 .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/stella_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/stella2014_libretro.so %ROM% + %EMULATOR_STELLA% %ROM% + %EMULATOR_GOPHER2600% %ROM% + %EMULATOR_ARES% --fullscreen --system "Atari 2600" %ROM% + atari2600 + atari2600 + + + atari5200 + Atari 5200 + %ROMPATH%/atari5200 + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .car .CAR .cas .CAS .cdm .CDM .rom .ROM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/a5200_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/atari800_libretro.so %ROM% + %EMULATOR_ATARI800% %ROM% + atari5200 + atari5200 + + + atari7800 + Atari 7800 ProSystem + %ROMPATH%/atari7800 + .a78 .A78 .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/prosystem_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "a7800 -rompath \"%GAMEDIRRAW%;%ROMPATH%/atari7800\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/atari7800 a7800 -cart %ROM% + atari7800 + atari7800 + + + atari800 + Atari 800 + %ROMPATH%/atari800 + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .car .CAR .cas .CAS .cdm .CDM .rom .ROM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/atari800_libretro.so %ROM% + %EMULATOR_ATARI800% %ROM% + atari800 + atari800 + + + atarijaguar + Atari Jaguar + %ROMPATH%/atarijaguar + .abs .ABS .bin .BIN .cdi .CDI .cof .COF .cue .CUE .j64 .J64 .jag .JAG .prg .PRG .rom .ROM .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/virtualjaguar_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/atarijaguar jaguar -cart %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_BIGPEMU-WINDOWS% %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_BIGPEMU-WINDOWS% %ROM% + atarijaguar + atarijaguar + + + atarijaguarcd + Atari Jaguar CD + %ROMPATH%/atarijaguarcd + .abs .ABS .bin .BIN .cdi .CDI .cof .COF .cue .CUE .j64 .J64 .jag .JAG .prg .PRG .rom .ROM .7z .7Z .zip .ZIP + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_BIGPEMU-WINDOWS% %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_BIGPEMU-WINDOWS% %ROM% + atarijaguarcd + atarijaguarcd + + + atarilynx + Atari Lynx + %ROMPATH%/atarilynx + .lnx .LNX .o .O .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/handy_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_lynx_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module lynx %ROM% + atarilynx + atarilynx + + + atarist + Atari ST + %ROMPATH%/atarist + .st .ST .msa .MSA .stx .STX .dim .DIM .ipf .IPF .m3u .M3U .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/hatari_libretro.so %ROM% + %EMULATOR_HATARI% %ROM% + atarist + atarist + + + atarixe + Atari XE + %ROMPATH%/atarixe + .a52 .A52 .atr .ATR .atx .ATX .bin .BIN .cas .CAS .cdm .CDM .xex .XEX .xfd .XFD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/atari800_libretro.so %ROM% + %EMULATOR_ATARI800% %ROM% + atarixe + atarixe + + + atomiswave + Sammy Corporation Atomiswave + %ROMPATH%/atomiswave + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + arcade + atomiswave + + + bbcmicro + Acorn Computers BBC Micro + %ROMPATH%/bbcmicro + .dsd .DSD .img .IMG .ssd .SSD .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/bbcmicro bbcb -autoboot_delay "2" -autoboot_command "*cat\n\n*exec !boot\n" -flop1 %ROM% + bbcmicro + bbcmicro + + + c64 + Commodore 64 + %ROMPATH%/c64 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_x64sc_libretro.so %ROM% + %EMULATOR_VICE-X64SC% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_x64_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_xscpu64_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_x128_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/frodo_libretro.so %ROM% + c64 + c64 + + + cdimono1 + Philips CD-i + %ROMPATH%/cdimono1 + .chd .CHD .cue .CUE .iso .ISO + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/same_cdi_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/cdi2015_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/cdimono1 cdimono1 -cdrom %ROM% + cdimono1 + cdimono1 + + + cdtv + Commodore CDTV + %ROMPATH%/cdtv + .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .nrg .NRG .rp9 .RP9 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/puae2021_libretro.so %ROM% + %EMULATOR_FS-UAE% --config:amiga-model=CDTV %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_AMIBERRY% --model CDTV --autoload %ROM% + cdtv + cdtv + + + chailove + ChaiLove Game Engine + %ROMPATH%/chailove + .chai .CHAI .chailove .CHAILOVE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/chailove_libretro.so %ROM% + love + chailove + + + channelf + Fairchild Channel F + %ROMPATH%/channelf + .bin .BIN .chf .CHF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/freechaf_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "channelf -rompath \"%GAMEDIRRAW%;%ROMPATH%/channelf\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/channelf channelf -cart %ROM% + channelf + channelf + + + coco + Tandy Color Computer + %ROMPATH%/coco + .cas .CAS .ccc .CCC .dsk .DSK .rom .ROM + %EMULATOR_XROAR% -fs -default-machine coco2bus %ROM% + %EMULATOR_XROAR% -fs -default-machine coco2b %ROM% + coco + coco + + + colecovision + Coleco ColecoVision + %ROMPATH%/colecovision + .bin .BIN .cas .CAS .col .COL .cv .CV .dsk .DSK .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ri .RI .rom .ROM .sc .SC .sg .SG .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearcoleco_libretro.so %ROM% + %EMULATOR_OPENMSX% -machine ColecoVision_SGM %INJECT%=%BASENAME%.commands -cart %ROM% + %EMULATOR_ARES% --fullscreen --system "ColecoVision" %ROM% + colecovision + colecovision + + + consolearcade + Console Arcade Systems + %ROMPATH%/consolearcade + .arcadedef .desktop .iso .ISO .sh .xbe .XBE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/consolearcade %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module ss %ROM% + %EMULATOR_PLAY!% --disc %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_TRIFORCE% -b -e %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_XEMU% -dvd_path %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + arcade + consolearcade + + + cps + Capcom Play System + %ROMPATH%/cps + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/cps %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps1_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps2_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps3_libretro.so %ROM% + arcade + cps + + + cps1 + Capcom Play System I + %ROMPATH%/cps1 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/cps1 %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps1_libretro.so %ROM% + arcade + cps1 + + + cps2 + Capcom Play System II + %ROMPATH%/cps2 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/cps2 %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps2_libretro.so %ROM% + arcade + cps2 + + + cps3 + Capcom Play System III + %ROMPATH%/cps3 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/cps3 %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps3_libretro.so %ROM% + arcade + cps3 + + + crvision + VTech CreatiVision + %ROMPATH%/crvision + .bin .BIN .rom .ROM .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "crvision -rompath \"%GAMEDIRRAW%;%ROMPATH%/crvision\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/crvision crvision -cart %ROM% + crvision + crvision + + + daphne + Daphne Arcade LaserDisc Emulator + %ROMPATH%/daphne + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP + %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands + %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/daphne %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dirksimple_libretro.so %ROM% + daphne, arcade + daphne + + + desktop + Desktop Applications + %ROMPATH%/desktop + .AppImage .desktop .sh + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" + pcwindows + desktop + + + doom + Doom + %ROMPATH%/doom + .desktop .ipk3 .IPK3 .iwad .IWAD .pk3 .PK3 .pk4 .PK4 .pwad .PWAD .sh .wad .WAD + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/prboom_libretro.so %ROM% + %EMULATOR_PRBOOM-PLUS% -iwad %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/boom3_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/boom3_xp_libretro.so %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pc, pcwindows + doom + + + dos + DOS (PC) + %ROMPATH%/dos + .bat .BAT .com .COM .conf .CONF .cue .CUE .dosz .DOSZ .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-STAGING% %ROM% + dos + dos + + + dragon32 + Dragon Data Dragon 32 + %ROMPATH%/dragon32 + .cas .CAS .ccc .CCC .dsk .DSK .rom .ROM + %EMULATOR_XROAR% -fs -default-machine dragon32 %ROM% + %EMULATOR_XROAR% -fs -default-machine dragon64 %ROM% + dragon32 + dragon32 + + + dreamcast + Sega Dreamcast + %ROMPATH%/dreamcast + .cdi .CDI .chd .CHD .cue .CUE .dat .DAT .elf .ELF .gdi .GDI .iso .ISO .lst .LST .m3u .M3U .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + %EMULATOR_REDREAM% %ROM% + dreamcast + dreamcast + + + easyrpg + EasyRPG Game Engine + %ROMPATH%/easyrpg + .easyrpg .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/easyrpg_libretro.so %ROM% + %STARTDIR%=%GAMEENTRYDIR% %EMULATOR_EASYRPG% + easyrpg + easyrpg + + + electron + Acorn Electron + %ROMPATH%/electron + .1dd .1DD .adf .ADF .adl .ADL .adm .ADM .ads .ADS .bbc .BBC .bin .BIN .cqi .CQI .cqm .CQM .csw .CSW .d77 .D77 .d88 .D88 .dfi .DFI .dsd .DSD .dsk .DSK .hfe .HFE .imd .IMD .img .IMG .mfi .MFI .mfm .MFM .rom .ROM .ssd .SSD .td0 .TD0 .uef .UEF .wav .WAV .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/electron electron64 -autoboot_delay "2" -autoboot_command "*T.\nCH.\"\"\n" -cass1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/electron electron64 -exp plus1 -cart1 seds -autoboot_delay "2" -autoboot_command "*CAT\n\n\n\n\n\n*EXEC !BOOT\n" -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/electron electron64 -exp plus3 -exp:plus3:fdc:1 35dd -autoboot_delay "2" -autoboot_command "*CAT\n\n\n\n\n\n*RUN !BOOT\n" -flop1 %ROM% + electron + electron + + + emulators + Emulators + %ROMPATH%/emulators + .AppImage .desktop .sh + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" + pcwindows + emulators + + + epic + Epic Games Store + %ROMPATH%/epic + .desktop .sh + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pcwindows + epic + + + famicom + Nintendo Family Computer + %ROMPATH%/famicom + .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nestopia_libretro.so %ROM% + %EMULATOR_NESTOPIA-UE% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fceumm_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/quicknes_libretro.so %ROM% + %EMULATOR_PUNES% -u yes %ROM% + %EMULATOR_MEDNAFEN% -force_module nes %ROM% + %EMULATOR_ARES% --fullscreen --system "Famicom" %ROM% + %EMULATOR_ARES% --fullscreen --system "Famicom Disk System" %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen + famicom + famicom + + + fba + FinalBurn Alpha + %ROMPATH%/fba + .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_neogeo_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps1_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps2_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_cps3_libretro.so %ROM% + arcade + fba + + + fbneo + FinalBurn Neo + %ROMPATH%/fbneo + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + arcade + fbneo + + + fds + Nintendo Famicom Disk System + %ROMPATH%/fds + .nes .NES .fds .FDS .unf .UNF .UNIF .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nestopia_libretro.so %ROM% + %EMULATOR_NESTOPIA-UE% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fceumm_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module nes %ROM% + %EMULATOR_ARES% --fullscreen --system "Famicom Disk System" %ROM% + fds + fds + + + flash + Adobe Flash + %ROMPATH%/flash + .swf .SWF + %EMULATOR_RUFFLE% --fullscreen %ROM% + %EMULATOR_LIGHTSPARK% --fullscreen %ROM% + flash + flash + + + fm7 + Fujitsu FM-7 + %ROMPATH%/fm7 + .1dd .1DD .cqi .CQI .cqm .CQM .d77 .D77 .d88 .D88 .dfi .DFI .dsk .DSK .hfe .HFE .imd .IMD .mfi .MFI .mfm .MFM .t77 .T77 .td0 .TD0 .wav .WAV .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm7 -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm7 -autoboot_delay "5" -autoboot_command "load\n\n\nrun\n" -cass1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm7 %BASENAME% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm77av -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm77av -autoboot_delay "5" -autoboot_command "load\n\n\nrun\n" -cass1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fm7 fm77av %BASENAME% + fm7 + fm7 + + + fmtowns + Fujitsu FM Towns + %ROMPATH%/fmtowns + .cdr .CDR .chd .CHD .cue .CUE .gdi .GDI .iso .ISO + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "fmtownshr -rompath \"%GAMEDIRRAW%;%ROMPATH%/fmtowns\" -cdrom \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/fmtowns fmtownshr -cdrom %ROM% + %EMULATOR_TSUGARU% %EMUDIR%/roms -HOSTSHORTCUT ESC 0 0 FORCEQUIT -FULLSCREEN -CD %ROM% %INJECT%=%BASENAME%.cfg + fmtowns + fmtowns + + + fpinball + Future Pinball + %ROMPATH%/fpinball + .fpt .FPT + PLACEHOLDER %ROM% + fpinball + fpinball + + + gamate + Bit Corporation Gamate + %ROMPATH%/gamate + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "gamate -rompath \"%GAMEDIRRAW%;%ROMPATH%/gamate\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gamate gamate -cart %ROM% + gamate + gamate + + + gameandwatch + Nintendo Game and Watch + %ROMPATH%/gameandwatch + .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/gameandwatch/artwork -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.so %ROM% + gameandwatch + gameandwatch + + + gamecom + Tiger Electronics Game.com + %ROMPATH%/gamecom + .tgc .TGC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "gamecom -rompath \"%GAMEDIRRAW%;%ROMPATH%/gamecom\" -cartridge1 \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gamecom gamecom -cartridge1 %ROM% + gamecom + gamecom + + + gamegear + Sega Game Gear + %ROMPATH%/gamegear + .68k .68K .bin .BIN .bms .BMS .chd .CHD .col .COL .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/smsplus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module gg %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "Game Gear" %ROM% + gamegear + gamegear + + + gb + Nintendo Game Boy + %ROMPATH%/gb + .bs .BS .cgb .CGB .dmg .DMG .gb .GB .gbc .GBC .sgb .SGB .sfc .SFC .smc .SMC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gambatte_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/sameboy_libretro.so %ROM% + %EMULATOR_SAMEBOY% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearboy_libretro.so %ROM% + %EMULATOR_GEARBOY% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tgbdual_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/DoubleCherryGB_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mgba_libretro.so %ROM% + %EMULATOR_MGBA% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vbam_libretro.so %ROM% + %EMULATOR_VBA-M% -f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% + %EMULATOR_ARES% --fullscreen --system "Game Boy" %ROM% + %EMULATOR_SKYEMU% %ROM% + gb + gb + + + gba + Nintendo Game Boy Advance + %ROMPATH%/gba + .agb .AGB .bin .BIN .cgb .CGB .dmg .DMG .gb .GB .gba .GBA .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mgba_libretro.so %ROM% + %EMULATOR_MGBA% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vbam_libretro.so %ROM% + %EMULATOR_VBA-M% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vba_next_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gpsp_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module gba %ROM% + %EMULATOR_ARES% --fullscreen --system "Game Boy Advance" %ROM% + %EMULATOR_SKYEMU% %ROM% + gba + gba + + + gbc + Nintendo Game Boy Color + %ROMPATH%/gbc + .bs .BS .cgb .CGB .dmg .DMG .gb .GB .gbc .GBC .sgb .SGB .sfc .SFC .smc .SMC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gambatte_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/sameboy_libretro.so %ROM% + %EMULATOR_SAMEBOY% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearboy_libretro.so %ROM% + %EMULATOR_GEARBOY% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tgbdual_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/DoubleCherryGB_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mgba_libretro.so %ROM% + %EMULATOR_MGBA% -f %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vbam_libretro.so %ROM% + %EMULATOR_VBA-M% -f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% + %EMULATOR_ARES% --fullscreen --system "Game Boy Color" %ROM% + %EMULATOR_SKYEMU% %ROM% + gbc + gbc + + + gc + Nintendo GameCube + %ROMPATH%/gc + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dolphin_libretro.so %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_DOLPHIN% -b -e %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_PRIMEHACK% -b -e %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_TRIFORCE% -b -e %ROM% + gc + gc + + + genesis + Sega Genesis + %ROMPATH%/genesis + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/blastem_libretro.so %ROM% + %EMULATOR_BLASTEM% -m gen %ROM% + %EMULATOR_MEDNAFEN% -force_module md %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega Drive" %ROM% + genesis + genesis + + + gmaster + Hartung Game Master + %ROMPATH%/gmaster + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "gmaster -rompath \"%GAMEDIRRAW%;%ROMPATH%/gmaster\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gmaster gmaster -cart %ROM% + gmaster + gmaster + + + gx4000 + Amstrad GX4000 + %ROMPATH%/gx4000 + .bin .BIN .cdt .CDT .cpr .CPR .dsk .DSK .kcr .KCR .m3u .M3U .sna .SNA .tap .TAR .voc .VOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/cap32_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/crocods_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gx4000 gx4000 -cart %ROM% + gx4000 + gx4000 + + + intellivision + Mattel Electronics Intellivision + %ROMPATH%/intellivision + .bin .BIN .int .INT .rom .ROM .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/freeintv_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "intv -rompath \"%GAMEDIRRAW%;%ROMPATH%/intellivision\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/intellivision intv -cart %ROM% + intellivision + intellivision + + + j2me + Java 2 Micro Edition (J2ME) + %ROMPATH%/j2me + .jar .JAR .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/squirreljme_libretro.so %ROM% + android + j2me + + + kodi + Kodi Home Theatre Software + %ROMPATH%/kodi + .desktop .sh + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pcwindows + kodi + + + laserdisc + LaserDisc Games + %ROMPATH%/laserdisc + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP + %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands + %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/laserdisc %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dirksimple_libretro.so %ROM% + daphne, arcade + laserdisc + + + lcdgames + LCD Handheld Games + %ROMPATH%/lcdgames + .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/lcdgames/artwork -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.so %ROM% + lcdgames, gameandwatch + lcdgames + + + lowresnx + LowRes NX Fantasy Console + %ROMPATH%/lowresnx + .nx .NX + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/lowresnx_libretro.so %ROM% + lowresnx + lowresnx + + + lutris + Lutris Open Gaming Platform + %ROMPATH%/lutris + .desktop .sh + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pc, pcwindows + lutris + + + lutro + Lutro Game Engine + %ROMPATH%/lutro + .lua .LUA .lutro .LUTRO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/lutro_libretro.so %ROM% + lutro + lutro + + + macintosh + Apple Macintosh + %ROMPATH%/macintosh + .dsk .DSK .game .GAME + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/macintosh macse -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/macintosh macse -flop1 %GAMEDIR%/boot.dsk -flop2 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/macintosh macplus -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/macintosh macplus -flop1 %GAMEDIR%/boot.dsk -flop2 %ROM% + %EMULATOR_BASILISKII% --nogui true + %EMULATOR_SHEEPSHAVER% --nogui true + macintosh + macintosh + + + mame + Multiple Arcade Machine Emulator + %ROMPATH%/mame + .cmd .CMD .desktop .sh .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2010_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2003_plus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame2000_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/mame %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbalpha2012_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_SUPERMODEL% -log-output=%GAMEDIR%/Config/Supermodel.log %INJECT%=%BASENAME%.commands %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + arcade + mame + + + mame-advmame + AdvanceMAME + %ROMPATH%/mame-advmame + .7z .7Z .zip .ZIP + %STARTDIR%=~/.advance %EMULATOR_ADVANCEMAME% %BASENAME% + arcade + mame-advmame + + + mastersystem + Sega Master System + %ROMPATH%/mastersystem + .68k .68K .bin .BIN .bms .BMS .chd .CHD .col .COL .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/smsplus_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module sms %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "Master System" %ROM% + mastersystem + mastersystem + + + megacd + Sega Mega-CD + %ROMPATH%/megacd + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega CD" %ROM% + segacd + megacd + + + megacdjp + Sega Mega-CD + %ROMPATH%/megacdjp + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega CD" %ROM% + segacd + megacdjp + + + megadrive + Sega Mega Drive + %ROMPATH%/megadrive + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/blastem_libretro.so %ROM% + %EMULATOR_BLASTEM% -m gen %ROM% + %EMULATOR_MEDNAFEN% -force_module md %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega Drive" %ROM% + megadrive + megadrive + + + megadrivejp + Sega Mega Drive + %ROMPATH%/megadrivejp + .32x .32X .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/blastem_libretro.so %ROM% + %EMULATOR_BLASTEM% -m gen %ROM% + %EMULATOR_MEDNAFEN% -force_module md %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega Drive" %ROM% + megadrive + megadrivejp + + + megaduck + Creatronic Mega Duck + %ROMPATH%/megaduck + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/sameduck_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "megaduck -rompath \"%GAMEDIRRAW%;%ROMPATH%/megaduck\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/megaduck megaduck -cart %ROM% + megaduck + megaduck + + + mess + Multi Emulator Super System + %ROMPATH%/mess + .chd .CHD .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mess2015_libretro.so %ROM% + mess + mess + + + model2 + Sega Model 2 + %ROMPATH%/model2 + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/model2 %BASENAME% + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_M2EMULATOR-WINDOWS% %BASENAME% + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_M2EMULATOR-WINDOWS% %BASENAME% + arcade + model2 + + + model3 + Sega Model 3 + %ROMPATH%/model3 + .7z .7Z .zip .ZIP + %STARTDIR%=%GAMEDIR% %EMULATOR_SUPERMODEL% -log-output=%GAMEDIR%/Config/Supermodel.log %INJECT%=%BASENAME%.commands %ROM% + arcade + model3 + + + moto + Thomson MO/TO Series + %ROMPATH%/moto + .fd .FD .k7 .K7 .m5 .M5 .m7 .M7 .rom .ROM .sap .SAP .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/theodore_libretro.so %ROM% + moto + moto + + + msx + MSX + %ROMPATH%/msx + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fmsx_libretro.so %ROM% + %EMULATOR_OPENMSX% -machine National_CF-3300 %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_OPENMSX% %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_ARES% --fullscreen --system "MSX" %ROM% + msx + msx + + + msx1 + MSX1 + %ROMPATH%/msx1 + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fmsx_libretro.so %ROM% + %EMULATOR_OPENMSX% -machine National_CF-3300 %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_OPENMSX% %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_ARES% --fullscreen --system "MSX" %ROM% + msx + msx1 + + + msx2 + MSX2 + %ROMPATH%/msx2 + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fmsx_libretro.so %ROM% + %EMULATOR_OPENMSX% -machine Panasonic_FS-A1WSX %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_OPENMSX% %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_ARES% --fullscreen --system "MSX2" %ROM% + msx2 + msx2 + + + msxturbor + MSX Turbo R + %ROMPATH%/msxturbor + .cas .CAS .col .COL .di1 .DI1 .di2 .DI2 .dmk .DMK .dsk .DSK .fd1 .FD1 .fd2 .FD2 .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ogv .OGV .ri .RI .rom .ROM .sc .SC .sg .SG .wav .WAV .xsa .XSA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_OPENMSX% -machine Panasonic_FS-A1GT %INJECT%=%BASENAME%.commands %ROM% + %EMULATOR_OPENMSX% %INJECT%=%BASENAME%.commands %ROM% + msxturbor + msxturbor + + + mugen + M.U.G.E.N Game Engine + %ROMPATH%/mugen + .mugen + %STARTDIR%=%GAMEDIR% %EMULATOR_OS-SHELL% -c "%ROM%" + mugen + mugen + + + multivision + Othello Multivision + %ROMPATH%/multivision + .bin .BIN .gg .GG .rom .ROM .sg .SG .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + sg-1000 + multivision + + + n3ds + Nintendo 3DS + %ROMPATH%/n3ds + .3ds .3DS .3dsx .3DSX .app .APP .axf .AXF .cci .CCI .cxi .CXI .elf .ELF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/citra_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/citra2018_libretro.so %ROM% + %EMULATOR_CITRA% %ROM% + n3ds + n3ds + + + n64 + Nintendo 64 + %ROMPATH%/n64 + .bin .BIN .d64 .D64 .n64 .N64 .ndd .NDD .u1 .U1 .v64 .V64 .z64 .Z64 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mupen64plus_next_libretro.so %ROM% + %EMULATOR_MUPEN64PLUS% --nogui %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.so %ROM% + %EMULATOR_SIMPLE64% --nogui %ROM% + %EMULATOR_ROSALIES-MUPEN-GUI% --nogui -q %ROM% + %EMULATOR_ARES% --fullscreen --system "Nintendo 64" %ROM% + n64 + n64 + + + n64dd + Nintendo 64DD + %ROMPATH%/n64dd + .bin .BIN .d64 .D64 .n64 .N64 .ndd .NDD .u1 .U1 .v64 .V64 .z64 .Z64 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/parallel_n64_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mupen64plus_next_libretro.so %ROM% + %EMULATOR_ROSALIES-MUPEN-GUI% --nogui -q %ROM% + %EMULATOR_ARES% --fullscreen --system "Nintendo 64DD" %ROM% + n64 + n64dd + + + naomi + Sega NAOMI + %ROMPATH%/naomi + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + arcade + naomi + + + naomi2 + Sega NAOMI 2 + %ROMPATH%/naomi2 + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + arcade + naomi2 + + + naomigd + Sega NAOMI GD-ROM + %ROMPATH%/naomigd + .bin .BIN .dat .DAT .elf .ELF .lst .LST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/flycast_libretro.so %ROM% + %EMULATOR_FLYCAST% %ROM% + %EMULATOR_FLYCAST-DOJO% %ROM% + arcade + naomigd + + + nds + Nintendo DS + %ROMPATH%/nds + .app .APP .bin .BIN .nds .NDS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melondsds_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melonds_libretro.so %ROM% + %EMULATOR_MELONDS% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume2015_libretro.so %ROM% + %EMULATOR_DESMUME% %ROM% + %EMULATOR_SKYEMU% %ROM% + nds + nds + + + neogeo + SNK Neo Geo + %ROMPATH%/neogeo + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% -fullscreen %BASENAME% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/neogeo %BASENAME% + neogeo + neogeo + + + neogeocd + SNK Neo Geo CD + %ROMPATH%/neogeocd + .chd .CHD .cue .CUE + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/neocd_libretro.so %ROM% + %EMULATOR_RETROARCH% --subsystem neocd -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% neocdz -fullscreen -cd %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/neogeocd neocdz -cdrm %ROM% + neogeocd + neogeocd + + + neogeocdjp + SNK Neo Geo CD + %ROMPATH%/neogeocdjp + .chd .CHD .cue .CUE + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/neocd_libretro.so %ROM% + %EMULATOR_RETROARCH% --subsystem neocd -L %CORE_RETROARCH%/fbneo_libretro.so %ROM% + %EMULATOR_FINALBURN-NEO% neocdz -fullscreen -cd %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/neogeocdjp neocdz -cdrm %ROM% + neogeocd + neogeocdjp + + + nes + Nintendo Entertainment System + %ROMPATH%/nes + .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nestopia_libretro.so %ROM% + %EMULATOR_NESTOPIA-UE% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fceumm_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/quicknes_libretro.so %ROM% + %EMULATOR_PUNES% -u yes %ROM% + %EMULATOR_MEDNAFEN% -force_module nes %ROM% + %EMULATOR_ARES% --fullscreen --system "Famicom" %ROM% + %EMULATOR_ARES% --fullscreen --system "Famicom Disk System" %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen + nes + nes + + + ngage + Nokia N-Gage + %ROMPATH%/ngage + .ngage .zip .ZIP + %EMULATOR_EKA2L1% --fullscreen --device RH-29 --mount %ROM% --run "%BASENAME%" + %EMULATOR_EKA2L1% --fullscreen --device RH-29 --run "%BASENAME%" + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_EKA2L1-WINDOWS% --fullscreen --device RH-29 --mount %ROM% --run "%BASENAME%" + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_EKA2L1-WINDOWS% --fullscreen --device RH-29 --run "%BASENAME%" + ngage + ngage + + + ngp + SNK Neo Geo Pocket + %ROMPATH%/ngp + .ngc .NGC .ngp .NGP .ngpc .NGPC .npc .NPC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_ngp_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/race_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module ngp %ROM% + %EMULATOR_ARES% --fullscreen --system "Neo Geo Pocket" %ROM% + ngp + ngp + + + ngpc + SNK Neo Geo Pocket Color + %ROMPATH%/ngpc + .ngc .NGC .ngp .NGP .ngpc .NGPC .npc .NPC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_ngp_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/race_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module ngp %ROM% + %EMULATOR_ARES% --fullscreen --system "Neo Geo Pocket Color" %ROM% + ngpc + ngpc + + + odyssey2 + Magnavox Odyssey 2 + %ROMPATH%/odyssey2 + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/o2em_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "odyssey2 -rompath \"%GAMEDIRRAW%;%ROMPATH%/odyssey2\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/odyssey2 odyssey2 -cart %ROM% + odyssey2 + odyssey2 + + + openbor + OpenBOR Game Engine + %ROMPATH%/openbor + .AppImage + %STARTDIR%=%GAMEDIR% %EMULATOR_OS-SHELL% -c "%ROM%" + openbor + openbor + + + oric + Tangerine Computer Systems Oric + %ROMPATH%/oric + .dsk .DSK .ort .ORT .tap .TAP .wav .WAV + %STARTDIR%=%EMUDIR% %EMULATOR_ORICUTRON% %ROM% + oric + oric + + + palm + Palm OS + %ROMPATH%/palm + .img .IMG .pqa .PQA .prc .PRC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mu_libretro.so %ROM% + palm + palm + + + pc + IBM PC + %ROMPATH%/pc + .bat .BAT .com .COM .conf .CONF .cue .CUE .dosz .DOSZ .exe .EXE .iso .ISO .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_core_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_svn_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-STAGING% %ROM% + pc + pc + + + pc88 + NEC PC-8800 Series + %ROMPATH%/pc88 + .88d .88D .cmt .CMT .d88 .D88 .m3u .M3U .t88 .T88 .u88 .U88 + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/quasi88_libretro.so %ROM% + %EMULATOR_QUASI88% -romdir ~/.quasi88 %ROM% + pc88 + pc88 + + + pc98 + NEC PC-9800 Series + %ROMPATH%/pc98 + .2hd .2HD .88d .88D .98d .98D .d88 .D88 .d98 .D98 .cmd .CMD .dup .DUP .fdd .FDD .fdi .FDI .hdd .HDD .hdi .HDI .hdm .HDM .hdn .HDN .m3u .M3U .nhd .NHD .tfd .TFD .thd .THD .xdf .XDF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/np2kai_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nekop2_libretro.so %ROM% + pc98 + pc98 + + + pcarcade + PC Arcade Systems + %ROMPATH%/pcarcade + .AppImage .desktop .exe .EXE .sh + %STARTDIR%=%GAMEDIR% %EMULATOR_WINE% %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_PROTON% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + arcade + pcarcade + + + pcengine + NEC PC Engine + %ROMPATH%/pcengine + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_fast_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "PC Engine" %ROM% + pcengine + pcengine + + + pcenginecd + NEC PC Engine CD + %ROMPATH%/pcenginecd + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_fast_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "PC Engine CD" %ROM% + pcenginecd + pcenginecd + + + pcfx + NEC PC-FX + %ROMPATH%/pcfx + .ccd .CCD .chd .CHD .cue CUE .m3u .M3U .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pcfx_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pcfx %ROM% + pcfx + pcfx + + + pico8 + PICO-8 Fantasy Console + %ROMPATH%/pico8 + .p8 .P8 .png .PNG + %EMULATOR_PICO-8% -root_path %GAMEDIR% -run %ROM% + %EMULATOR_PICO-8% -root_path %GAMEDIR% -splore + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/retro8_libretro.so %ROM% + pico8 + pico8 + + + plus4 + Commodore Plus/4 + %ROMPATH%/plus4 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_xplus4_libretro.so %ROM% + %EMULATOR_VICE-XPLUS4% %ROM% + plus4 + plus4 + + + pokemini + Nintendo Pokémon Mini + %ROMPATH%/pokemini + .min .MIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pokemini_libretro.so %ROM% + pokemini + pokemini + + + ports + Ports + %ROMPATH%/ports + .AppImage .desktop .exe .EXE .game .GAME .phd .PHD .psx .PSX .sh + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/ecwolf_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nxengine_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/openlara_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/superbroswar_libretro.so %ROM% + pc, pcwindows + ports + + + ps2 + Sony PlayStation 2 + %ROMPATH%/ps2 + .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG .zso .ZSO + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pcsx2_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pcsx2_libretro.so %ROM% + %EMULATOR_PCSX2% -batch %ROM% + %EMULATOR_PCSX2-LEGACY% --nogui %ROM% + %EMULATOR_PLAY!% --disc %ROM% + ps2 + ps2 + + + ps3 + Sony PlayStation 3 + %ROMPATH%/ps3 + .desktop .ps3 .PS3 .ps3dir .PS3DIR + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_RPCS3% --no-gui %ROM% + ps3 + ps3 + + + ps4 + Sony PlayStation 4 + %ROMPATH%/ps4 + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% + ps4 + ps4 + + + psp + Sony PlayStation Portable + %ROMPATH%/psp + .chd .CHD .cso .CSO .elf .ELF .iso .ISO .pbp .PBP .prx .PRX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/ppsspp_libretro.so %ROM% + %EMULATOR_PPSSPP% %ROM% + psp + psp + + + psvita + Sony PlayStation Vita + %ROMPATH%/psvita + .psvita + %EMULATOR_VITA3K% -r %INJECT%=%BASENAME%.psvita + psvita + psvita + + + psx + Sony PlayStation + %ROMPATH%/psx + .bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_psx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_psx_hw_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pcsx_rearmed_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/swanstation_libretro.so %ROM% + %EMULATOR_DUCKSTATION% -batch %ROM% + %EMULATOR_MEDNAFEN% -force_module psx %ROM% + psx + psx + + + pv1000 + Casio PV-1000 + %ROMPATH%/pv1000 + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "pv1000 -rompath \"%GAMEDIRRAW%;%ROMPATH%/pv1000\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/pv1000 pv1000 -cart %ROM% + pv1000 + pv1000 + + + quake + Quake + %ROMPATH%/quake + .desktop .pak .PAK .pk3 .PK3 .sh + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tyrquake_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vitaquake2_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vitaquake2-rogue_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vitaquake2-xatrix_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vitaquake2-zaero_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vitaquake3_libretro.so %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + pc, pcwindows + quake + + + samcoupe + MGT SAM Coupé + %ROMPATH%/samcoupe + .dsk .DSK .mgt .MGT .sad .SAD .sbt .SBT .7z .7Z .zip .ZIP + %EMULATOR_SIMCOUPE% %ROM% + samcoupe + samcoupe + + + satellaview + Nintendo Satellaview + %ROMPATH%/satellaview + .bml .BML .bs .BS .fig .FIG .sfc .SFC .smc .SMC .swc .SWC .st .ST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_SNES9X% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_hd_beta_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_BSNES% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "Super Famicom" %ROM% + satellaview + satellaview + + + saturn + Sega Saturn + %ROMPATH%/saturn + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_saturn_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/yabasanshiro_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/yabause_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module ss %ROM% + saturn + saturn + + + saturnjp + Sega Saturn + %ROMPATH%/saturnjp + .bin .BIN .ccd .CCD .chd .CHD .cue .CUE .iso .ISO .m3u .M3U .mds .MDS .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_saturn_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/yabasanshiro_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/yabause_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module ss %ROM% + saturn + saturnjp + + + scummvm + ScummVM Game Engine + %ROMPATH%/scummvm + .scummvm .SCUMMVM .svm .SVM + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/scummvm_libretro.so %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_SCUMMVM% %BASENAME% + scummvm + scummvm + + + scv + Epoch Super Cassette Vision + %ROMPATH%/scv + .0 .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "scv -rompath \"%GAMEDIRRAW%;%ROMPATH%/scv\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/scv scv -cart %ROM% + scv + scv + + + sega32x + Sega Mega Drive 32X + %ROMPATH%/sega32x + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega 32X" %ROM% + sega32x + sega32x + + + sega32xjp + Sega Super 32X + %ROMPATH%/sega32xjp + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega 32X" %ROM% + sega32x + sega32xjp + + + sega32xna + Sega Genesis 32X + %ROMPATH%/sega32xna + .32x .32X .68k .68K .bin .BIN .cue .CUE .gen .GEN .iso .ISO .md .MD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega 32X" %ROM% + sega32x + sega32xna + + + segacd + Sega CD + %ROMPATH%/segacd + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% + %EMULATOR_ARES% --fullscreen --system "Mega CD" %ROM% + segacd + segacd + + + sfc + Nintendo SFC (Super Famicom) + %ROMPATH%/sfc + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_SNES9X% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_hd_beta_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_BSNES% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_MEDNAFEN% -force_module snes %ROM% + %EMULATOR_ARES% --fullscreen --system "Super Famicom" %ROM% + snes + sfc + + + sg-1000 + Sega SG-1000 + %ROMPATH%/sg-1000 + .68k .68K .bin .BIN .bms .BMS .chd .CHD .cue .CUE .gen .GEN .gg .GG .iso .ISO .m3u .M3U .md .MD .mdx .MDX .ri .RI .rom .ROM .sg .SG .sgd .SGD .smd .SMD .sms .SMS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "SG-1000" %ROM% + sg-1000 + sg-1000 + + + sgb + Nintendo Super Game Boy + %ROMPATH%/sgb + .gb .GB .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen --gameBoy.useSgb2=true %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/sameboy_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mgba_libretro.so %ROM% + %EMULATOR_MGBA% -f %ROM% + sgb + sgb + + + snes + Nintendo SNES (Super Nintendo) + %ROMPATH%/snes + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_SNES9X% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_hd_beta_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_BSNES% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_MEDNAFEN% -force_module snes %ROM% + %EMULATOR_ARES% --fullscreen --system "Super Famicom" %ROM% + snes + snes + + + snesna + Nintendo SNES (Super Nintendo) + %ROMPATH%/snesna + .bin .BIN .bml .BML .bs .BS .bsx .BSX .dx2 .DX2 .fig .FIG .gd3 .GD3 .gd7 .GD7 .mgd .MGD .sfc .SFC .smc .SMC .st .ST .swc .SWC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_SNES9X% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_hd_beta_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_BSNES% --fullscreen %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supafaust_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_MEDNAFEN% -force_module snes %ROM% + %EMULATOR_ARES% --fullscreen --system "Super Famicom" %ROM% + snes + snesna + + + solarus + Solarus Game Engine + %ROMPATH%/solarus + .solarus + %EMULATOR_SOLARUS% %ROM% + solarus + solarus + + + spectravideo + Spectravideo + %ROMPATH%/spectravideo + .cas .CAS .col .COL .dsk .DSK .m3u .M3U .mx1 .MX1 .mx2 .MX2 .ri .RI .rom .ROM .sc .SC .sg .SG .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + spectravideo + spectravideo + + + steam + Valve Steam + %ROMPATH%/steam + .desktop .sh + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + steam + steam + + + stv + Sega Titan Video Game System + %ROMPATH%/stv + .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/stv %BASENAME% + %EMULATOR_MEDNAFEN% -force_module ss %ROM% + arcade + stv + + + sufami + Bandai SuFami Turbo + %ROMPATH%/sufami + .bml .BML .bs .BS .fig .FIG .sfc .SFC .smc .SMC .st .ST .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/snes9x2010_libretro.so %ROM% + %EMULATOR_SNES9X% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_hd_beta_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_mercury_accuracy_libretro.so %ROM% + %EMULATOR_BSNES% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "Super Famicom" %ROM% + sufami + sufami + + + supergrafx + NEC SuperGrafx + %ROMPATH%/supergrafx + .ccd .CCD .chd .CHD .cue .CUE .pce .PCE .sgx .SGX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supergrafx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "SuperGrafx" %ROM% + supergrafx + supergrafx + + + supervision + Watara Supervision + %ROMPATH%/supervision + .bin .BIN .sv .SV .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/potator_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "svision -rompath \"%GAMEDIRRAW%;%ROMPATH%/supervision\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/supervision svision -cart %ROM% + supervision + supervision + + + supracan + Funtech Super A'Can + %ROMPATH%/supracan + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "supracan -rompath \"%GAMEDIRRAW%;%ROMPATH%/supracan\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/supracan supracan -cart %ROM% + supracan + supracan + + + switch + Nintendo Switch + %ROMPATH%/switch + .nca .NCA .nro .NRO .nso .NSO .nsp .NSP .xci .XCI + %INJECT%=%BASENAME%.esprefix %EMULATOR_YUZU% -f -g %ROM% + %EMULATOR_RYUJINX% %ROM% + switch + switch + + + symbian + Symbian + %ROMPATH%/symbian + .sis .SIS .sisx .SISX .symbian + %EMULATOR_EKA2L1% --fullscreen --device RH-29 --run "%BASENAME%" + %EMULATOR_EKA2L1% --fullscreen --device RM-84 --run "%BASENAME%" + %EMULATOR_EKA2L1% --fullscreen --device RM-507 --run "%BASENAME%" + %EMULATOR_EKA2L1% --fullscreen --device %INJECT%=%BASENAME%.device --run "%BASENAME%" + ngage + symbian + + + tanodragon + Tano Dragon + %ROMPATH%/tanodragon + .cas .CAS .ccc .CCC .dsk .DSK .rom .ROM + %EMULATOR_XROAR% -fs -default-machine tano %ROM% + dragon32 + tanodragon + + + tg16 + NEC TurboGrafx-16 + %ROMPATH%/tg16 + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_fast_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "PC Engine" %ROM% + pcengine + tg16 + + + tg-cd + NEC TurboGrafx-CD + %ROMPATH%/tg-cd + .ccd .CCD .chd .CHD .cue .CUE .img .IMG .iso .ISO .m3u .M3U .pce .PCE .sgx .SGX .toc .TOC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_fast_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_ARES% --fullscreen --system "PC Engine CD" %ROM% + pcenginecd + tg-cd + + + ti99 + Texas Instruments TI-99 + %ROMPATH%/ti99 + .rpk .RPK .7z .7Z .zip .ZIP + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/ti99 ti99_4a -ioport peb -ioport:peb:slot3 speech -cart %BASENAME% + ti99 + ti99 + + + tic80 + TIC-80 Fantasy Computer + %ROMPATH%/tic80 + .tic .TIC + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tic80_libretro.so %ROM% + %EMULATOR_TIC-80% %ROM% --fullscreen + tic80 + tic80 + + + to8 + Thomson TO8 + %ROMPATH%/to8 + .fd .FD .k7 .K7 .m5 .M5 .m7 .M7 .rom .ROM .sap .SAP .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/theodore_libretro.so %ROM% + moto + to8 + + + triforce + Namco-Sega-Nintendo Triforce + %ROMPATH%/triforce + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %INJECT%=%BASENAME%.esprefix %EMULATOR_TRIFORCE% -b -e %ROM% + arcade + triforce + + + trs-80 + Tandy TRS-80 + %ROMPATH%/trs-80 + .cmd .CMD .dsk .DSK + %STARTDIR%=%GAMEDIR% %EMULATOR_SDL2TRS% -rom %ROMPATH%/trs-80/level2.rom -disk0 %ROMPATH%/trs-80/boot.dsk -disk1 %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_SDL2TRS% -rom %ROMPATH%/trs-80/level2.rom -disk0 %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_SDL2TRS% -rom %ROMPATH%/trs-80/level2.rom %ROM% + trs-80 + trs-80 + + + type-x + Taito Type X + %ROMPATH%/type-x + .AppImage .desktop .exe .EXE .sh + %STARTDIR%=%GAMEDIR% %EMULATOR_WINE% %ROM% + %STARTDIR%=%GAMEDIR% %EMULATOR_PROTON% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + arcade + type-x + + + uzebox + Uzebox Open Source Console + %ROMPATH%/uzebox + .uze .UZE .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/uzem_libretro.so %ROM% + uzebox + uzebox + + + vectrex + GCE Vectrex + %ROMPATH%/vectrex + .bin .BIN .gam .GAM .vc .VC .vec .VEC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vecx_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "vectrex -rompath \"%GAMEDIRRAW%;%ROMPATH%/vectrex\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/vectrex vectrex -cart %ROM% + vectrex + vectrex + + + vic20 + Commodore VIC-20 + %ROMPATH%/vic20 + .bin .BIN .cmd .CMD .crt .CRT .d2m .D2M .d4m .D4M .d64 .D64 .d6z .D6Z .d71 .D71 .d7z .D7Z .d80 .D80 .d81 .D81 .d82 .D82 .d8z .D8Z .g41 .G41 .g4z .G4Z .g64 .G64 .g6z .G6Z .gz .GZ .lnx .LNX .m3u .M3U .nbz .NBZ .nib .NIB .p00 .P00 .prg .PRG .t64 .T64 .tap .TAP .vfl .VFL .vsf .VSF .x64 .X64 .x6z .X6Z .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vice_xvic_libretro.so %ROM% + %EMULATOR_VICE-XVIC% %ROM% + vic20 + vic20 + + + videopac + Philips Videopac G7000 + %ROMPATH%/videopac + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/o2em_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "videopac -rompath \"%GAMEDIRRAW%;%ROMPATH%/videopac\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/videopac videopac -cart %ROM% + odyssey2 + videopac + + + virtualboy + Nintendo Virtual Boy + %ROMPATH%/virtualboy + .bin .BIN .vb .VB .vboy .VBOY .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_vb_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module vb %ROM% + virtualboy + virtualboy + + + vpinball + Visual Pinball + %ROMPATH%/vpinball + .vpt .VPT .vpx .VPX + %EMULATOR_VISUAL-PINBALL% -play %ROM% + vpinball + vpinball + + + vsmile + VTech V.Smile + %ROMPATH%/vsmile + .bin .BIN .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so "vsmile -rompath \"%GAMEDIRRAW%;%ROMPATH%/vsmile\" -cart \"%ROMRAW%\"" + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/vsmile vsmile -cart %ROM% + vsmile + vsmile + + + wasm4 + WASM-4 Fantasy Console + %ROMPATH%/wasm4 + .wasm .WASM + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/wasm4_libretro.so %ROM% + wasm4 + wasm4 + + + wii + Nintendo Wii + %ROMPATH%/wii + .ciso .CISO .dff .DFF .dol .DOL .elf .ELF .gcm .GCM .gcz .GCZ .iso .ISO .json .JSON .m3u .M3U .rvz .RVZ .tgc .TGC .wad .WAD .wbfs .WBFS .wia .WIA .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dolphin_libretro.so %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_DOLPHIN% -b -e %ROM% + %INJECT%=%BASENAME%.esprefix %EMULATOR_PRIMEHACK% -b -e %ROM% + wii + wii + + + wiiu + Nintendo Wii U + %ROMPATH%/wiiu + .rpx .RPX .wua .WUA .wud .WUD .wux .WUX + %EMULATOR_CEMU% -g %ROM% + wiiu + wiiu + + + windows + Microsoft Windows + %ROMPATH%/windows + .AppImage .desktop .sh + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" + pcwindows + windows + + + windows3x + Microsoft Windows 3.x + %ROMPATH%/windows3x + .AppImage .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% -defaultdir %GAMEDIR% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" + windows3x + windows3x + + + windows9x + Microsoft Windows 9x + %ROMPATH%/windows9x + .AppImage .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP + %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% -defaultdir %GAMEDIR% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + %EMULATOR_OS-SHELL% -c "%ROM%" + %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" + pcwindows + windows9x + + + wonderswan + Bandai WonderSwan + %ROMPATH%/wonderswan + .pc2 .PC2 .ws .WS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_wswan_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module wswan %ROM% + %EMULATOR_ARES% --fullscreen --system "WonderSwan" %ROM% + %EMULATOR_ARES% --fullscreen --system "Pocket Challenge V2" %ROM% + wonderswan + wonderswan + + + wonderswancolor + Bandai WonderSwan Color + %ROMPATH%/wonderswancolor + .pc2 .PC2 .ws .WS .wsc .WSC .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_wswan_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module wswan %ROM% + %EMULATOR_ARES% --fullscreen --system "WonderSwan Color" %ROM% + wonderswancolor + wonderswancolor + + + x1 + Sharp X1 + %ROMPATH%/x1 + .2d .2D .2hd .2HD .88d .88D .cmd .CMD .d88 .D88 .dup .DUP .dx1 .DX1 .hdm .HDM .tap .TAP .tfd .TFD .xdf .XDF .7z .7Z .zip .ZIP + %STARTDIR%=%GAMEDIR% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/x1_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/x1 x1 -flop1 %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/x1 x1 -cass1 %ROM% + x1 + x1 + + + x68000 + Sharp X68000 + %ROMPATH%/x68000 + .2hd .2HD .88d .88D .cmd .CMD .d88 .D88 .dim .DIM .dup .DUP .hdf .HDF .hdm .HDM .img .IMG .m3u .M3U .xdf .XDF .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/px68k_libretro.so %ROM% + %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/x68000 x68000 -flop1 %ROM% + x68000 + x68000 + + + xbox + Microsoft Xbox + %ROMPATH%/xbox + .iso .ISO + %INJECT%=%BASENAME%.esprefix %EMULATOR_XEMU% -dvd_path %ROM% + xbox + xbox + + + xbox360 + Microsoft Xbox 360 + %ROMPATH%/xbox360 + . .desktop .iso .ISO .sh .xex .XEX .zar .ZAR + %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% + %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_XENIA-WINDOWS% %ROM% + %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + xbox360 + xbox360 + + + zmachine + Infocom Z-machine + %ROMPATH%/zmachine + .dat .DAT .z1 .Z1 .z2 .Z2 .z3 .Z3 .z4 .Z4 .z5 .Z5 .z6 .Z6 .z7 .Z7 .z8 .Z8 .zlb .ZLB .zblorb .ZBLORB + %EMULATOR_GARGOYLE% %ROM% + zmachine + zmachine + + + zx81 + Sinclair ZX81 + %ROMPATH%/zx81 + .p .P .tzx .TZX .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/81_libretro.so %ROM% + zx81 + zx81 + + + zxnext + Sinclair ZX Spectrum Next + %ROMPATH%/zxnext + .nex .NEX .sna .SNA + %STARTDIR%=%GAMEDIR% MONO_IOMAP=all mono %EMULATOR_CSPECT% -fullscreen -s28 -vsync -60 -analytics -tv -zxnext -mmc=./ %ROM% + %STARTDIR%=%EMUDIR% %EMULATOR_ZESARUX% --machine tbblue --realvideo --enabletimexvideo --tbblue-fast-boot-mode --enable-esxdos-handler --esxdos-root-dir %GAMEDIR% %ROM% + zxnext + zxnext + + + zxspectrum + Sinclair ZX Spectrum + %ROMPATH%/zxspectrum + .dsk .DSK .gz .GZ .img .IMG .mgt .MGT .rzx .RZX .scl .SCL .sh .SH .sna .SNA .szx .SZX .tap .TAP .trd .TRD .tzx .TZX .udi .UDI .z80 .Z80 .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/fuse_libretro.so %ROM% + %EMULATOR_FUSE% %ROM% + zxspectrum + zxspectrum + + \ No newline at end of file diff --git a/resources/systems/macos/es_find_rules.xml b/resources/systems/macos/es_find_rules.xml index 8d967f405..e380cd234 100644 --- a/resources/systems/macos/es_find_rules.xml +++ b/resources/systems/macos/es_find_rules.xml @@ -370,6 +370,12 @@ /usr/local/bin/xvic + + + + /Applications/VPinballX_GL.app/Contents/MacOS/VPinballX_GL + + diff --git a/resources/systems/macos/es_systems.xml b/resources/systems/macos/es_systems.xml index 8c23370da..7a4be3963 100644 --- a/resources/systems/macos/es_systems.xml +++ b/resources/systems/macos/es_systems.xml @@ -472,7 +472,7 @@ daphne Daphne Arcade LaserDisc Emulator %ROMPATH%/daphne - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.dylib %ROM% @@ -684,6 +684,7 @@ Nintendo Game and Watch %ROMPATH%/gameandwatch .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.dylib %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/gameandwatch/artwork -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.dylib %ROM% @@ -731,6 +732,7 @@ %EMULATOR_MGBA% -f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vbam_libretro.dylib %ROM% %EMULATOR_VBA-M% -f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy" %ROM% %EMULATOR_SKYEMU% %ROM% gb @@ -747,6 +749,7 @@ %EMULATOR_VBA-M% -f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vba_next_libretro.dylib %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gpsp_libretro.dylib %ROM% + %EMULATOR_MEDNAFEN% -force_module gba %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy Advance" %ROM% %EMULATOR_SKYEMU% %ROM% gba @@ -768,6 +771,7 @@ %EMULATOR_MGBA% -f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/vbam_libretro.dylib %ROM% %EMULATOR_VBA-M% -f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy Color" %ROM% %EMULATOR_SKYEMU% %ROM% gbc @@ -851,7 +855,7 @@ laserdisc LaserDisc Games %ROMPATH%/laserdisc - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.dylib %ROM% @@ -865,6 +869,7 @@ LCD Handheld Games %ROMPATH%/lcdgames .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.dylib %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/lcdgames/artwork -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.dylib %ROM% @@ -1196,6 +1201,7 @@ .app .APP .bin .BIN .nds .NDS .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume_libretro.dylib %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume2015_libretro.dylib %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melondsds_libretro.dylib %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melonds_libretro.dylib %ROM% %EMULATOR_MELONDS% %ROM% %EMULATOR_SKYEMU% %ROM% @@ -1443,7 +1449,7 @@ ps2 Sony PlayStation 2 %ROMPATH%/ps2 - .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG + .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG .zso .ZSO %EMULATOR_PCSX2% -batch %ROM% %EMULATOR_PCSX2% --nogui %ROM% %EMULATOR_AETHERSX2% -batch %ROM% @@ -1772,6 +1778,7 @@ .ccd .CCD .chd .CHD .cue .CUE .pce .PCE .sgx .SGX .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supergrafx_libretro.dylib %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.dylib %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% %EMULATOR_ARES% --fullscreen --system "SuperGrafx" %ROM% supergrafx supergrafx @@ -1962,7 +1969,7 @@ Visual Pinball %ROMPATH%/vpinball .vpt .VPT .vpx .VPX - PLACEHOLDER %ROM% + %EMULATOR_VISUAL-PINBALL% -play %ROM% vpinball vpinball
diff --git a/resources/systems/unix/es_find_rules.xml b/resources/systems/unix/es_find_rules.xml index f6848a30d..9c657e59a 100644 --- a/resources/systems/unix/es_find_rules.xml +++ b/resources/systems/unix/es_find_rules.xml @@ -1,5 +1,5 @@ - + @@ -11,51 +11,18 @@ retroarch - org.libretro.RetroArch - - - ~/Applications/RetroArch-Linux*.AppImage - ~/.local/share/applications/RetroArch-Linux*.AppImage - ~/.local/bin/RetroArch-Linux*.AppImage - ~/bin/RetroArch-Linux*.AppImage - /var/lib/flatpak/exports/bin/org.libretro.RetroArch - ~/.local/share/flatpak/exports/bin/org.libretro.RetroArch - + ~/.config/retroarch/cores - - ~/Applications/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores - ~/.local/share/applications/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores - ~/.local/bin/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores - ~/bin/RetroArch-Linux-x86_64.AppImage.home/.config/retroarch/cores - - ~/.var/app/org.libretro.RetroArch/config/retroarch/cores - - ~/snap/retroarch/current/.config/retroarch/cores - - /usr/lib/x86_64-linux-gnu/libretro - - /usr/lib64/libretro - - /usr/lib/libretro /usr/local/lib/libretro /usr/pkg/lib/libretro - - - - ~/Applications/3dSen/3dSen.exe - ~/.local/share/applications/3dSen/3dSen.exe - ~/.local/bin/3dSen/3dSen.exe - ~/bin/3dSen/3dSen.exe - - @@ -84,64 +51,30 @@ ares - dev.ares.ares - - - /var/lib/flatpak/exports/bin/dev.ares.ares - ~/.local/share/flatpak/exports/bin/dev.ares.ares atari800 - atari800-jz.atari800 BasiliskII - net.cebix.basilisk - - - ~/Applications/BasiliskII*.AppImage - ~/.local/share/applications/BasiliskII*.AppImage - ~/.local/bin/BasiliskII*.AppImage - ~/bin/BasiliskII*.AppImage - /var/lib/flatpak/exports/bin/net.cebix.basilisk - ~/.local/share/flatpak/exports/bin/net.cebix.basilisk - - - - - - ~/Applications/BigPEmu/BigPEmu.exe - ~/.local/share/applications/BigPEmu/BigPEmu.exe - ~/.local/bin/BigPEmu/BigPEmu.exe - ~/bin/BigPEmu/BigPEmu.exe blastem - com.retrodev.blastem - - - /var/lib/flatpak/exports/bin/com.retrodev.blastem - ~/.local/share/flatpak/exports/bin/com.retrodev.blastem bsnes - dev.bsnes.bsnes - - - /var/lib/flatpak/exports/bin/dev.bsnes.bsnes - ~/.local/share/flatpak/exports/bin/dev.bsnes.bsnes @@ -151,34 +84,16 @@ Cemu - ~/Applications/Cemu*.AppImage - ~/.local/share/applications/Cemu*.AppImage - ~/.local/bin/Cemu*.AppImage - ~/bin/Cemu*.AppImage ~/Applications/Cemu/Cemu ~/.local/share/applications/Cemu/Cemu ~/.local/bin/Cemu/Cemu ~/bin/Cemu/Cemu - /var/lib/flatpak/exports/bin/info.cemu.Cemu - ~/.local/share/flatpak/exports/bin/info.cemu.Cemu citra - citra-emu.citra-nightly - org.citra_emu.citra - - - ~/Applications/citra-qt*.AppImage - ~/.local/share/applications/citra-qt*.AppImage - ~/.local/bin/citra-qt*.AppImage - ~/bin/citra-qt*.AppImage - ~/.citra/canary/citra-qt.AppImage - ~/.citra/nightly/citra-qt.AppImage - /var/lib/flatpak/exports/bin/org.citra_emu.citra - ~/.local/share/flatpak/exports/bin/org.citra_emu.citra @@ -202,62 +117,28 @@ ~/bin/CSpect/CSpect.exe - - - - ~/Applications/demul/demul.exe - ~/.local/share/applications/demul/demul.exe - ~/.local/bin/demul/demul.exe - ~/bin/demul/demul.exe - - desmume - org.desmume.DeSmuME - - - /var/lib/flatpak/exports/bin/org.desmume.DeSmuME - ~/.local/share/flatpak/exports/bin/org.desmume.DeSmuME dolphin-emu - dolphin-emulator.dolphin-emu - org.DolphinEmu.dolphin-emu - - - ~/Applications/Dolphin_Emulator*.AppImage - ~/.local/share/applications/Dolphin_Emulator*.AppImage - ~/.local/bin/Dolphin_Emulator*.AppImage - ~/bin/Dolphin_Emulator*.AppImage - /var/lib/flatpak/exports/bin/org.DolphinEmu.dolphin-emu - ~/.local/share/flatpak/exports/bin/org.DolphinEmu.dolphin-emu dosbox-staging - io.github.dosbox-staging - - - /var/lib/flatpak/exports/bin/io.github.dosbox-staging - ~/.local/share/flatpak/exports/bin/io.github.dosbox-staging dosbox-x - com.dosbox_x.DOSBox-X - - - /var/lib/flatpak/exports/bin/com.dosbox_x.DOSBox-X - ~/.local/share/flatpak/exports/bin/com.dosbox_x.DOSBox-X @@ -265,23 +146,6 @@ duckstation-nogui duckstation-qt - org.duckstation.DuckStation - - - ~/Applications/DuckStation*.AppImage - ~/.local/share/applications/DuckStation*.AppImage - ~/.local/bin/DuckStation*.AppImage - ~/bin/DuckStation*.AppImage - ~/Applications/duckstation-nogui*.AppImage - ~/.local/share/applications/duckstation-nogui*.AppImage - ~/.local/bin/duckstation-nogui*.AppImage - ~/bin/duckstation-nogui*.AppImage - ~/Applications/duckstation-qt*.AppImage - ~/.local/share/applications/duckstation-qt*.AppImage - ~/.local/bin/duckstation-qt*.AppImage - ~/bin/duckstation-qt*.AppImage - /var/lib/flatpak/exports/bin/org.duckstation.DuckStation - ~/.local/share/flatpak/exports/bin/org.duckstation.DuckStation @@ -301,21 +165,6 @@ eka2l1_qt - - ~/Applications/EKA2L1*.AppImage - ~/.local/share/applications/EKA2L1*.AppImage - ~/.local/bin/EKA2L1*.AppImage - ~/bin/EKA2L1*.AppImage - - - - - - ~/Applications/EKA2L1/eka2l1_qt.exe - ~/.local/share/applications/EKA2L1/eka2l1_qt.exe - ~/.local/bin/EKA2L1/eka2l1_qt.exe - ~/bin/EKA2L1/eka2l1_qt.exe - @@ -333,15 +182,6 @@ flycast - org.flycast.Flycast - - - ~/Applications/flycast-x86*.AppImage - ~/.local/share/applications/flycast-x86*.AppImage - ~/.local/bin/flycast-x86*.AppImage - ~/bin/flycast-x86*.AppImage - /var/lib/flatpak/exports/bin/org.flycast.Flycast - ~/.local/share/flatpak/exports/bin/org.flycast.Flycast @@ -349,12 +189,6 @@ flycast-dojo - - ~/Applications/flycast-dojo*.AppImage - ~/.local/share/applications/flycast-dojo*.AppImage - ~/.local/bin/flycast-dojo*.AppImage - ~/bin/flycast-dojo*.AppImage - @@ -362,35 +196,17 @@ fs-uae-launcher fsuae.launcher - - /var/lib/flatpak/exports/bin/net.fsuae.FS-UAE|flatpak run --command=fs-uae-launcher net.fsuae.FS-UAE - ~/.local/share/flatpak/exports/bin/net.fsuae.FS-UAE|flatpak run --command=fs-uae-launcher net.fsuae.FS-UAE - fuse - net.sf.fuse_emulator - - - /var/lib/flatpak/exports/bin/net.sf.fuse_emulator - ~/.local/share/flatpak/exports/bin/net.sf.fuse_emulator gargoyle - io.github.garglk.Gargoyle - - - ~/Applications/Gargoyle*.AppImage - ~/.local/share/applications/Gargoyle*.AppImage - ~/.local/bin/Gargoyle*.AppImage - ~/bin/Gargoyle*.AppImage - /var/lib/flatpak/exports/bin/io.github.garglk.Gargoyle - ~/.local/share/flatpak/exports/bin/io.github.garglk.Gargoyle @@ -405,24 +221,10 @@ ~/bin/gearboy/gearboy - - - - ~/Applications/gopher2600/gopher2600_linux_amd64 - ~/.local/share/applications/gopher2600/gopher2600_linux_amd64 - ~/.local/bin/gopher2600/gopher2600_linux_amd64 - ~/bin/gopher2600/gopher2600_linux_amd64 - - hatari - org.tuxfamily.hatari - - - /var/lib/flatpak/exports/bin/org.tuxfamily.hatari - ~/.local/share/flatpak/exports/bin/org.tuxfamily.hatari @@ -461,24 +263,10 @@ ~/bin/linapple/linapple - - - - ~/Applications/m2emulator/EMULATOR.EXE - ~/.local/share/applications/m2emulator/EMULATOR.EXE - ~/.local/bin/m2emulator/EMULATOR.EXE - ~/bin/m2emulator/EMULATOR.EXE - - mame - org.mamedev.MAME - - - /var/lib/flatpak/exports/bin/org.mamedev.MAME - ~/.local/share/flatpak/exports/bin/org.mamedev.MAME @@ -486,21 +274,12 @@ mednafen - - /var/lib/flatpak/exports/bin/com.github.AmatCoder.mednaffe|flatpak run --command=mednafen com.github.AmatCoder.mednaffe - ~/.local/share/flatpak/exports/bin/com.github.AmatCoder.mednaffe|flatpak run --command=mednafen com.github.AmatCoder.mednaffe - melonds melonDS - net.kuribo64.melonDS - - - /var/lib/flatpak/exports/bin/net.kuribo64.melonDS - ~/.local/share/flatpak/exports/bin/net.kuribo64.melonDS @@ -508,60 +287,30 @@ mesen2 - - ~/Applications/Mesen*.AppImage - ~/.local/share/applications/Mesen*.AppImage - ~/.local/bin/Mesen*.AppImage - ~/bin/Mesen*.AppImage - mgba mgba-qt - io.mgba.mGBA - - - ~/Applications/mGBA*.AppImage - ~/.local/share/applications/mGBA*.AppImage - ~/.local/bin/mGBA*.AppImage - ~/bin/mGBA*.AppImage - /var/lib/flatpak/exports/bin/io.mgba.mGBA - ~/.local/share/flatpak/exports/bin/io.mgba.mGBA m64p - io.github.m64p.m64p - - - /var/lib/flatpak/exports/bin/io.github.m64p.m64p - ~/.local/share/flatpak/exports/bin/io.github.m64p.m64p nestopia - ca._0ldsk00l.Nestopia - - - /var/lib/flatpak/exports/bin/ca._0ldsk00l.Nestopia - ~/.local/share/flatpak/exports/bin/ca._0ldsk00l.Nestopia openmsx - org.openmsx.openMSX - - - /var/lib/flatpak/exports/bin/org.openmsx.openMSX - ~/.local/share/flatpak/exports/bin/org.openmsx.openMSX @@ -580,27 +329,7 @@ pcsx2-qt - net.pcsx2.PCSX2 - - - ~/Applications/pcsx2*.AppImage - ~/.local/share/applications/pcsx2*.AppImage - ~/.local/bin/pcsx2*.AppImage - ~/bin/pcsx2*.AppImage - /var/lib/flatpak/exports/bin/net.pcsx2.PCSX2 - ~/.local/share/flatpak/exports/bin/net.pcsx2.PCSX2 - - - - - - PCSX2 pcsx2 - net.pcsx2.PCSX2 - - - /var/lib/flatpak/exports/bin/net.pcsx2.PCSX2 - ~/.local/share/flatpak/exports/bin/net.pcsx2.PCSX2 @@ -615,31 +344,12 @@ ~/bin/pico-8/pico8 - - - - org.purei.Play - - - ~/Applications/Play!*.AppImage - ~/.local/share/applications/Play!*.AppImage - ~/.local/bin/Play!*.AppImage - ~/bin/Play!*.AppImage - /var/lib/flatpak/exports/bin/org.purei.Play - ~/.local/share/flatpak/exports/bin/org.purei.Play - - ppsspp-emu.ppsspp-sdl PPSSPPSDL PPSSPPQt - org.ppsspp.PPSSPP - - - /var/lib/flatpak/exports/bin/org.ppsspp.PPSSPP - ~/.local/share/flatpak/exports/bin/org.ppsspp.PPSSPP @@ -652,20 +362,6 @@ primehack - io.github.shiiion.primehack - - - /var/lib/flatpak/exports/bin/io.github.shiiion.primehack - ~/.local/share/flatpak/exports/bin/io.github.shiiion.primehack - - - - - - ~/Applications/Proton/wine*.AppImage - ~/.local/share/applications/Proton/wine*.AppImage - ~/.local/bin/Proton/wine*.AppImage - ~/bin/Proton/wine*.AppImage @@ -708,31 +404,12 @@ RMG - com.github.Rosalie241.RMG - - - ~/Applications/RMG*.AppImage - ~/.local/share/applications/RMG*.AppImage - ~/.local/bin/RMG*.AppImage - ~/bin/RMG*.AppImage - /var/lib/flatpak/exports/bin/com.github.Rosalie241.RMG - ~/.local/share/flatpak/exports/bin/com.github.Rosalie241.RMG rpcs3 - rpcs3-emu.rpcs3 - net.rpcs3.RPCS3 - - - ~/Applications/rpcs3*.AppImage - ~/.local/share/applications/rpcs3*.AppImage - ~/.local/bin/rpcs3*.AppImage - ~/bin/rpcs3*.AppImage - /var/lib/flatpak/exports/bin/net.rpcs3.RPCS3 - ~/.local/share/flatpak/exports/bin/net.rpcs3.RPCS3 @@ -752,11 +429,8 @@ Ryujinx Ryujinx.Ava - org.ryujinx.Ryujinx - /var/lib/flatpak/exports/bin/org.ryujinx.Ryujinx - ~/.local/share/flatpak/exports/bin/org.ryujinx.Ryujinx ~/Applications/publish/Ryujinx ~/.local/share/applications/publish/Ryujinx ~/.local/bin/publish/Ryujinx @@ -771,22 +445,12 @@ sameboy - io.github.sameboy.SameBoy - - - /var/lib/flatpak/exports/bin/io.github.sameboy.SameBoy - ~/.local/share/flatpak/exports/bin/io.github.sameboy.SameBoy scummvm - org.scummvm.ScummVM - - - /var/lib/flatpak/exports/bin/org.scummvm.ScummVM - ~/.local/share/flatpak/exports/bin/org.scummvm.ScummVM @@ -806,12 +470,6 @@ SheepShaver - - ~/Applications/SheepShaver*.AppImage - ~/.local/share/applications/SheepShaver*.AppImage - ~/.local/bin/SheepShaver*.AppImage - ~/bin/SheepShaver*.AppImage - @@ -829,11 +487,6 @@ simple64-gui - io.github.simple64.simple64 - - - /var/lib/flatpak/exports/bin/io.github.simple64.simple64 - ~/.local/share/flatpak/exports/bin/io.github.simple64.simple64 @@ -853,15 +506,6 @@ snes9x snes9x-gtk - com.snes9x.Snes9x - - - ~/Applications/Snes9x*.AppImage - ~/.local/share/applications/Snes9x*.AppImage - ~/.local/bin/Snes9x*.AppImage - ~/bin/Snes9x*.AppImage - /var/lib/flatpak/exports/bin/com.snes9x.Snes9x - ~/.local/share/flatpak/exports/bin/com.snes9x.Snes9x @@ -870,10 +514,6 @@ solarus-run solarus.run - - /var/lib/flatpak/exports/bin/org.solarus_games.solarus.Launcher|flatpak run --command=solarus-run org.solarus_games.solarus.Launcher - ~/.local/share/flatpak/exports/bin/org.solarus_games.solarus.Launcher|flatpak run --command=solarus-run org.solarus_games.solarus.Launcher - @@ -885,11 +525,6 @@ stella - io.github.stella_emu.Stella - - - /var/lib/flatpak/exports/bin/io.github.stella_emu.Stella - ~/.local/share/flatpak/exports/bin/io.github.stella_emu.Stella @@ -902,19 +537,12 @@ ~/.local/share/applications/Supermodel/supermodel ~/.local/bin/Supermodel/supermodel ~/bin/Supermodel/supermodel - /var/lib/flatpak/exports/bin/com.supermodel3.Supermodel - ~/.local/share/flatpak/exports/bin/com.supermodel3.Supermodel tic80 - com.tic80.TIC_80 - - - /var/lib/flatpak/exports/bin/com.tic80.TIC_80 - ~/.local/share/flatpak/exports/bin/com.tic80.TIC_80 @@ -922,12 +550,6 @@ dolphin-emu-triforce - - ~/Applications/dolphin-emu-triforce*.AppImage - ~/.local/share/applications/dolphin-emu-triforce*.AppImage - ~/.local/bin/dolphin-emu-triforce*.AppImage - ~/bin/dolphin-emu-triforce*.AppImage - @@ -948,34 +570,18 @@ x64sc - vice-jz.x64sc - net.sf.VICE - - - /var/lib/flatpak/exports/bin/net.sf.VICE - ~/.local/share/flatpak/exports/bin/net.sf.VICE xplus4 - vice-jz.xplus4 - - - /var/lib/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xplus4 net.sf.VICE - ~/.local/share/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xplus4 net.sf.VICE xvic - vice-jz.xvic - - - /var/lib/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xvic net.sf.VICE - ~/.local/share/flatpak/exports/bin/net.sf.VICE|flatpak run --command=xvic net.sf.VICE @@ -1007,37 +613,6 @@ xemu - app.xemu.xemu - - - ~/Applications/xemu*.AppImage - ~/.local/share/applications/xemu*.AppImage - ~/.local/bin/xemu*.AppImage - ~/bin/xemu*.AppImage - /var/lib/flatpak/exports/bin/app.xemu.xemu - ~/.local/share/flatpak/exports/bin/app.xemu.xemu - - - - - - ~/Applications/Wine/wine*.AppImage - ~/.local/share/applications/Wine/wine*.AppImage - ~/.local/bin/Wine/wine*.AppImage - ~/bin/Wine/wine*.AppImage - - - - - - ~/Applications/xenia/xenia.exe - ~/.local/share/applications/xenia/xenia.exe - ~/.local/bin/xenia/xenia.exe - ~/bin/xenia/xenia.exe - ~/Applications/xenia/xenia_canary.exe - ~/.local/share/applications/xenia/xenia_canary.exe - ~/.local/bin/xenia/xenia_canary.exe - ~/bin/xenia/xenia_canary.exe @@ -1056,15 +631,6 @@ yuzu - org.yuzu_emu.yuzu - - - ~/Applications/yuzu*.AppImage - ~/.local/share/applications/yuzu*.AppImage - ~/.local/bin/yuzu*.AppImage - ~/bin/yuzu*.AppImage - /var/lib/flatpak/exports/bin/org.yuzu_emu.yuzu - ~/.local/share/flatpak/exports/bin/org.yuzu_emu.yuzu diff --git a/resources/systems/unix/es_systems.xml b/resources/systems/unix/es_systems.xml index dc05793f1..0b4733538 100644 --- a/resources/systems/unix/es_systems.xml +++ b/resources/systems/unix/es_systems.xml @@ -1,5 +1,5 @@ - + 3do @@ -193,7 +193,6 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/stella_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/stella2014_libretro.so %ROM% %EMULATOR_STELLA% %ROM% - %EMULATOR_GOPHER2600% %ROM% %EMULATOR_ARES% --fullscreen --system "Atari 2600" %ROM% atari2600 atari2600 @@ -237,8 +236,6 @@ .abs .ABS .bin .BIN .cdi .CDI .cof .COF .cue .CUE .j64 .J64 .jag .JAG .prg .PRG .rom .ROM .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/virtualjaguar_libretro.so %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/atarijaguar jaguar -cart %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_BIGPEMU-WINDOWS% %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_BIGPEMU-WINDOWS% %ROM% atarijaguar atarijaguar @@ -246,9 +243,8 @@ atarijaguarcd Atari Jaguar CD %ROMPATH%/atarijaguarcd - .abs .ABS .bin .BIN .cdi .CDI .cof .COF .cue .CUE .j64 .J64 .jag .JAG .prg .PRG .rom .ROM .7z .7Z .zip .ZIP - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_BIGPEMU-WINDOWS% %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_BIGPEMU-WINDOWS% %ROM% + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% atarijaguarcd atarijaguarcd
@@ -394,7 +390,6 @@ %EMULATOR_FLYCAST-DOJO% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/kronos_libretro.so %ROM% %EMULATOR_MEDNAFEN% -force_module ss %ROM% - %EMULATOR_PLAY!% --disc %ROM% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %INJECT%=%BASENAME%.esprefix %EMULATOR_TRIFORCE% -b -e %ROM% %INJECT%=%BASENAME%.esprefix %EMULATOR_XEMU% -dvd_path %ROM% @@ -486,7 +481,7 @@ daphne Daphne Arcade LaserDisc Emulator %ROMPATH%/daphne - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% @@ -499,11 +494,9 @@ desktop Desktop Applications %ROMPATH%/desktop - .AppImage .desktop .sh + .desktop .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" - %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" pcwindows desktop
@@ -511,7 +504,7 @@ doom Doom %ROMPATH%/doom - .desktop .iwad .IWAD .pk4 .PK4 .pwad .PWAD .sh .wad .WAD + .desktop .ipk3 .IPK3 .iwad .IWAD .pk3 .PK3 .pk4 .PK4 .pwad .PWAD .sh .wad .WAD %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/prboom_libretro.so %ROM% %EMULATOR_PRBOOM-PLUS% -iwad %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/boom3_libretro.so %ROM% @@ -580,11 +573,9 @@ emulators Emulators %ROMPATH%/emulators - .AppImage .desktop .sh + .desktop .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" - %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" pcwindows emulators
@@ -601,7 +592,7 @@ famicom Nintendo Family Computer %ROMPATH%/famicom - .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen_libretro.so %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nestopia_libretro.so %ROM% @@ -612,8 +603,6 @@ %EMULATOR_MEDNAFEN% -force_module nes %ROM% %EMULATOR_ARES% --fullscreen --system "Famicom" %ROM% %EMULATOR_ARES% --fullscreen --system "Famicom Disk System" %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen famicom famicom
@@ -714,6 +703,7 @@ Nintendo Game and Watch %ROMPATH%/gameandwatch .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/gameandwatch/artwork -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/gameandwatch %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.so %ROM% @@ -741,6 +731,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/smsplus_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% %EMULATOR_MEDNAFEN% -force_module gg %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "Game Gear" %ROM% gamegear gamegear @@ -756,6 +747,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearboy_libretro.so %ROM% %EMULATOR_GEARBOY% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tgbdual_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/DoubleCherryGB_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% @@ -795,6 +787,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearboy_libretro.so %ROM% %EMULATOR_GEARBOY% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/tgbdual_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/DoubleCherryGB_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bsnes_libretro.so %ROM% @@ -888,7 +881,7 @@ laserdisc LaserDisc Games %ROMPATH%/laserdisc - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%/%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%/%BASENAME%.txt -script %GAMEDIR%/%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% @@ -902,6 +895,7 @@ LCD Handheld Games %ROMPATH%/lcdgames .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -artpath %ROMPATH%/lcdgames/artwork -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/lcdgames %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gw_libretro.so %ROM% @@ -991,6 +985,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/picodrive_libretro.so %ROM% %EMULATOR_MEDNAFEN% -force_module sms %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "Master System" %ROM% mastersystem mastersystem @@ -1076,8 +1071,6 @@ .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mame_libretro.so %ROM% %STARTDIR%=~/.mame %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%/model2 %BASENAME% - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_M2EMULATOR-WINDOWS% %BASENAME% - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_M2EMULATOR-WINDOWS% %BASENAME% arcade model2
@@ -1164,6 +1157,7 @@ %ROMPATH%/multivision .bin .BIN .gg .GG .rom .ROM .sg .SG .sms .SMS .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% sg-1000 multivision
@@ -1242,11 +1236,12 @@ Nintendo DS %ROMPATH%/nds .app .APP .bin .BIN .nds .NDS .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melondsds_libretro.so %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melonds_libretro.so %ROM% + %EMULATOR_MELONDS% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/desmume2015_libretro.so %ROM% %EMULATOR_DESMUME% %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/melonds_libretro.so %ROM% - %EMULATOR_MELONDS% %ROM% %EMULATOR_SKYEMU% %ROM% nds nds @@ -1290,7 +1285,7 @@ nes Nintendo Entertainment System %ROMPATH%/nes - .3dsen .3DSEN .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP + .fds .FDS .nes .NES .unf .UNF .unif .UNIF .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen_libretro.so %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nestopia_libretro.so %ROM% @@ -1301,8 +1296,6 @@ %EMULATOR_MEDNAFEN% -force_module nes %ROM% %EMULATOR_ARES% --fullscreen --system "Famicom" %ROM% %EMULATOR_ARES% --fullscreen --system "Famicom Disk System" %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_3DSEN-WINDOWS% -id=%INJECT%=%BASENAME%.3dsen nes nes
@@ -1313,8 +1306,6 @@ .ngage .zip .ZIP %EMULATOR_EKA2L1% --fullscreen --device RH-29 --mount %ROM% --run "%BASENAME%" %EMULATOR_EKA2L1% --fullscreen --device RH-29 --run "%BASENAME%" - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_EKA2L1-WINDOWS% --fullscreen --device RH-29 --mount %ROM% --run "%BASENAME%" - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_EKA2L1-WINDOWS% --fullscreen --device RH-29 --run "%BASENAME%" ngage ngage
@@ -1357,8 +1348,8 @@ openbor OpenBOR Game Engine %ROMPATH%/openbor - .AppImage - %STARTDIR%=%GAMEDIR% %EMULATOR_OS-SHELL% -c "%ROM%" + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% openbor openbor
@@ -1417,10 +1408,7 @@ pcarcade PC Arcade Systems %ROMPATH%/pcarcade - .AppImage .desktop .exe .EXE .sh - %STARTDIR%=%GAMEDIR% %EMULATOR_WINE% %ROM% - %STARTDIR%=%GAMEDIR% %EMULATOR_PROTON% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" + .desktop .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% arcade pcarcade @@ -1495,9 +1483,8 @@ ports Ports %ROMPATH%/ports - .AppImage .desktop .exe .EXE .game .GAME .phd .PHD .psx .PSX .sh + .desktop .exe .EXE .game .GAME .phd .PHD .psx .PSX .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/ecwolf_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/nxengine_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/openlara_libretro.so %ROM% @@ -1509,12 +1496,10 @@ ps2 Sony PlayStation 2 %ROMPATH%/ps2 - .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG + .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG .zso .ZSO %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pcsx2_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/pcsx2_libretro.so %ROM% %EMULATOR_PCSX2% -batch %ROM% - %EMULATOR_PCSX2-LEGACY% --nogui %ROM% - %EMULATOR_PLAY!% --disc %ROM% ps2 ps2
@@ -1739,6 +1724,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/genesis_plus_gx_wide_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/gearsystem_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/bluemsx_libretro.so %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "SG-1000" %ROM% sg-1000 sg-1000 @@ -1749,7 +1735,7 @@ %ROMPATH%/sgb .gb .GB .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mesen-s_libretro.so %ROM% - %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_MESEN% --fullscreen --gameBoy.useSgb2=true %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/sameboy_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mgba_libretro.so %ROM% %EMULATOR_MGBA% -f %ROM% @@ -1858,6 +1844,8 @@ .ccd .CCD .chd .CHD .cue .CUE .pce .PCE .sgx .SGX .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_supergrafx_libretro.so %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/mednafen_pce_libretro.so %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "SuperGrafx" %ROM% supergrafx supergrafx @@ -1992,10 +1980,7 @@ type-x Taito Type X %ROMPATH%/type-x - .AppImage .desktop .exe .EXE .sh - %STARTDIR%=%GAMEDIR% %EMULATOR_WINE% %ROM% - %STARTDIR%=%GAMEDIR% %EMULATOR_PROTON% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" + .desktop .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% arcade type-x @@ -2056,7 +2041,7 @@ Visual Pinball %ROMPATH%/vpinball .vpt .VPT .vpx .VPX - %EMULATOR_VISUAL-PINBALL% -Minimized -Play %ROM% + %EMULATOR_VISUAL-PINBALL% -play %ROM% vpinball vpinball
@@ -2103,11 +2088,9 @@ windows Microsoft Windows %ROMPATH%/windows - .AppImage .desktop .sh + .desktop .sh %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" - %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" pcwindows windows
@@ -2115,13 +2098,11 @@ windows3x Microsoft Windows 3.x %ROMPATH%/windows3x - .AppImage .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP + .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% -defaultdir %GAMEDIR% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" - %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" windows3x windows3x
@@ -2129,13 +2110,11 @@ windows9x Microsoft Windows 9x %ROMPATH%/windows9x - .AppImage .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP + .bat .BAT .desktop .dosz .DOSZ .sh .7z .7Z .zip .ZIP %STARTDIR%=%GAMEDIR% %EMULATOR_DOSBOX-X% -defaultdir %GAMEDIR% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%/dosbox_pure_libretro.so %ROM% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% %RUNINBACKGROUND% %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% - %EMULATOR_OS-SHELL% -c "%ROM%" - %RUNINBACKGROUND% %EMULATOR_OS-SHELL% -c "%ROM%" pcwindows windows9x @@ -2196,10 +2175,8 @@ xbox360 Microsoft Xbox 360 %ROMPATH%/xbox360 - . .desktop .iso .ISO .sh .xex .XEX - %STARTDIR%=%EMUDIR% %PRECOMMAND_WINE% %EMULATOR_XENIA-WINDOWS% %ROM% - %STARTDIR%=%EMUDIR% %PRECOMMAND_PROTON% %EMULATOR_XENIA-WINDOWS% %ROM% - %ENABLESHORTCUTS% %EMULATOR_OS-SHELL% %ROM% + .7z .7Z .zip .ZIP + PLACEHOLDER %ROM% xbox360 xbox360 diff --git a/resources/systems/windows/es_find_rules.xml b/resources/systems/windows/es_find_rules.xml index 7d64d4fca..42ce7f53d 100644 --- a/resources/systems/windows/es_find_rules.xml +++ b/resources/systems/windows/es_find_rules.xml @@ -886,9 +886,15 @@ + VPinballX_GL64.exe + VPinballX64.exe VPinballX.exe + %ESPATH%\Emulators\VPinballX\VPinballX_GL64.exe + %ESPATH%\..\Emulators\VPinballX\VPinballX_GL64.exe + %ESPATH%\Emulators\VPinballX\VPinballX64.exe + %ESPATH%\..\Emulators\VPinballX\VPinballX64.exe %ESPATH%\Emulators\Visual Pinball\VPinballX.exe %ESPATH%\..\Emulators\Visual Pinball\VPinballX.exe diff --git a/resources/systems/windows/es_find_rules_portable.xml b/resources/systems/windows/es_find_rules_portable.xml index 0ed950f73..c793ebc02 100644 --- a/resources/systems/windows/es_find_rules_portable.xml +++ b/resources/systems/windows/es_find_rules_portable.xml @@ -592,6 +592,10 @@ + %ESPATH%\Emulators\VPinballX\VPinballX_GL64.exe + %ESPATH%\..\Emulators\VPinballX\VPinballX_GL64.exe + %ESPATH%\Emulators\VPinballX\VPinballX64.exe + %ESPATH%\..\Emulators\VPinballX\VPinballX64.exe %ESPATH%\Emulators\Visual Pinball\VPinballX.exe %ESPATH%\..\Emulators\Visual Pinball\VPinballX.exe diff --git a/resources/systems/windows/es_systems.xml b/resources/systems/windows/es_systems.xml index 7062e11c0..c4accf08c 100644 --- a/resources/systems/windows/es_systems.xml +++ b/resources/systems/windows/es_systems.xml @@ -486,7 +486,7 @@ daphne Daphne Arcade LaserDisc Emulator %ROMPATH%\daphne - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%\%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%\%BASENAME%.txt -script %GAMEDIR%\%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mame_libretro.dll %ROM% @@ -509,7 +509,7 @@ doom Doom %ROMPATH%\doom - .bat .BAT .iwad .IWAD .lnk .LNK .pk4 .PK4 .pwad .PWAD .wad .WAD + .bat .BAT .ipk3 .IPK3 .iwad .IWAD .lnk .LNK .pk3 .PK3 .pk4 .PK4 .pwad .PWAD .wad .WAD %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\prboom_libretro.dll %ROM% %EMULATOR_PRBOOM-PLUS% -iwad %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\boom3_libretro.dll %ROM% @@ -590,7 +590,7 @@ Epic Games Store %ROMPATH%\epic .bat .BAT .lnk .LNK .url .URL - %HIDEWINDOW% %ESCAPESPECIALS% %EMULATOR_OS-SHELL% /C %ROM% + %HIDEWINDOW% %ESCAPESPECIALS% %RUNINBACKGROUND% %EMULATOR_OS-SHELL% /C %ROM% pcwindows epic @@ -708,6 +708,7 @@ Nintendo Game and Watch %ROMPATH%\gameandwatch .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mame_libretro.dll %ROM% %HIDEWINDOW% %STARTDIR%=%EMUDIR% %EMULATOR_MAME% -artpath %ROMPATH%\gameandwatch\artwork -rompath %GAMEDIR%\;%ROMPATH%\gameandwatch %BASENAME% %HIDEWINDOW% %STARTDIR%=%EMUDIR% %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%\gameandwatch %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gw_libretro.dll %ROM% @@ -735,6 +736,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\smsplus_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\picodrive_libretro.dll %ROM% %EMULATOR_MEDNAFEN% -force_module gg %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "Game Gear" %ROM% gamegear gamegear @@ -750,6 +752,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gearboy_libretro.dll %ROM% %EMULATOR_GEARBOY% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\tgbdual_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\DoubleCherryGB_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mesen-s_libretro.dll %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\bsnes_libretro.dll %ROM% @@ -757,6 +760,7 @@ %EMULATOR_MGBA% -f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\vbam_libretro.dll %ROM% %EMULATOR_VBA-M% /f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy" %ROM% %EMULATOR_SKYEMU% %ROM% gb @@ -773,6 +777,7 @@ %EMULATOR_VBA-M% /f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\vba_next_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gpsp_libretro.dll %ROM% + %EMULATOR_MEDNAFEN% -force_module gba %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy Advance" %ROM% %EMULATOR_SKYEMU% %ROM% gba @@ -789,6 +794,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gearboy_libretro.dll %ROM% %EMULATOR_GEARBOY% %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\tgbdual_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\DoubleCherryGB_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mesen-s_libretro.dll %ROM% %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\bsnes_libretro.dll %ROM% @@ -796,6 +802,7 @@ %EMULATOR_MGBA% -f %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\vbam_libretro.dll %ROM% %EMULATOR_VBA-M% /f %ROM% + %EMULATOR_MEDNAFEN% -force_module gb %ROM% %EMULATOR_ARES% --fullscreen --system "Game Boy Color" %ROM% %EMULATOR_SKYEMU% %ROM% gbc @@ -882,7 +889,7 @@ laserdisc LaserDisc Games %ROMPATH%\laserdisc - .daphne .ogv .OGV .singe .7z .7Z .zip .ZIP + .daphne .dirksimple .ogv .OGV .singe .7z .7Z .zip .ZIP %EMULATOR_HYPSEUS-SINGE% %BASENAME% vldp -framefile %GAMEDIR%\%BASENAME%.txt %INJECT%=%BASENAME%.commands %EMULATOR_HYPSEUS-SINGE% singe vldp -framefile %GAMEDIR%\%BASENAME%.txt -script %GAMEDIR%\%BASENAME%.singe %INJECT%=%BASENAME%.commands %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mame_libretro.dll %ROM% @@ -896,6 +903,7 @@ LCD Handheld Games %ROMPATH%\lcdgames .mgw .MGW .7z .7Z .zip .ZIP + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mame_libretro.dll %ROM% %HIDEWINDOW% %STARTDIR%=%EMUDIR% %EMULATOR_MAME% -artpath %ROMPATH%\lcdgames\artwork -rompath %GAMEDIR%\;%ROMPATH%\lcdgames %BASENAME% %HIDEWINDOW% %STARTDIR%=%EMUDIR% %EMULATOR_MAME% -rompath %GAMEDIR%\;%ROMPATH%\lcdgames %BASENAME% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gw_libretro.dll %ROM% @@ -987,6 +995,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gearsystem_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\picodrive_libretro.dll %ROM% %EMULATOR_MEDNAFEN% -force_module sms %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "Master System" %ROM% mastersystem mastersystem @@ -1158,6 +1167,7 @@ %ROMPATH%\multivision .bin .BIN .gg .GG .rom .ROM .sg .SG .sms .SMS .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gearsystem_libretro.dll %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% sg-1000 multivision @@ -1239,10 +1249,11 @@ Nintendo DS %ROMPATH%\nds .app .APP .bin .BIN .nds .NDS .7z .7Z .zip .ZIP - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\desmume_libretro.dll %ROM% - %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\desmume2015_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\melondsds_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\melonds_libretro.dll %ROM% %EMULATOR_MELONDS% %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\desmume_libretro.dll %ROM% + %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\desmume2015_libretro.dll %ROM% %EMULATOR_SKYEMU% %ROM% nds nds @@ -1495,7 +1506,7 @@ ps2 Sony PlayStation 2 %ROMPATH%\ps2 - .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG + .arcadedef .bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG .zso .ZSO %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\pcsx2_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\pcsx2_libretro.dll %ROM% %EMULATOR_PCSX2% -batch %ROM% @@ -1727,6 +1738,7 @@ %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\genesis_plus_gx_wide_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\gearsystem_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\bluemsx_libretro.dll %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "SG-1000" %ROM% sg-1000 sg-1000 @@ -1737,7 +1749,7 @@ %ROMPATH%\sgb .gb .GB .gbc .GBC .sgb .SGB .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mesen-s_libretro.dll %ROM% - %EMULATOR_MESEN% --fullscreen %ROM% + %EMULATOR_MESEN% --fullscreen --gameBoy.useSgb2=true %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\sameboy_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mgba_libretro.dll %ROM% %EMULATOR_MGBA% -f %ROM% @@ -1846,6 +1858,8 @@ .ccd .CCD .chd .CHD .cue .CUE .pce .PCE .sgx .SGX .7z .7Z .zip .ZIP %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_supergrafx_libretro.dll %ROM% %EMULATOR_RETROARCH% -L %CORE_RETROARCH%\mednafen_pce_libretro.dll %ROM% + %EMULATOR_MEDNAFEN% -force_module pce %ROM% + %EMULATOR_MESEN% --fullscreen %ROM% %EMULATOR_ARES% --fullscreen --system "SuperGrafx" %ROM% supergrafx supergrafx @@ -2041,7 +2055,7 @@ Visual Pinball %ROMPATH%\vpinball .vpt .VPT .vpx .VPX - %EMULATOR_VISUAL-PINBALL% -Minimized -Play %ROM% + %EMULATOR_VISUAL-PINBALL% -minimized -play %ROM% vpinball vpinball @@ -2176,7 +2190,7 @@ xbox360 Microsoft Xbox 360 %ROMPATH%\xbox360 - . .iso .ISO .xex .XEX + . .iso .ISO .xex .XEX .zar .ZAR %STARTDIR%=%EMUDIR% %EMULATOR_XENIA% %ROM% xbox360 xbox360 diff --git a/themes/.gitignore b/themes/.gitignore index 535115a92..9e8b779c7 100644 --- a/themes/.gitignore +++ b/themes/.gitignore @@ -1,5 +1,7 @@ * !.gitignore +!linear-es-de +!linear-es-de/** !modern-es-de !modern-es-de/** !slate-es-de diff --git a/themes/linear-es-de/CREDITS.md b/themes/linear-es-de/CREDITS.md new file mode 100644 index 000000000..a090bd620 --- /dev/null +++ b/themes/linear-es-de/CREDITS.md @@ -0,0 +1,5 @@ +# Linear for ES-DE - credits + +The Linear theme is based on [ESonline](https://github.com/Weestuarty/esonline-es-de) by Weestuarty. + +[Carousel icons](https://github.com/szymon-kulak/es-de-moderntheme-nsoicons) originally made by Szymon Kulak and modified by the ES-DE project. diff --git a/themes/linear-es-de/LICENSE b/themes/linear-es-de/LICENSE new file mode 100644 index 000000000..5ad1cf226 --- /dev/null +++ b/themes/linear-es-de/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2024 Leon Styhre +Copyright (c) 2023 Weestuarty + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/themes/linear-es-de/README.md b/themes/linear-es-de/README.md new file mode 100644 index 000000000..06abbe760 --- /dev/null +++ b/themes/linear-es-de/README.md @@ -0,0 +1,40 @@ +# Linear for ES-DE (linear-es-de) + +The following options are included: + +6 variants: + +- Textlist +- Textlist without videos +- Simple textlist +- Simple textlist without videos +- Carousel +- Simple carousel + +5 color schemes: + +- Dark +- Light +- NSO +- LIVE +- PSN + +2 font sizes: + +- Medium +- Large + +4 aspect ratios: + +- 16:9 +- 16:10 +- 4:3 +- 21:9 + +3 transitions: + +- Instant and slide +- Instant +- Fade + +Credits and license information can be found next to this file. diff --git a/themes/linear-es-de/aspect-ratio-16-10.xml b/themes/linear-es-de/aspect-ratio-16-10.xml new file mode 100644 index 000000000..95be205d9 --- /dev/null +++ b/themes/linear-es-de/aspect-ratio-16-10.xml @@ -0,0 +1,77 @@ + + + + 0.032 + 1 0.057 + + + + + 0.036 + 1 0.061 + + + + + + + ${helpsystemPanelSize} + + + ${helpsystemFontSize} + + + + + + + + 0.405 0.66 + + + + + + + + 0.03 0.049 + + + + + + + + + + + + + + 0.592 0.417 + 0.377 0.485 + + + + + + + + + + + + + + 0.655 0.22 + 0.5 0.62 + + + + \ No newline at end of file diff --git a/themes/linear-es-de/aspect-ratio-16-9.xml b/themes/linear-es-de/aspect-ratio-16-9.xml new file mode 100644 index 000000000..6486c5329 --- /dev/null +++ b/themes/linear-es-de/aspect-ratio-16-9.xml @@ -0,0 +1,77 @@ + + + + 0.032 + 1 0.06 + + + + + 0.038 + 1 0.064 + + + + + + + ${helpsystemPanelSize} + + + ${helpsystemFontSize} + + + + + + + + 0.405 0.674 + + + + + + + + 0.03 0.043 + + + + + + + + + + + + + + 0.592 0.417 + 0.377 0.485 + + + + + + + + + + + + + + 0.66 0.174 + 0.5 0.69 + + + + \ No newline at end of file diff --git a/themes/linear-es-de/aspect-ratio-21-9.xml b/themes/linear-es-de/aspect-ratio-21-9.xml new file mode 100644 index 000000000..1f676dd1c --- /dev/null +++ b/themes/linear-es-de/aspect-ratio-21-9.xml @@ -0,0 +1,77 @@ + + + + 0.032 + 1 0.058 + + + + + 0.038 + 1 0.063 + + + + + + + ${helpsystemPanelSize} + + + ${helpsystemFontSize} + + + + + + + + 0.405 0.67 + + + + + + + + 0.03 0.024 + + + + + + + + + + + + + + 0.592 0.417 + 0.3 0.485 + + + + + + + + + + + + + + 0.66 0.174 + 0.45 0.715 + + + + \ No newline at end of file diff --git a/themes/linear-es-de/aspect-ratio-4-3.xml b/themes/linear-es-de/aspect-ratio-4-3.xml new file mode 100644 index 000000000..4cf91652b --- /dev/null +++ b/themes/linear-es-de/aspect-ratio-4-3.xml @@ -0,0 +1,77 @@ + + + + 0.029 + 1 0.054 + + + + + 0.030 + 1 0.056 + + + + + + + ${helpsystemPanelSize} + + + ${helpsystemFontSize} + + + + + + + + 0.405 0.64 + + + + + + + + 0.03 0.058 + + + + + + + + + + + + + + 0.592 0.417 + 0.377 0.415 + + + + + + + + + + + + + + 0.655 0.25 + 0.5 0.52 + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-altemulator.svg b/themes/linear-es-de/assets/badges/badge-altemulator.svg new file mode 100644 index 000000000..ea9384088 --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-altemulator.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-broken.svg b/themes/linear-es-de/assets/badges/badge-broken.svg new file mode 100644 index 000000000..5f6c3a71b --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-broken.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-collection.svg b/themes/linear-es-de/assets/badges/badge-collection.svg new file mode 100644 index 000000000..7178b05a3 --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-collection.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-completed.svg b/themes/linear-es-de/assets/badges/badge-completed.svg new file mode 100644 index 000000000..972cc62c9 --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-completed.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-controller.svg b/themes/linear-es-de/assets/badges/badge-controller.svg new file mode 100644 index 000000000..5a6438a3b --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-controller.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-favorite.svg b/themes/linear-es-de/assets/badges/badge-favorite.svg new file mode 100644 index 000000000..bb5053d42 --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-favorite.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-folder.svg b/themes/linear-es-de/assets/badges/badge-folder.svg new file mode 100644 index 000000000..1b7e4eae8 --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-folder.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-kidgame.svg b/themes/linear-es-de/assets/badges/badge-kidgame.svg new file mode 100644 index 000000000..d3b94811b --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-kidgame.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/badges/badge-manual.svg b/themes/linear-es-de/assets/badges/badge-manual.svg new file mode 100644 index 000000000..55a6be9bd --- /dev/null +++ b/themes/linear-es-de/assets/badges/badge-manual.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/assets/fonts/Gilroy-Light.ttf b/themes/linear-es-de/assets/fonts/Gilroy-Light.ttf new file mode 100644 index 000000000..d8c2bb949 Binary files /dev/null and b/themes/linear-es-de/assets/fonts/Gilroy-Light.ttf differ diff --git a/themes/linear-es-de/assets/fonts/Oxygen-Regular.ttf b/themes/linear-es-de/assets/fonts/Oxygen-Regular.ttf new file mode 100644 index 000000000..a66ddf1c8 Binary files /dev/null and b/themes/linear-es-de/assets/fonts/Oxygen-Regular.ttf differ diff --git a/themes/linear-es-de/assets/images/gradient.svg b/themes/linear-es-de/assets/images/gradient.svg new file mode 100644 index 000000000..f1a8c7dc8 --- /dev/null +++ b/themes/linear-es-de/assets/images/gradient.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/assets/images/icon-players.svg b/themes/linear-es-de/assets/images/icon-players.svg new file mode 100644 index 000000000..906fce24a --- /dev/null +++ b/themes/linear-es-de/assets/images/icon-players.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/themes/linear-es-de/assets/images/icon-release-date.svg b/themes/linear-es-de/assets/images/icon-release-date.svg new file mode 100644 index 000000000..0faa1eb61 --- /dev/null +++ b/themes/linear-es-de/assets/images/icon-release-date.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/themes/linear-es-de/assets/images/pixel.png b/themes/linear-es-de/assets/images/pixel.png new file mode 100644 index 000000000..9e6e20d89 Binary files /dev/null and b/themes/linear-es-de/assets/images/pixel.png differ diff --git a/themes/linear-es-de/auto-allgames/theme.xml b/themes/linear-es-de/auto-allgames/theme.xml new file mode 100644 index 000000000..0645d9f1d --- /dev/null +++ b/themes/linear-es-de/auto-allgames/theme.xml @@ -0,0 +1,11 @@ + + ./../theme.xml + + + + + capitalize + + + + \ No newline at end of file diff --git a/themes/linear-es-de/auto-favorites/theme.xml b/themes/linear-es-de/auto-favorites/theme.xml new file mode 100644 index 000000000..0645d9f1d --- /dev/null +++ b/themes/linear-es-de/auto-favorites/theme.xml @@ -0,0 +1,11 @@ + + ./../theme.xml + + + + + capitalize + + + + \ No newline at end of file diff --git a/themes/linear-es-de/auto-lastplayed/theme.xml b/themes/linear-es-de/auto-lastplayed/theme.xml new file mode 100644 index 000000000..0645d9f1d --- /dev/null +++ b/themes/linear-es-de/auto-lastplayed/theme.xml @@ -0,0 +1,11 @@ + + ./../theme.xml + + + + + capitalize + + + + \ No newline at end of file diff --git a/themes/linear-es-de/capabilities.xml b/themes/linear-es-de/capabilities.xml new file mode 100644 index 000000000..53aa8e1b5 --- /dev/null +++ b/themes/linear-es-de/capabilities.xml @@ -0,0 +1,102 @@ + + + + Linear + + 16:9 + 16:10 + 4:3 + 21:9 + + medium + large + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + + + + + true + instant + slide + instant + slide + + + + + true + instant + instant + instant + instant + slide + slide + + + + + true + fade + fade + fade + fade + slide + slide + + + + builtin-instant + builtin-slide + builtin-fade + + \ No newline at end of file diff --git a/themes/linear-es-de/colors.xml b/themes/linear-es-de/colors.xml new file mode 100644 index 000000000..b3804e912 --- /dev/null +++ b/themes/linear-es-de/colors.xml @@ -0,0 +1,92 @@ + + + + + 000000 + 373737 + FAFAFA + C2C2C2 + C2C2C2 + + + FFFFFF + 777777 + BBBBBB + 303030 + ABABAB + 545454 + + + + + + 000000 + 838383 + FFFFFF + D2D2D2 + FAFAFA + + + FFFFFF + 545454 + BBBBBB + 787878 + 3B3B3B + 707070 + + + + + + 000000 + E4000F + FFFFFF + FFFFFF + FFFFFF + + + FFFFFF + 111111 + 68000F + D0000F + 000000 + B0000F + + + + + + 000000 + 0E7A0D + FAF9F6 + FFFFFF + FFFFFF + + + FFFFFF + 111111 + 00460F + 00700F + 000000 + 00660F + + + + + + 000000 + 00338F + EAE9E6 + FFFFFF + FFFFFF + + + EAE9E6 + 000000 + 000072 + 0039AF + 000000 + 1B4DC0 + + + \ No newline at end of file diff --git a/themes/linear-es-de/custom-collections/theme.xml b/themes/linear-es-de/custom-collections/theme.xml new file mode 100644 index 000000000..46a6c629c --- /dev/null +++ b/themes/linear-es-de/custom-collections/theme.xml @@ -0,0 +1,26 @@ + + ./../theme.xml + + + + + Custom Collections + capitalize + + + systemFullname + Your Collections + + + + + + + + systemFullname + Your Collections + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/3do.svg b/themes/linear-es-de/system/logos/3do.svg new file mode 100644 index 000000000..e9099701a --- /dev/null +++ b/themes/linear-es-de/system/logos/3do.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/adam.svg b/themes/linear-es-de/system/logos/adam.svg new file mode 100644 index 000000000..56cc79b11 --- /dev/null +++ b/themes/linear-es-de/system/logos/adam.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/ags.svg b/themes/linear-es-de/system/logos/ags.svg new file mode 100644 index 000000000..f4a34a83d --- /dev/null +++ b/themes/linear-es-de/system/logos/ags.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/amiga.svg b/themes/linear-es-de/system/logos/amiga.svg new file mode 100644 index 000000000..716a73022 --- /dev/null +++ b/themes/linear-es-de/system/logos/amiga.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/amiga1200.svg b/themes/linear-es-de/system/logos/amiga1200.svg new file mode 100644 index 000000000..b3e7da2e2 --- /dev/null +++ b/themes/linear-es-de/system/logos/amiga1200.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/amiga600.svg b/themes/linear-es-de/system/logos/amiga600.svg new file mode 100644 index 000000000..491d7cedc --- /dev/null +++ b/themes/linear-es-de/system/logos/amiga600.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/amigacd32.svg b/themes/linear-es-de/system/logos/amigacd32.svg new file mode 100644 index 000000000..30433e304 --- /dev/null +++ b/themes/linear-es-de/system/logos/amigacd32.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/amstradcpc.svg b/themes/linear-es-de/system/logos/amstradcpc.svg new file mode 100644 index 000000000..50af50f97 --- /dev/null +++ b/themes/linear-es-de/system/logos/amstradcpc.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/android.svg b/themes/linear-es-de/system/logos/android.svg new file mode 100644 index 000000000..50333bea1 --- /dev/null +++ b/themes/linear-es-de/system/logos/android.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/apple2.svg b/themes/linear-es-de/system/logos/apple2.svg new file mode 100644 index 000000000..b0263f1a6 --- /dev/null +++ b/themes/linear-es-de/system/logos/apple2.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/apple2gs.svg b/themes/linear-es-de/system/logos/apple2gs.svg new file mode 100644 index 000000000..4c603dd14 --- /dev/null +++ b/themes/linear-es-de/system/logos/apple2gs.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/arcade.svg b/themes/linear-es-de/system/logos/arcade.svg new file mode 100644 index 000000000..c88f40a33 --- /dev/null +++ b/themes/linear-es-de/system/logos/arcade.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/arcadia.svg b/themes/linear-es-de/system/logos/arcadia.svg new file mode 100644 index 000000000..cb237e2ae --- /dev/null +++ b/themes/linear-es-de/system/logos/arcadia.svg @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/archimedes.svg b/themes/linear-es-de/system/logos/archimedes.svg new file mode 100644 index 000000000..5e0c26fa8 --- /dev/null +++ b/themes/linear-es-de/system/logos/archimedes.svg @@ -0,0 +1,40 @@ + + + + + + diff --git a/themes/linear-es-de/system/logos/arduboy.svg b/themes/linear-es-de/system/logos/arduboy.svg new file mode 100644 index 000000000..9080b8414 --- /dev/null +++ b/themes/linear-es-de/system/logos/arduboy.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/astrocade.svg b/themes/linear-es-de/system/logos/astrocade.svg new file mode 100644 index 000000000..c09bad1d5 --- /dev/null +++ b/themes/linear-es-de/system/logos/astrocade.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atari2600.svg b/themes/linear-es-de/system/logos/atari2600.svg new file mode 100644 index 000000000..a1c78e887 --- /dev/null +++ b/themes/linear-es-de/system/logos/atari2600.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atari5200.svg b/themes/linear-es-de/system/logos/atari5200.svg new file mode 100644 index 000000000..d793b184d --- /dev/null +++ b/themes/linear-es-de/system/logos/atari5200.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atari7800.svg b/themes/linear-es-de/system/logos/atari7800.svg new file mode 100644 index 000000000..6da0fbd48 --- /dev/null +++ b/themes/linear-es-de/system/logos/atari7800.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atari800.svg b/themes/linear-es-de/system/logos/atari800.svg new file mode 100644 index 000000000..b2d112ff1 --- /dev/null +++ b/themes/linear-es-de/system/logos/atari800.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atarijaguar.svg b/themes/linear-es-de/system/logos/atarijaguar.svg new file mode 100644 index 000000000..d5d76422c --- /dev/null +++ b/themes/linear-es-de/system/logos/atarijaguar.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atarijaguarcd.svg b/themes/linear-es-de/system/logos/atarijaguarcd.svg new file mode 100644 index 000000000..9a8e5aad8 --- /dev/null +++ b/themes/linear-es-de/system/logos/atarijaguarcd.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atarilynx.svg b/themes/linear-es-de/system/logos/atarilynx.svg new file mode 100644 index 000000000..4c785b10f --- /dev/null +++ b/themes/linear-es-de/system/logos/atarilynx.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atarist.svg b/themes/linear-es-de/system/logos/atarist.svg new file mode 100644 index 000000000..a4b0396df --- /dev/null +++ b/themes/linear-es-de/system/logos/atarist.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atarixe.svg b/themes/linear-es-de/system/logos/atarixe.svg new file mode 100644 index 000000000..a5665c432 --- /dev/null +++ b/themes/linear-es-de/system/logos/atarixe.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/atomiswave.svg b/themes/linear-es-de/system/logos/atomiswave.svg new file mode 100644 index 000000000..92a1679b6 --- /dev/null +++ b/themes/linear-es-de/system/logos/atomiswave.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/auto-allgames.svg b/themes/linear-es-de/system/logos/auto-allgames.svg new file mode 100644 index 000000000..7d4a4e19b --- /dev/null +++ b/themes/linear-es-de/system/logos/auto-allgames.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/auto-favorites.svg b/themes/linear-es-de/system/logos/auto-favorites.svg new file mode 100644 index 000000000..86161442b --- /dev/null +++ b/themes/linear-es-de/system/logos/auto-favorites.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/auto-lastplayed.svg b/themes/linear-es-de/system/logos/auto-lastplayed.svg new file mode 100644 index 000000000..48f97ec96 --- /dev/null +++ b/themes/linear-es-de/system/logos/auto-lastplayed.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/bbcmicro.svg b/themes/linear-es-de/system/logos/bbcmicro.svg new file mode 100644 index 000000000..60124da6c --- /dev/null +++ b/themes/linear-es-de/system/logos/bbcmicro.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/c64.svg b/themes/linear-es-de/system/logos/c64.svg new file mode 100644 index 000000000..91a8c0b09 --- /dev/null +++ b/themes/linear-es-de/system/logos/c64.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/cavestory.svg b/themes/linear-es-de/system/logos/cavestory.svg new file mode 100644 index 000000000..2fe4c3cd4 --- /dev/null +++ b/themes/linear-es-de/system/logos/cavestory.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/cdimono1.svg b/themes/linear-es-de/system/logos/cdimono1.svg new file mode 100644 index 000000000..8a4850ddb --- /dev/null +++ b/themes/linear-es-de/system/logos/cdimono1.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/cdtv.svg b/themes/linear-es-de/system/logos/cdtv.svg new file mode 100644 index 000000000..cb11dec6d --- /dev/null +++ b/themes/linear-es-de/system/logos/cdtv.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/chailove.svg b/themes/linear-es-de/system/logos/chailove.svg new file mode 100644 index 000000000..c5ebf99e2 --- /dev/null +++ b/themes/linear-es-de/system/logos/chailove.svg @@ -0,0 +1,10 @@ + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/channelf.svg b/themes/linear-es-de/system/logos/channelf.svg new file mode 100644 index 000000000..458101f31 --- /dev/null +++ b/themes/linear-es-de/system/logos/channelf.svg @@ -0,0 +1,11 @@ + + + Sharp_X1_logo + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/coco.svg b/themes/linear-es-de/system/logos/coco.svg new file mode 100644 index 000000000..6d623294f --- /dev/null +++ b/themes/linear-es-de/system/logos/coco.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/colecovision.svg b/themes/linear-es-de/system/logos/colecovision.svg new file mode 100644 index 000000000..beeee8a8d --- /dev/null +++ b/themes/linear-es-de/system/logos/colecovision.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/consolearcade.svg b/themes/linear-es-de/system/logos/consolearcade.svg new file mode 100644 index 000000000..958dd4ca3 --- /dev/null +++ b/themes/linear-es-de/system/logos/consolearcade.svg @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/cps.svg b/themes/linear-es-de/system/logos/cps.svg new file mode 100644 index 000000000..c6567685e --- /dev/null +++ b/themes/linear-es-de/system/logos/cps.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/cps1.svg b/themes/linear-es-de/system/logos/cps1.svg new file mode 100644 index 000000000..34e4291ba --- /dev/null +++ b/themes/linear-es-de/system/logos/cps1.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/cps2.svg b/themes/linear-es-de/system/logos/cps2.svg new file mode 100644 index 000000000..889f155ea --- /dev/null +++ b/themes/linear-es-de/system/logos/cps2.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/cps3.svg b/themes/linear-es-de/system/logos/cps3.svg new file mode 100644 index 000000000..78061292a --- /dev/null +++ b/themes/linear-es-de/system/logos/cps3.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/crvision.svg b/themes/linear-es-de/system/logos/crvision.svg new file mode 100644 index 000000000..b40931f07 --- /dev/null +++ b/themes/linear-es-de/system/logos/crvision.svg @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/custom-collections.svg b/themes/linear-es-de/system/logos/custom-collections.svg new file mode 100644 index 000000000..157092b86 --- /dev/null +++ b/themes/linear-es-de/system/logos/custom-collections.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/daphne.svg b/themes/linear-es-de/system/logos/daphne.svg new file mode 100644 index 000000000..4714292b8 --- /dev/null +++ b/themes/linear-es-de/system/logos/daphne.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/desktop.svg b/themes/linear-es-de/system/logos/desktop.svg new file mode 100644 index 000000000..d969ac156 --- /dev/null +++ b/themes/linear-es-de/system/logos/desktop.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/doom.svg b/themes/linear-es-de/system/logos/doom.svg new file mode 100644 index 000000000..e12b4a820 --- /dev/null +++ b/themes/linear-es-de/system/logos/doom.svg @@ -0,0 +1,35 @@ + + + + + + + image/svg+xml + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/dos.svg b/themes/linear-es-de/system/logos/dos.svg new file mode 100644 index 000000000..889379889 --- /dev/null +++ b/themes/linear-es-de/system/logos/dos.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/dragon32.svg b/themes/linear-es-de/system/logos/dragon32.svg new file mode 100644 index 000000000..f69fbceb3 --- /dev/null +++ b/themes/linear-es-de/system/logos/dragon32.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/dreamcast.svg b/themes/linear-es-de/system/logos/dreamcast.svg new file mode 100644 index 000000000..aaa4717ed --- /dev/null +++ b/themes/linear-es-de/system/logos/dreamcast.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/easyrpg.svg b/themes/linear-es-de/system/logos/easyrpg.svg new file mode 100644 index 000000000..058f30286 --- /dev/null +++ b/themes/linear-es-de/system/logos/easyrpg.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/electron.svg b/themes/linear-es-de/system/logos/electron.svg new file mode 100644 index 000000000..dad0506ff --- /dev/null +++ b/themes/linear-es-de/system/logos/electron.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/emulators.svg b/themes/linear-es-de/system/logos/emulators.svg new file mode 100644 index 000000000..cc097c7d9 --- /dev/null +++ b/themes/linear-es-de/system/logos/emulators.svg @@ -0,0 +1,93 @@ + + + +image/svg+xml + + diff --git a/themes/linear-es-de/system/logos/epic.svg b/themes/linear-es-de/system/logos/epic.svg new file mode 100644 index 000000000..893b5566c --- /dev/null +++ b/themes/linear-es-de/system/logos/epic.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/famicom.svg b/themes/linear-es-de/system/logos/famicom.svg new file mode 100644 index 000000000..710c5c369 --- /dev/null +++ b/themes/linear-es-de/system/logos/famicom.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/fba.svg b/themes/linear-es-de/system/logos/fba.svg new file mode 100644 index 000000000..386351f8f --- /dev/null +++ b/themes/linear-es-de/system/logos/fba.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/fbneo.svg b/themes/linear-es-de/system/logos/fbneo.svg new file mode 100644 index 000000000..e2bb6daa5 --- /dev/null +++ b/themes/linear-es-de/system/logos/fbneo.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/fds.svg b/themes/linear-es-de/system/logos/fds.svg new file mode 100644 index 000000000..9c5a20a75 --- /dev/null +++ b/themes/linear-es-de/system/logos/fds.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/flash.svg b/themes/linear-es-de/system/logos/flash.svg new file mode 100644 index 000000000..87677ce8f --- /dev/null +++ b/themes/linear-es-de/system/logos/flash.svg @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/fm7.svg b/themes/linear-es-de/system/logos/fm7.svg new file mode 100644 index 000000000..bf1d1f979 --- /dev/null +++ b/themes/linear-es-de/system/logos/fm7.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/fmtowns.svg b/themes/linear-es-de/system/logos/fmtowns.svg new file mode 100644 index 000000000..2fe672b09 --- /dev/null +++ b/themes/linear-es-de/system/logos/fmtowns.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/fpinball.svg b/themes/linear-es-de/system/logos/fpinball.svg new file mode 100644 index 000000000..f6ffff7bd --- /dev/null +++ b/themes/linear-es-de/system/logos/fpinball.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + Layer 1 + + + + + diff --git a/themes/linear-es-de/system/logos/gamate.svg b/themes/linear-es-de/system/logos/gamate.svg new file mode 100644 index 000000000..4b1186880 --- /dev/null +++ b/themes/linear-es-de/system/logos/gamate.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/gameandwatch.svg b/themes/linear-es-de/system/logos/gameandwatch.svg new file mode 100644 index 000000000..8b90808d7 --- /dev/null +++ b/themes/linear-es-de/system/logos/gameandwatch.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gamecom.svg b/themes/linear-es-de/system/logos/gamecom.svg new file mode 100644 index 000000000..50113dc45 --- /dev/null +++ b/themes/linear-es-de/system/logos/gamecom.svg @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/gamegear.svg b/themes/linear-es-de/system/logos/gamegear.svg new file mode 100644 index 000000000..38f274fb6 --- /dev/null +++ b/themes/linear-es-de/system/logos/gamegear.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gb.svg b/themes/linear-es-de/system/logos/gb.svg new file mode 100644 index 000000000..ece29dbc7 --- /dev/null +++ b/themes/linear-es-de/system/logos/gb.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gba.svg b/themes/linear-es-de/system/logos/gba.svg new file mode 100644 index 000000000..0efbc3179 --- /dev/null +++ b/themes/linear-es-de/system/logos/gba.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gbc.svg b/themes/linear-es-de/system/logos/gbc.svg new file mode 100644 index 000000000..35bed7bf6 --- /dev/null +++ b/themes/linear-es-de/system/logos/gbc.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gc.svg b/themes/linear-es-de/system/logos/gc.svg new file mode 100644 index 000000000..676d95715 --- /dev/null +++ b/themes/linear-es-de/system/logos/gc.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/genesis.svg b/themes/linear-es-de/system/logos/genesis.svg new file mode 100644 index 000000000..e8fdf36e9 --- /dev/null +++ b/themes/linear-es-de/system/logos/genesis.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/gmaster.svg b/themes/linear-es-de/system/logos/gmaster.svg new file mode 100644 index 000000000..a29e84885 --- /dev/null +++ b/themes/linear-es-de/system/logos/gmaster.svg @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/gx4000.svg b/themes/linear-es-de/system/logos/gx4000.svg new file mode 100644 index 000000000..09f5bde96 --- /dev/null +++ b/themes/linear-es-de/system/logos/gx4000.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/intellivision.svg b/themes/linear-es-de/system/logos/intellivision.svg new file mode 100644 index 000000000..93e1aff5e --- /dev/null +++ b/themes/linear-es-de/system/logos/intellivision.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/j2me.svg b/themes/linear-es-de/system/logos/j2me.svg new file mode 100644 index 000000000..84bf7927c --- /dev/null +++ b/themes/linear-es-de/system/logos/j2me.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/kodi.svg b/themes/linear-es-de/system/logos/kodi.svg new file mode 100644 index 000000000..1210d9447 --- /dev/null +++ b/themes/linear-es-de/system/logos/kodi.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/laserdisc.svg b/themes/linear-es-de/system/logos/laserdisc.svg new file mode 100644 index 000000000..495a57df4 --- /dev/null +++ b/themes/linear-es-de/system/logos/laserdisc.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/lcdgames.svg b/themes/linear-es-de/system/logos/lcdgames.svg new file mode 100644 index 000000000..a42c00ec3 --- /dev/null +++ b/themes/linear-es-de/system/logos/lcdgames.svg @@ -0,0 +1,1410 @@ + + + +image/svg+xml diff --git a/themes/linear-es-de/system/logos/lowresnx.svg b/themes/linear-es-de/system/logos/lowresnx.svg new file mode 100644 index 000000000..28cd7a5c5 --- /dev/null +++ b/themes/linear-es-de/system/logos/lowresnx.svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/lutris.svg b/themes/linear-es-de/system/logos/lutris.svg new file mode 100644 index 000000000..dfbf27f0b --- /dev/null +++ b/themes/linear-es-de/system/logos/lutris.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/lutro.svg b/themes/linear-es-de/system/logos/lutro.svg new file mode 100644 index 000000000..fa70e93f8 --- /dev/null +++ b/themes/linear-es-de/system/logos/lutro.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/macintosh.svg b/themes/linear-es-de/system/logos/macintosh.svg new file mode 100644 index 000000000..47f9e8e58 --- /dev/null +++ b/themes/linear-es-de/system/logos/macintosh.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/mame-advmame.svg b/themes/linear-es-de/system/logos/mame-advmame.svg new file mode 100644 index 000000000..ea979e993 --- /dev/null +++ b/themes/linear-es-de/system/logos/mame-advmame.svg @@ -0,0 +1,524 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/mame.svg b/themes/linear-es-de/system/logos/mame.svg new file mode 100644 index 000000000..08023926b --- /dev/null +++ b/themes/linear-es-de/system/logos/mame.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/mastersystem.svg b/themes/linear-es-de/system/logos/mastersystem.svg new file mode 100644 index 000000000..efec37f05 --- /dev/null +++ b/themes/linear-es-de/system/logos/mastersystem.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/megacd.svg b/themes/linear-es-de/system/logos/megacd.svg new file mode 100644 index 000000000..174b653c6 --- /dev/null +++ b/themes/linear-es-de/system/logos/megacd.svg @@ -0,0 +1 @@ +sega32x \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/megacdjp.svg b/themes/linear-es-de/system/logos/megacdjp.svg new file mode 100644 index 000000000..174b653c6 --- /dev/null +++ b/themes/linear-es-de/system/logos/megacdjp.svg @@ -0,0 +1 @@ +sega32x \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/megadrive.svg b/themes/linear-es-de/system/logos/megadrive.svg new file mode 100644 index 000000000..91aab8510 --- /dev/null +++ b/themes/linear-es-de/system/logos/megadrive.svg @@ -0,0 +1 @@ +megadrive \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/megadrivejp.svg b/themes/linear-es-de/system/logos/megadrivejp.svg new file mode 100644 index 000000000..e099a8b53 --- /dev/null +++ b/themes/linear-es-de/system/logos/megadrivejp.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/megaduck.svg b/themes/linear-es-de/system/logos/megaduck.svg new file mode 100644 index 000000000..a8f5c1e31 --- /dev/null +++ b/themes/linear-es-de/system/logos/megaduck.svg @@ -0,0 +1 @@ +megaduck \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/mess.svg b/themes/linear-es-de/system/logos/mess.svg new file mode 100644 index 000000000..8acebe3e5 --- /dev/null +++ b/themes/linear-es-de/system/logos/mess.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/model2.svg b/themes/linear-es-de/system/logos/model2.svg new file mode 100644 index 000000000..26bb05fb7 --- /dev/null +++ b/themes/linear-es-de/system/logos/model2.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/model3.svg b/themes/linear-es-de/system/logos/model3.svg new file mode 100644 index 000000000..6d9a4acea --- /dev/null +++ b/themes/linear-es-de/system/logos/model3.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/moonlight.svg b/themes/linear-es-de/system/logos/moonlight.svg new file mode 100644 index 000000000..8e7fbb75a --- /dev/null +++ b/themes/linear-es-de/system/logos/moonlight.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/moto.svg b/themes/linear-es-de/system/logos/moto.svg new file mode 100644 index 000000000..a24b6dfdf --- /dev/null +++ b/themes/linear-es-de/system/logos/moto.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/msx.svg b/themes/linear-es-de/system/logos/msx.svg new file mode 100644 index 000000000..7ad036f67 --- /dev/null +++ b/themes/linear-es-de/system/logos/msx.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/msx1.svg b/themes/linear-es-de/system/logos/msx1.svg new file mode 100644 index 000000000..7ad036f67 --- /dev/null +++ b/themes/linear-es-de/system/logos/msx1.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/msx2.svg b/themes/linear-es-de/system/logos/msx2.svg new file mode 100644 index 000000000..782a98ad8 --- /dev/null +++ b/themes/linear-es-de/system/logos/msx2.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/msxturbor.svg b/themes/linear-es-de/system/logos/msxturbor.svg new file mode 100644 index 000000000..9512676ab --- /dev/null +++ b/themes/linear-es-de/system/logos/msxturbor.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/mugen.svg b/themes/linear-es-de/system/logos/mugen.svg new file mode 100644 index 000000000..95e59e8a1 --- /dev/null +++ b/themes/linear-es-de/system/logos/mugen.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/multivision.svg b/themes/linear-es-de/system/logos/multivision.svg new file mode 100644 index 000000000..f7a8cc962 --- /dev/null +++ b/themes/linear-es-de/system/logos/multivision.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/n3ds.svg b/themes/linear-es-de/system/logos/n3ds.svg new file mode 100644 index 000000000..b5e504096 --- /dev/null +++ b/themes/linear-es-de/system/logos/n3ds.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/n64.svg b/themes/linear-es-de/system/logos/n64.svg new file mode 100644 index 000000000..c265227bc --- /dev/null +++ b/themes/linear-es-de/system/logos/n64.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/n64dd.svg b/themes/linear-es-de/system/logos/n64dd.svg new file mode 100644 index 000000000..da028ab03 --- /dev/null +++ b/themes/linear-es-de/system/logos/n64dd.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/naomi.svg b/themes/linear-es-de/system/logos/naomi.svg new file mode 100644 index 000000000..681181fbd --- /dev/null +++ b/themes/linear-es-de/system/logos/naomi.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/naomi2.svg b/themes/linear-es-de/system/logos/naomi2.svg new file mode 100644 index 000000000..ae618974a --- /dev/null +++ b/themes/linear-es-de/system/logos/naomi2.svg @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/naomigd.svg b/themes/linear-es-de/system/logos/naomigd.svg new file mode 100644 index 000000000..0a171702b --- /dev/null +++ b/themes/linear-es-de/system/logos/naomigd.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/nds.svg b/themes/linear-es-de/system/logos/nds.svg new file mode 100644 index 000000000..876cac639 --- /dev/null +++ b/themes/linear-es-de/system/logos/nds.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/neogeo.svg b/themes/linear-es-de/system/logos/neogeo.svg new file mode 100644 index 000000000..c67e8cc79 --- /dev/null +++ b/themes/linear-es-de/system/logos/neogeo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/neogeocd.svg b/themes/linear-es-de/system/logos/neogeocd.svg new file mode 100644 index 000000000..6e2df971a --- /dev/null +++ b/themes/linear-es-de/system/logos/neogeocd.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/neogeocdjp.svg b/themes/linear-es-de/system/logos/neogeocdjp.svg new file mode 100644 index 000000000..6e2df971a --- /dev/null +++ b/themes/linear-es-de/system/logos/neogeocdjp.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/nes.svg b/themes/linear-es-de/system/logos/nes.svg new file mode 100644 index 000000000..3f13ab3a9 --- /dev/null +++ b/themes/linear-es-de/system/logos/nes.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ngage.svg b/themes/linear-es-de/system/logos/ngage.svg new file mode 100644 index 000000000..401f99b7a --- /dev/null +++ b/themes/linear-es-de/system/logos/ngage.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/ngp.svg b/themes/linear-es-de/system/logos/ngp.svg new file mode 100644 index 000000000..2459abc0b --- /dev/null +++ b/themes/linear-es-de/system/logos/ngp.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ngpc.svg b/themes/linear-es-de/system/logos/ngpc.svg new file mode 100644 index 000000000..f1aa6c4f1 --- /dev/null +++ b/themes/linear-es-de/system/logos/ngpc.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/now-playing.svg b/themes/linear-es-de/system/logos/now-playing.svg new file mode 100644 index 000000000..322cb5df2 --- /dev/null +++ b/themes/linear-es-de/system/logos/now-playing.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/odyssey2.svg b/themes/linear-es-de/system/logos/odyssey2.svg new file mode 100644 index 000000000..1f8d59922 --- /dev/null +++ b/themes/linear-es-de/system/logos/odyssey2.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/openbor.svg b/themes/linear-es-de/system/logos/openbor.svg new file mode 100644 index 000000000..94b10e5da --- /dev/null +++ b/themes/linear-es-de/system/logos/openbor.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/oric.svg b/themes/linear-es-de/system/logos/oric.svg new file mode 100644 index 000000000..c19486086 --- /dev/null +++ b/themes/linear-es-de/system/logos/oric.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/palm.svg b/themes/linear-es-de/system/logos/palm.svg new file mode 100644 index 000000000..1e0c41049 --- /dev/null +++ b/themes/linear-es-de/system/logos/palm.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pc.svg b/themes/linear-es-de/system/logos/pc.svg new file mode 100644 index 000000000..758545c81 --- /dev/null +++ b/themes/linear-es-de/system/logos/pc.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pc88.svg b/themes/linear-es-de/system/logos/pc88.svg new file mode 100644 index 000000000..11b28f3fc --- /dev/null +++ b/themes/linear-es-de/system/logos/pc88.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/pc98.svg b/themes/linear-es-de/system/logos/pc98.svg new file mode 100644 index 000000000..bcfe4849f --- /dev/null +++ b/themes/linear-es-de/system/logos/pc98.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pcarcade.svg b/themes/linear-es-de/system/logos/pcarcade.svg new file mode 100644 index 000000000..4f304eb55 --- /dev/null +++ b/themes/linear-es-de/system/logos/pcarcade.svg @@ -0,0 +1,445 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/pcengine.svg b/themes/linear-es-de/system/logos/pcengine.svg new file mode 100644 index 000000000..99ff9dde0 --- /dev/null +++ b/themes/linear-es-de/system/logos/pcengine.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pcenginecd.svg b/themes/linear-es-de/system/logos/pcenginecd.svg new file mode 100644 index 000000000..d7d630858 --- /dev/null +++ b/themes/linear-es-de/system/logos/pcenginecd.svg @@ -0,0 +1 @@ +pce-cd \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pcfx.svg b/themes/linear-es-de/system/logos/pcfx.svg new file mode 100644 index 000000000..3eecf66ed --- /dev/null +++ b/themes/linear-es-de/system/logos/pcfx.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pico8.svg b/themes/linear-es-de/system/logos/pico8.svg new file mode 100644 index 000000000..8d3edc85b --- /dev/null +++ b/themes/linear-es-de/system/logos/pico8.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/plus4.svg b/themes/linear-es-de/system/logos/plus4.svg new file mode 100644 index 000000000..a4fefc476 --- /dev/null +++ b/themes/linear-es-de/system/logos/plus4.svg @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/pokemini.svg b/themes/linear-es-de/system/logos/pokemini.svg new file mode 100644 index 000000000..648b9c5e7 --- /dev/null +++ b/themes/linear-es-de/system/logos/pokemini.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ports.svg b/themes/linear-es-de/system/logos/ports.svg new file mode 100644 index 000000000..03fd34c65 --- /dev/null +++ b/themes/linear-es-de/system/logos/ports.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ps2.svg b/themes/linear-es-de/system/logos/ps2.svg new file mode 100644 index 000000000..816de4f5c --- /dev/null +++ b/themes/linear-es-de/system/logos/ps2.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ps3.svg b/themes/linear-es-de/system/logos/ps3.svg new file mode 100644 index 000000000..83f3af490 --- /dev/null +++ b/themes/linear-es-de/system/logos/ps3.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ps4.svg b/themes/linear-es-de/system/logos/ps4.svg new file mode 100644 index 000000000..07e47eb00 --- /dev/null +++ b/themes/linear-es-de/system/logos/ps4.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/psp.svg b/themes/linear-es-de/system/logos/psp.svg new file mode 100644 index 000000000..5a69ab8f2 --- /dev/null +++ b/themes/linear-es-de/system/logos/psp.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/psvita.svg b/themes/linear-es-de/system/logos/psvita.svg new file mode 100644 index 000000000..b56f7ef64 --- /dev/null +++ b/themes/linear-es-de/system/logos/psvita.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/psx.svg b/themes/linear-es-de/system/logos/psx.svg new file mode 100644 index 000000000..4123eda2b --- /dev/null +++ b/themes/linear-es-de/system/logos/psx.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/pv1000.svg b/themes/linear-es-de/system/logos/pv1000.svg new file mode 100644 index 000000000..5bd6b6c8c --- /dev/null +++ b/themes/linear-es-de/system/logos/pv1000.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/quake.svg b/themes/linear-es-de/system/logos/quake.svg new file mode 100644 index 000000000..73b6ea09b --- /dev/null +++ b/themes/linear-es-de/system/logos/quake.svg @@ -0,0 +1,54 @@ + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/samcoupe.svg b/themes/linear-es-de/system/logos/samcoupe.svg new file mode 100644 index 000000000..d1c462cd4 --- /dev/null +++ b/themes/linear-es-de/system/logos/samcoupe.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/satellaview.svg b/themes/linear-es-de/system/logos/satellaview.svg new file mode 100644 index 000000000..490472fc1 --- /dev/null +++ b/themes/linear-es-de/system/logos/satellaview.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/saturn.svg b/themes/linear-es-de/system/logos/saturn.svg new file mode 100644 index 000000000..284f58905 --- /dev/null +++ b/themes/linear-es-de/system/logos/saturn.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/saturnjp.svg b/themes/linear-es-de/system/logos/saturnjp.svg new file mode 100644 index 000000000..284f58905 --- /dev/null +++ b/themes/linear-es-de/system/logos/saturnjp.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/scummvm.svg b/themes/linear-es-de/system/logos/scummvm.svg new file mode 100644 index 000000000..f1ff43d11 --- /dev/null +++ b/themes/linear-es-de/system/logos/scummvm.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/scv.svg b/themes/linear-es-de/system/logos/scv.svg new file mode 100644 index 000000000..bab8e009a --- /dev/null +++ b/themes/linear-es-de/system/logos/scv.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/sega32x.svg b/themes/linear-es-de/system/logos/sega32x.svg new file mode 100644 index 000000000..333ec5967 --- /dev/null +++ b/themes/linear-es-de/system/logos/sega32x.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/sega32xjp.svg b/themes/linear-es-de/system/logos/sega32xjp.svg new file mode 100644 index 000000000..333ec5967 --- /dev/null +++ b/themes/linear-es-de/system/logos/sega32xjp.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/sega32xna.svg b/themes/linear-es-de/system/logos/sega32xna.svg new file mode 100644 index 000000000..333ec5967 --- /dev/null +++ b/themes/linear-es-de/system/logos/sega32xna.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/segacd.svg b/themes/linear-es-de/system/logos/segacd.svg new file mode 100644 index 000000000..0b07389c1 --- /dev/null +++ b/themes/linear-es-de/system/logos/segacd.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/sfc.svg b/themes/linear-es-de/system/logos/sfc.svg new file mode 100644 index 000000000..f6ba6b227 --- /dev/null +++ b/themes/linear-es-de/system/logos/sfc.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/sg-1000.svg b/themes/linear-es-de/system/logos/sg-1000.svg new file mode 100644 index 000000000..876b0f813 --- /dev/null +++ b/themes/linear-es-de/system/logos/sg-1000.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/sgb.svg b/themes/linear-es-de/system/logos/sgb.svg new file mode 100644 index 000000000..331328164 --- /dev/null +++ b/themes/linear-es-de/system/logos/sgb.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/snes.svg b/themes/linear-es-de/system/logos/snes.svg new file mode 100644 index 000000000..2989df13a --- /dev/null +++ b/themes/linear-es-de/system/logos/snes.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/snesna.svg b/themes/linear-es-de/system/logos/snesna.svg new file mode 100644 index 000000000..2989df13a --- /dev/null +++ b/themes/linear-es-de/system/logos/snesna.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/solarus.svg b/themes/linear-es-de/system/logos/solarus.svg new file mode 100644 index 000000000..669c95d95 --- /dev/null +++ b/themes/linear-es-de/system/logos/solarus.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/spectravideo.svg b/themes/linear-es-de/system/logos/spectravideo.svg new file mode 100644 index 000000000..f7ee0fc8a --- /dev/null +++ b/themes/linear-es-de/system/logos/spectravideo.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/steam.svg b/themes/linear-es-de/system/logos/steam.svg new file mode 100644 index 000000000..994088d41 --- /dev/null +++ b/themes/linear-es-de/system/logos/steam.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/stratagus.svg b/themes/linear-es-de/system/logos/stratagus.svg new file mode 100644 index 000000000..be7845cb0 --- /dev/null +++ b/themes/linear-es-de/system/logos/stratagus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/stv.svg b/themes/linear-es-de/system/logos/stv.svg new file mode 100644 index 000000000..2dfeda954 --- /dev/null +++ b/themes/linear-es-de/system/logos/stv.svg @@ -0,0 +1,5138 @@ + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/sufami.svg b/themes/linear-es-de/system/logos/sufami.svg new file mode 100644 index 000000000..d85590f21 --- /dev/null +++ b/themes/linear-es-de/system/logos/sufami.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/supergrafx.svg b/themes/linear-es-de/system/logos/supergrafx.svg new file mode 100644 index 000000000..d72ad75c8 --- /dev/null +++ b/themes/linear-es-de/system/logos/supergrafx.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/supervision.svg b/themes/linear-es-de/system/logos/supervision.svg new file mode 100644 index 000000000..87621fbb6 --- /dev/null +++ b/themes/linear-es-de/system/logos/supervision.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/supracan.svg b/themes/linear-es-de/system/logos/supracan.svg new file mode 100644 index 000000000..58076f506 --- /dev/null +++ b/themes/linear-es-de/system/logos/supracan.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/switch.svg b/themes/linear-es-de/system/logos/switch.svg new file mode 100644 index 000000000..6a3fa5831 --- /dev/null +++ b/themes/linear-es-de/system/logos/switch.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/symbian.svg b/themes/linear-es-de/system/logos/symbian.svg new file mode 100644 index 000000000..0bc552c9b --- /dev/null +++ b/themes/linear-es-de/system/logos/symbian.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/tanodragon.svg b/themes/linear-es-de/system/logos/tanodragon.svg new file mode 100644 index 000000000..1e72a9b5f --- /dev/null +++ b/themes/linear-es-de/system/logos/tanodragon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/tg-cd.svg b/themes/linear-es-de/system/logos/tg-cd.svg new file mode 100644 index 000000000..97a553237 --- /dev/null +++ b/themes/linear-es-de/system/logos/tg-cd.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/tg16.svg b/themes/linear-es-de/system/logos/tg16.svg new file mode 100644 index 000000000..c8b3c4326 --- /dev/null +++ b/themes/linear-es-de/system/logos/tg16.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/ti99.svg b/themes/linear-es-de/system/logos/ti99.svg new file mode 100644 index 000000000..983cbf068 --- /dev/null +++ b/themes/linear-es-de/system/logos/ti99.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/tic80.svg b/themes/linear-es-de/system/logos/tic80.svg new file mode 100644 index 000000000..4b4850815 --- /dev/null +++ b/themes/linear-es-de/system/logos/tic80.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/to8.svg b/themes/linear-es-de/system/logos/to8.svg new file mode 100644 index 000000000..ca2363c17 --- /dev/null +++ b/themes/linear-es-de/system/logos/to8.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/tools.svg b/themes/linear-es-de/system/logos/tools.svg new file mode 100644 index 000000000..a05eaadde --- /dev/null +++ b/themes/linear-es-de/system/logos/tools.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/triforce.svg b/themes/linear-es-de/system/logos/triforce.svg new file mode 100644 index 000000000..3217dfb9b --- /dev/null +++ b/themes/linear-es-de/system/logos/triforce.svg @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/trs-80.svg b/themes/linear-es-de/system/logos/trs-80.svg new file mode 100644 index 000000000..8015c8b3d --- /dev/null +++ b/themes/linear-es-de/system/logos/trs-80.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/type-x.svg b/themes/linear-es-de/system/logos/type-x.svg new file mode 100644 index 000000000..2ca1e2c3d --- /dev/null +++ b/themes/linear-es-de/system/logos/type-x.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/uzebox.svg b/themes/linear-es-de/system/logos/uzebox.svg new file mode 100644 index 000000000..1829e6e99 --- /dev/null +++ b/themes/linear-es-de/system/logos/uzebox.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/vectrex.svg b/themes/linear-es-de/system/logos/vectrex.svg new file mode 100644 index 000000000..73dd55989 --- /dev/null +++ b/themes/linear-es-de/system/logos/vectrex.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/vic20.svg b/themes/linear-es-de/system/logos/vic20.svg new file mode 100644 index 000000000..9ce457ae4 --- /dev/null +++ b/themes/linear-es-de/system/logos/vic20.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/videopac.svg b/themes/linear-es-de/system/logos/videopac.svg new file mode 100644 index 000000000..89127dab9 --- /dev/null +++ b/themes/linear-es-de/system/logos/videopac.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/virtualboy.svg b/themes/linear-es-de/system/logos/virtualboy.svg new file mode 100644 index 000000000..c07861f8b --- /dev/null +++ b/themes/linear-es-de/system/logos/virtualboy.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/vpinball.svg b/themes/linear-es-de/system/logos/vpinball.svg new file mode 100644 index 000000000..e6d638e99 --- /dev/null +++ b/themes/linear-es-de/system/logos/vpinball.svg @@ -0,0 +1,68 @@ + + + + + + + + + John Loreth 2022 + + Layer 1 + + + + + diff --git a/themes/linear-es-de/system/logos/vsmile.svg b/themes/linear-es-de/system/logos/vsmile.svg new file mode 100644 index 000000000..9ad901805 --- /dev/null +++ b/themes/linear-es-de/system/logos/vsmile.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/wasm4.svg b/themes/linear-es-de/system/logos/wasm4.svg new file mode 100644 index 000000000..68ff7e124 --- /dev/null +++ b/themes/linear-es-de/system/logos/wasm4.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/wii.svg b/themes/linear-es-de/system/logos/wii.svg new file mode 100644 index 000000000..5f78ee79d --- /dev/null +++ b/themes/linear-es-de/system/logos/wii.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/wiiu.svg b/themes/linear-es-de/system/logos/wiiu.svg new file mode 100644 index 000000000..937795488 --- /dev/null +++ b/themes/linear-es-de/system/logos/wiiu.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/windows.svg b/themes/linear-es-de/system/logos/windows.svg new file mode 100644 index 000000000..f42327683 --- /dev/null +++ b/themes/linear-es-de/system/logos/windows.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/windows3x.svg b/themes/linear-es-de/system/logos/windows3x.svg new file mode 100644 index 000000000..384ceb87e --- /dev/null +++ b/themes/linear-es-de/system/logos/windows3x.svg @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/windows9x.svg b/themes/linear-es-de/system/logos/windows9x.svg new file mode 100644 index 000000000..65bf33681 --- /dev/null +++ b/themes/linear-es-de/system/logos/windows9x.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/wonderswan.svg b/themes/linear-es-de/system/logos/wonderswan.svg new file mode 100644 index 000000000..51c4c261b --- /dev/null +++ b/themes/linear-es-de/system/logos/wonderswan.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/wonderswancolor.svg b/themes/linear-es-de/system/logos/wonderswancolor.svg new file mode 100644 index 000000000..2cc1f900c --- /dev/null +++ b/themes/linear-es-de/system/logos/wonderswancolor.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/x1.svg b/themes/linear-es-de/system/logos/x1.svg new file mode 100644 index 000000000..b3a91cc6b --- /dev/null +++ b/themes/linear-es-de/system/logos/x1.svg @@ -0,0 +1 @@ +Sharp_X1_logo \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/x68000.svg b/themes/linear-es-de/system/logos/x68000.svg new file mode 100644 index 000000000..f99c6b150 --- /dev/null +++ b/themes/linear-es-de/system/logos/x68000.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/xbox.svg b/themes/linear-es-de/system/logos/xbox.svg new file mode 100644 index 000000000..1371869ac --- /dev/null +++ b/themes/linear-es-de/system/logos/xbox.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/xbox360.svg b/themes/linear-es-de/system/logos/xbox360.svg new file mode 100644 index 000000000..340c9d71b --- /dev/null +++ b/themes/linear-es-de/system/logos/xbox360.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/zmachine.svg b/themes/linear-es-de/system/logos/zmachine.svg new file mode 100644 index 000000000..4eba7582c --- /dev/null +++ b/themes/linear-es-de/system/logos/zmachine.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/zx81.svg b/themes/linear-es-de/system/logos/zx81.svg new file mode 100644 index 000000000..22caafea9 --- /dev/null +++ b/themes/linear-es-de/system/logos/zx81.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/logos/zxnext.svg b/themes/linear-es-de/system/logos/zxnext.svg new file mode 100644 index 000000000..263d1fb05 --- /dev/null +++ b/themes/linear-es-de/system/logos/zxnext.svg @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/themes/linear-es-de/system/logos/zxspectrum.svg b/themes/linear-es-de/system/logos/zxspectrum.svg new file mode 100644 index 000000000..b9b1ad7a7 --- /dev/null +++ b/themes/linear-es-de/system/logos/zxspectrum.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/3do.xml b/themes/linear-es-de/system/metadata-custom/3do.xml new file mode 100644 index 000000000..a5f0765fd --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/3do.xml @@ -0,0 +1,10 @@ + + + AA9D96 + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/_default.xml b/themes/linear-es-de/system/metadata-custom/_default.xml new file mode 100644 index 000000000..0c6bcfb94 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/_default.xml @@ -0,0 +1,16 @@ + + + + ${systemHardwareType} + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/adam.xml b/themes/linear-es-de/system/metadata-custom/adam.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/adam.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ags.xml b/themes/linear-es-de/system/metadata-custom/ags.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ags.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/amiga.xml b/themes/linear-es-de/system/metadata-custom/amiga.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/amiga.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/amiga1200.xml b/themes/linear-es-de/system/metadata-custom/amiga1200.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/amiga1200.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/amiga600.xml b/themes/linear-es-de/system/metadata-custom/amiga600.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/amiga600.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/amigacd32.xml b/themes/linear-es-de/system/metadata-custom/amigacd32.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/amigacd32.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/amstradcpc.xml b/themes/linear-es-de/system/metadata-custom/amstradcpc.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/amstradcpc.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/android.xml b/themes/linear-es-de/system/metadata-custom/android.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/android.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/apple2.xml b/themes/linear-es-de/system/metadata-custom/apple2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/apple2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/apple2gs.xml b/themes/linear-es-de/system/metadata-custom/apple2gs.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/apple2gs.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/arcadia.xml b/themes/linear-es-de/system/metadata-custom/arcadia.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/arcadia.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/archimedes.xml b/themes/linear-es-de/system/metadata-custom/archimedes.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/archimedes.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/arduboy.xml b/themes/linear-es-de/system/metadata-custom/arduboy.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/arduboy.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/astrocade.xml b/themes/linear-es-de/system/metadata-custom/astrocade.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/astrocade.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atari2600.xml b/themes/linear-es-de/system/metadata-custom/atari2600.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atari2600.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atari5200.xml b/themes/linear-es-de/system/metadata-custom/atari5200.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atari5200.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atari7800.xml b/themes/linear-es-de/system/metadata-custom/atari7800.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atari7800.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atari800.xml b/themes/linear-es-de/system/metadata-custom/atari800.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atari800.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atarijaguar.xml b/themes/linear-es-de/system/metadata-custom/atarijaguar.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atarijaguar.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atarijaguarcd.xml b/themes/linear-es-de/system/metadata-custom/atarijaguarcd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atarijaguarcd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atarilynx.xml b/themes/linear-es-de/system/metadata-custom/atarilynx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atarilynx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atarist.xml b/themes/linear-es-de/system/metadata-custom/atarist.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atarist.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atarixe.xml b/themes/linear-es-de/system/metadata-custom/atarixe.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atarixe.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/atomiswave.xml b/themes/linear-es-de/system/metadata-custom/atomiswave.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/atomiswave.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/auto-allgames.xml b/themes/linear-es-de/system/metadata-custom/auto-allgames.xml new file mode 100644 index 000000000..b84737774 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/auto-allgames.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/auto-favorites.xml b/themes/linear-es-de/system/metadata-custom/auto-favorites.xml new file mode 100644 index 000000000..b84737774 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/auto-favorites.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/auto-lastplayed.xml b/themes/linear-es-de/system/metadata-custom/auto-lastplayed.xml new file mode 100644 index 000000000..b84737774 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/auto-lastplayed.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/bbcmicro.xml b/themes/linear-es-de/system/metadata-custom/bbcmicro.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/bbcmicro.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/c64.xml b/themes/linear-es-de/system/metadata-custom/c64.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/c64.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cdimono1.xml b/themes/linear-es-de/system/metadata-custom/cdimono1.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cdimono1.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cdtv.xml b/themes/linear-es-de/system/metadata-custom/cdtv.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cdtv.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/chailove.xml b/themes/linear-es-de/system/metadata-custom/chailove.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/chailove.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/channelf.xml b/themes/linear-es-de/system/metadata-custom/channelf.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/channelf.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/coco.xml b/themes/linear-es-de/system/metadata-custom/coco.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/coco.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/colecovision.xml b/themes/linear-es-de/system/metadata-custom/colecovision.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/colecovision.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/completed.xml b/themes/linear-es-de/system/metadata-custom/completed.xml new file mode 100644 index 000000000..9352af20c --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/completed.xml @@ -0,0 +1,9 @@ + + + + + fit + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cps.xml b/themes/linear-es-de/system/metadata-custom/cps.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cps.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cps1.xml b/themes/linear-es-de/system/metadata-custom/cps1.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cps1.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cps2.xml b/themes/linear-es-de/system/metadata-custom/cps2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cps2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/cps3.xml b/themes/linear-es-de/system/metadata-custom/cps3.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/cps3.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/crvision.xml b/themes/linear-es-de/system/metadata-custom/crvision.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/crvision.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/custom-collections.xml b/themes/linear-es-de/system/metadata-custom/custom-collections.xml new file mode 100644 index 000000000..b84737774 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/custom-collections.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/daphne.xml b/themes/linear-es-de/system/metadata-custom/daphne.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/daphne.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/doom.xml b/themes/linear-es-de/system/metadata-custom/doom.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/doom.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/dos.xml b/themes/linear-es-de/system/metadata-custom/dos.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/dos.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/dragon32.xml b/themes/linear-es-de/system/metadata-custom/dragon32.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/dragon32.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/dreamcast.xml b/themes/linear-es-de/system/metadata-custom/dreamcast.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/dreamcast.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/easyrpg.xml b/themes/linear-es-de/system/metadata-custom/easyrpg.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/easyrpg.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/electron.xml b/themes/linear-es-de/system/metadata-custom/electron.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/electron.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/famicom.xml b/themes/linear-es-de/system/metadata-custom/famicom.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/famicom.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fba.xml b/themes/linear-es-de/system/metadata-custom/fba.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fba.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fbneo.xml b/themes/linear-es-de/system/metadata-custom/fbneo.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fbneo.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fds.xml b/themes/linear-es-de/system/metadata-custom/fds.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fds.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/flash.xml b/themes/linear-es-de/system/metadata-custom/flash.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/flash.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fm7.xml b/themes/linear-es-de/system/metadata-custom/fm7.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fm7.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fmtowns.xml b/themes/linear-es-de/system/metadata-custom/fmtowns.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fmtowns.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/fpinball.xml b/themes/linear-es-de/system/metadata-custom/fpinball.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/fpinball.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gamate.xml b/themes/linear-es-de/system/metadata-custom/gamate.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gamate.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gameandwatch.xml b/themes/linear-es-de/system/metadata-custom/gameandwatch.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gameandwatch.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gamecom.xml b/themes/linear-es-de/system/metadata-custom/gamecom.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gamecom.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gamegear.xml b/themes/linear-es-de/system/metadata-custom/gamegear.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gamegear.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gb.xml b/themes/linear-es-de/system/metadata-custom/gb.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gb.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gba.xml b/themes/linear-es-de/system/metadata-custom/gba.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gba.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gbc.xml b/themes/linear-es-de/system/metadata-custom/gbc.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gbc.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gc.xml b/themes/linear-es-de/system/metadata-custom/gc.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gc.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/genesis.xml b/themes/linear-es-de/system/metadata-custom/genesis.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/genesis.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gmaster.xml b/themes/linear-es-de/system/metadata-custom/gmaster.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gmaster.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/gx4000.xml b/themes/linear-es-de/system/metadata-custom/gx4000.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/gx4000.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/intellivision.xml b/themes/linear-es-de/system/metadata-custom/intellivision.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/intellivision.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/j2me.xml b/themes/linear-es-de/system/metadata-custom/j2me.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/j2me.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/kodi.xml b/themes/linear-es-de/system/metadata-custom/kodi.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/kodi.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/lowresnx.xml b/themes/linear-es-de/system/metadata-custom/lowresnx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/lowresnx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/lutris.xml b/themes/linear-es-de/system/metadata-custom/lutris.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/lutris.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/lutro.xml b/themes/linear-es-de/system/metadata-custom/lutro.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/lutro.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/macintosh.xml b/themes/linear-es-de/system/metadata-custom/macintosh.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/macintosh.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/mame-advmame.xml b/themes/linear-es-de/system/metadata-custom/mame-advmame.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/mame-advmame.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/mame.xml b/themes/linear-es-de/system/metadata-custom/mame.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/mame.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/mastersystem.xml b/themes/linear-es-de/system/metadata-custom/mastersystem.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/mastersystem.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/megacd.xml b/themes/linear-es-de/system/metadata-custom/megacd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/megacd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/megacdjp.xml b/themes/linear-es-de/system/metadata-custom/megacdjp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/megacdjp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/megadrive.xml b/themes/linear-es-de/system/metadata-custom/megadrive.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/megadrive.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/megadrivejp.xml b/themes/linear-es-de/system/metadata-custom/megadrivejp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/megadrivejp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/megaduck.xml b/themes/linear-es-de/system/metadata-custom/megaduck.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/megaduck.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/mess.xml b/themes/linear-es-de/system/metadata-custom/mess.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/mess.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/model2.xml b/themes/linear-es-de/system/metadata-custom/model2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/model2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/model3.xml b/themes/linear-es-de/system/metadata-custom/model3.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/model3.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/moto.xml b/themes/linear-es-de/system/metadata-custom/moto.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/moto.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/msx.xml b/themes/linear-es-de/system/metadata-custom/msx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/msx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/msx1.xml b/themes/linear-es-de/system/metadata-custom/msx1.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/msx1.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/msx2.xml b/themes/linear-es-de/system/metadata-custom/msx2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/msx2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/msxturbor.xml b/themes/linear-es-de/system/metadata-custom/msxturbor.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/msxturbor.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/mugen.xml b/themes/linear-es-de/system/metadata-custom/mugen.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/mugen.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/multivision.xml b/themes/linear-es-de/system/metadata-custom/multivision.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/multivision.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/n3ds.xml b/themes/linear-es-de/system/metadata-custom/n3ds.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/n3ds.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/n64.xml b/themes/linear-es-de/system/metadata-custom/n64.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/n64.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/n64dd.xml b/themes/linear-es-de/system/metadata-custom/n64dd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/n64dd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/naomi.xml b/themes/linear-es-de/system/metadata-custom/naomi.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/naomi.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/naomi2.xml b/themes/linear-es-de/system/metadata-custom/naomi2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/naomi2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/naomigd.xml b/themes/linear-es-de/system/metadata-custom/naomigd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/naomigd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/nds.xml b/themes/linear-es-de/system/metadata-custom/nds.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/nds.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/neogeo.xml b/themes/linear-es-de/system/metadata-custom/neogeo.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/neogeo.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/neogeocd.xml b/themes/linear-es-de/system/metadata-custom/neogeocd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/neogeocd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/neogeocdjp.xml b/themes/linear-es-de/system/metadata-custom/neogeocdjp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/neogeocdjp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/nes.xml b/themes/linear-es-de/system/metadata-custom/nes.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/nes.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ngage.xml b/themes/linear-es-de/system/metadata-custom/ngage.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ngage.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ngp.xml b/themes/linear-es-de/system/metadata-custom/ngp.xml new file mode 100644 index 000000000..9a95ed380 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ngp.xml @@ -0,0 +1,10 @@ + + + CE4B39 + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ngpc.xml b/themes/linear-es-de/system/metadata-custom/ngpc.xml new file mode 100644 index 000000000..9a95ed380 --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ngpc.xml @@ -0,0 +1,10 @@ + + + CE4B39 + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/now-playing.xml b/themes/linear-es-de/system/metadata-custom/now-playing.xml new file mode 100644 index 000000000..9352af20c --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/now-playing.xml @@ -0,0 +1,9 @@ + + + + + fit + + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/odyssey2.xml b/themes/linear-es-de/system/metadata-custom/odyssey2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/odyssey2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/openbor.xml b/themes/linear-es-de/system/metadata-custom/openbor.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/openbor.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/oric.xml b/themes/linear-es-de/system/metadata-custom/oric.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/oric.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/palm.xml b/themes/linear-es-de/system/metadata-custom/palm.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/palm.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pc.xml b/themes/linear-es-de/system/metadata-custom/pc.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pc.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pc88.xml b/themes/linear-es-de/system/metadata-custom/pc88.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pc88.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pc98.xml b/themes/linear-es-de/system/metadata-custom/pc98.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pc98.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pcengine.xml b/themes/linear-es-de/system/metadata-custom/pcengine.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pcengine.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pcenginecd.xml b/themes/linear-es-de/system/metadata-custom/pcenginecd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pcenginecd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pcfx.xml b/themes/linear-es-de/system/metadata-custom/pcfx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pcfx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pico8.xml b/themes/linear-es-de/system/metadata-custom/pico8.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pico8.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/playdate.xml b/themes/linear-es-de/system/metadata-custom/playdate.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/playdate.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/plus4.xml b/themes/linear-es-de/system/metadata-custom/plus4.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/plus4.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pokemini.xml b/themes/linear-es-de/system/metadata-custom/pokemini.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pokemini.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ps2.xml b/themes/linear-es-de/system/metadata-custom/ps2.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ps2.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ps3.xml b/themes/linear-es-de/system/metadata-custom/ps3.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ps3.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ps4.xml b/themes/linear-es-de/system/metadata-custom/ps4.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ps4.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/psp.xml b/themes/linear-es-de/system/metadata-custom/psp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/psp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/psvita.xml b/themes/linear-es-de/system/metadata-custom/psvita.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/psvita.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/psx.xml b/themes/linear-es-de/system/metadata-custom/psx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/psx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/pv1000.xml b/themes/linear-es-de/system/metadata-custom/pv1000.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/pv1000.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/quake.xml b/themes/linear-es-de/system/metadata-custom/quake.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/quake.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/samcoupe.xml b/themes/linear-es-de/system/metadata-custom/samcoupe.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/samcoupe.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/satellaview.xml b/themes/linear-es-de/system/metadata-custom/satellaview.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/satellaview.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/saturn.xml b/themes/linear-es-de/system/metadata-custom/saturn.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/saturn.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/saturnjp.xml b/themes/linear-es-de/system/metadata-custom/saturnjp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/saturnjp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/scummvm.xml b/themes/linear-es-de/system/metadata-custom/scummvm.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/scummvm.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/scv.xml b/themes/linear-es-de/system/metadata-custom/scv.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/scv.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sega32x.xml b/themes/linear-es-de/system/metadata-custom/sega32x.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sega32x.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sega32xjp.xml b/themes/linear-es-de/system/metadata-custom/sega32xjp.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sega32xjp.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sega32xna.xml b/themes/linear-es-de/system/metadata-custom/sega32xna.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sega32xna.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/segacd.xml b/themes/linear-es-de/system/metadata-custom/segacd.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/segacd.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sfc.xml b/themes/linear-es-de/system/metadata-custom/sfc.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sfc.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sg-1000.xml b/themes/linear-es-de/system/metadata-custom/sg-1000.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sg-1000.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sgb.xml b/themes/linear-es-de/system/metadata-custom/sgb.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sgb.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/snes.xml b/themes/linear-es-de/system/metadata-custom/snes.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/snes.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/snesna.xml b/themes/linear-es-de/system/metadata-custom/snesna.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/snesna.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/solarus.xml b/themes/linear-es-de/system/metadata-custom/solarus.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/solarus.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/spectravideo.xml b/themes/linear-es-de/system/metadata-custom/spectravideo.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/spectravideo.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/stv.xml b/themes/linear-es-de/system/metadata-custom/stv.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/stv.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/sufami.xml b/themes/linear-es-de/system/metadata-custom/sufami.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/sufami.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/supergrafx.xml b/themes/linear-es-de/system/metadata-custom/supergrafx.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/supergrafx.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/supervision.xml b/themes/linear-es-de/system/metadata-custom/supervision.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/supervision.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/supracan.xml b/themes/linear-es-de/system/metadata-custom/supracan.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/supracan.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/switch.xml b/themes/linear-es-de/system/metadata-custom/switch.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/switch.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/symbian.xml b/themes/linear-es-de/system/metadata-custom/symbian.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/symbian.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/tanodragon.xml b/themes/linear-es-de/system/metadata-custom/tanodragon.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/tanodragon.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/tg-cd.xml b/themes/linear-es-de/system/metadata-custom/tg-cd.xml new file mode 100644 index 000000000..d6f97715d --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/tg-cd.xml @@ -0,0 +1,10 @@ + + + 5B6559 + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/tg16.xml b/themes/linear-es-de/system/metadata-custom/tg16.xml new file mode 100644 index 000000000..d6f97715d --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/tg16.xml @@ -0,0 +1,10 @@ + + + 5B6559 + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/ti99.xml b/themes/linear-es-de/system/metadata-custom/ti99.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/ti99.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/tic80.xml b/themes/linear-es-de/system/metadata-custom/tic80.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/tic80.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/to8.xml b/themes/linear-es-de/system/metadata-custom/to8.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/to8.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/triforce.xml b/themes/linear-es-de/system/metadata-custom/triforce.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/triforce.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/trs-80.xml b/themes/linear-es-de/system/metadata-custom/trs-80.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/trs-80.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/type-x.xml b/themes/linear-es-de/system/metadata-custom/type-x.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/type-x.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/uzebox.xml b/themes/linear-es-de/system/metadata-custom/uzebox.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/uzebox.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/vectrex.xml b/themes/linear-es-de/system/metadata-custom/vectrex.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/vectrex.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/vic20.xml b/themes/linear-es-de/system/metadata-custom/vic20.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/vic20.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/videopac.xml b/themes/linear-es-de/system/metadata-custom/videopac.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/videopac.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/virtualboy.xml b/themes/linear-es-de/system/metadata-custom/virtualboy.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/virtualboy.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/vpinball.xml b/themes/linear-es-de/system/metadata-custom/vpinball.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/vpinball.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/vsmile.xml b/themes/linear-es-de/system/metadata-custom/vsmile.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/vsmile.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/wasm4.xml b/themes/linear-es-de/system/metadata-custom/wasm4.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/wasm4.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/wii.xml b/themes/linear-es-de/system/metadata-custom/wii.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/wii.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/wiiu.xml b/themes/linear-es-de/system/metadata-custom/wiiu.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/wiiu.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/windows.xml b/themes/linear-es-de/system/metadata-custom/windows.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/windows.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/windows3x.xml b/themes/linear-es-de/system/metadata-custom/windows3x.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/windows3x.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/windows9x.xml b/themes/linear-es-de/system/metadata-custom/windows9x.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/windows9x.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/wonderswan.xml b/themes/linear-es-de/system/metadata-custom/wonderswan.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/wonderswan.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/wonderswancolor.xml b/themes/linear-es-de/system/metadata-custom/wonderswancolor.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/wonderswancolor.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/x1.xml b/themes/linear-es-de/system/metadata-custom/x1.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/x1.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/x68000.xml b/themes/linear-es-de/system/metadata-custom/x68000.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/x68000.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/xbox.xml b/themes/linear-es-de/system/metadata-custom/xbox.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/xbox.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/xbox360.xml b/themes/linear-es-de/system/metadata-custom/xbox360.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/xbox360.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/zmachine.xml b/themes/linear-es-de/system/metadata-custom/zmachine.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/zmachine.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/zx81.xml b/themes/linear-es-de/system/metadata-custom/zx81.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/zx81.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/zxnext.xml b/themes/linear-es-de/system/metadata-custom/zxnext.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/zxnext.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata-custom/zxspectrum.xml b/themes/linear-es-de/system/metadata-custom/zxspectrum.xml new file mode 100644 index 000000000..7e95c8bec --- /dev/null +++ b/themes/linear-es-de/system/metadata-custom/zxspectrum.xml @@ -0,0 +1,7 @@ + + + + ${systemManufacturer} / ${systemReleaseYear} / ${systemHardwareType} + + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/3do.xml b/themes/linear-es-de/system/metadata/3do.xml new file mode 100644 index 000000000..928dd0866 --- /dev/null +++ b/themes/linear-es-de/system/metadata/3do.xml @@ -0,0 +1,17 @@ + + + 3DO Interactive Multiplayer + The 3DO Interactive Multiplayer (often called simply 3DO) is a video game console originally produced by Panasonic in 1993. Further renditions of the hardware were released in 1994 by Sanyo and Goldstar. The consoles were manufactured according to specifications created by The 3DO Company, and were originally designed by Dave Needle and RJ Mical of New Technology Group. The system was conceived by entrepreneur and Electronic Arts founder Trip Hawkins. + Panasonic + 1993 + 1993-10-04 + October 4, 1993 + Console + 1-2 + CFA83E + FF0000 + 0000A0 + FFE41B + 23B14D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/README.md b/themes/linear-es-de/system/metadata/README.md new file mode 100644 index 000000000..3ecbee999 --- /dev/null +++ b/themes/linear-es-de/system/metadata/README.md @@ -0,0 +1,88 @@ +# System Metadata Files for ES-DE +This repo contains XML files that add system metadata variables for use in themes created for [ES-DE](https://es-de.org/) + +The files leverage ES-DE variables to allow the values to be used in any theme agnostic of how the theme is structured. + +It also includes a `_default.xml` that can be used as a temporary fallback for when new systems are added to ES-DE + +Each file provides the following metadata variables: +- `systemDescription` - A description of the system +- `systemReleaseYear` - The year the system was released (when available) +- `systemReleaseDate` - The date the system was released in ISO 8601 (`YYYY-MM-DD`) format. If only the month and year was known then the format is `YYYY-MM`. If only the year was known then the format is `YYYY`. +- `systemReleaseDateFormated` - A formated version of the release date in `Month Day, Year` format. If only the month and year was known then the format is `Month Year`. If only the year was known then the format is `Year`. +- `systemManufacturer` - Represents the original Manufacturer of the system. +- `systemHardwareType` - A value to represent the systems type (e.g. `Console`. `Portable`, `Computer`, etc...) +- `systemColor` - A hex value to represent a systems primary color (can be used for things like backgrounds or navigation highlights) +- `systemColorPalette1...4` - 4 different hex values to represent other colors that can be used for a system (useful for things like color bands) +- `systemCoverSize` - Represents the common aspect ratio for a given system's cover artwork. Can be used to customize the size of grids and carousels that display cover art. + - Current set of sizes: `4-3`, `1-1`, `3-4`, `1-2`, `3-5`, `5-7`, `243-340`, `257-229` + - Using these values you can define width/height for just this set and those sizes will apply automatically to a given system. + +## **Usage** +1. Download the latest release of this repo and place it in a dedicated folder in your theme. + - I recommend a dedicated folder like this: `/_inc/systems/metadata-global/` + - This approach will make it easier to update when changes are made. +2. Include a reference to files at the top of your root theme.xml file + - As an example; I add the following includes in my themes: + - `./_inc/systems/metadata-global/_default.xml` - default file for fallback use cases + - `./_inc/systems/metadata-global/${system.theme}.xml` - the system specific xml file +3. Reference a value using the variable names listed above + - For example if you wanted to add system specific colors to a UI element you would refernece `${systemColor}` for that value + +## **Contributions** +- If you see any existing values that should be updated with more accurate data; please submit an issue or PR to this repo. Make sure to include the system, specific change and the reason for the change in your request. +- If you have an idea for a new variable to add; please submitt an issue to this repo with details of the variable and what it could be used for. + +## **Examples** + +| [CarAlt)](https://github.com/Weestuarty/caralt-es-de) | [Chicuelo (Revisited](https://github.com/anthonycaccese/chicuelo-revisited-es-de) | +| :---: | :---: | +| ![CarAlt](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/eebb8d45-b881-482f-bac0-31888ab12fcd) | ![chicuelo](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/74411202-1985-40ee-8cf6-8e9e1d4b9cc1) | +| Implements: `systemDescription` | Implements: `systemDescription`, `systemReleaseYear` and `systemHardwareType` | + +| [CodyWheel](https://github.com/Weestuarty/codywheel-es-de) | [CoinOPS](https://github.com/TheGrizzMD/coinops-es-de) | +| :---: | :---: | +| ![codywheel](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/6ea5c477-371e-4bb9-b090-a200a8588282) | ![coinops](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/50f75c6e-04e3-41a6-af74-358bb45403f8) | +| Implements: `systemDescription`, `systemReleaseYear`, `systemManufacturer` and `systemHardwareType` | Implements: `systemDescription` | + +| [Colorful (Revisited)](https://github.com/anthonycaccese/colorful-revisited-es-de) | [Colorful (Simplified)](https://github.com/anthonycaccese/colorful-simplified-es-de) | +| :---: | :---: | +| ![colorful-revisited](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/9b79ccc8-e0d7-43ae-b865-40f7bf740267) | ![colorful-simplified](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/35fcfbf4-eb08-4682-ae09-4fa3b5b8060b) | +| Implements: `systemColor`, `systemDescription`, `systemManufacturer`, `systemReleaseYear`, and `systemHardwareType` | Implements: `systemColor`, `systemDescription`, `systemManufacturer`, `systemReleaseYear`, `systemCoverSize`, and `systemHardwareType` | + +| [Diamond](https://github.com/Weestuarty/diamond-es-de) | [Epic Noir (Next)](https://github.com/anthonycaccese/epic-noir-next-es-de) | +| :---: | :---: | +| ![diamond](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/378c8a8a-2e9f-4cbc-aab6-6f269218699f) | ![epic-noir-next](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/bc45b7fa-874f-4107-852f-9c1c3a0dfcc3) | +| Implements: `systemManufacturer` and `systemReleaseYear` | Implements: `systemColor`, `systemDescription`, `systemReleaseYear`, and `systemHardwareType` | + +| [Epic Noir (Revisited)](https://github.com/anthonycaccese/epic-noir-revisited-es-de) | [ForAll](https://github.com/Weestuarty/forall-es-de) | +| :---: | :---: | +| ![epic-noir-revisited](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/98c74c60-42a7-4b3e-b129-ed4156dbc070) | ![forall](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/01b12f6f-f18d-4b9f-9a2d-842b10e3b3d0) | +| Implements: `systemDescription`, `systemReleaseYear`, and `systemHardwareType` | Implements: `systemDescription` | + +| [NSO Menu (Interpreted)](https://github.com/anthonycaccese/nso-menu-interpreted-es-de) | [Retrofix (Revisited)](https://github.com/anthonycaccese/retrofix-revisited-es-de) | +| :---: | :---: | +| ![nso-menu](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/f483899f-56f0-4230-8bca-afed9aab63d4) | ![retrofix](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/cda97089-7611-47be-8a19-bff469c69e42) | +| Implements: `systemColor` and `systemCoverSize` | Implements: `systemColor` | + +| [Showcase](https://github.com/Weestuarty/showcase-es-de) | [SimCar](https://github.com/Weestuarty/simcar-es-de) | +| :---: | :---: | +| ![showcase](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/2b27affe-ed6c-437b-9569-cf4ded74061d) | ![simcar](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/dc1dae0e-a452-4c4a-83c5-05ce81a22ed6) | +| Implements: `systemDescription` | Implements: `systemDescription` | + +| [TexGriddy](https://github.com/Weestuarty/texgriddy-es-de) | +| :---: | +| ![textgriddy](https://github.com/anthonycaccese/nso-menu-interpreted-es-de/assets/1454947/ff0dc121-a943-4096-9d96-27ddaeea974f) | +| Implements: `systemDescription` | + + +## **Credits** +* Some descriptions, release dates & manufacturer details were sourced from the wikipedia entries for each system +* Some descriptions were sourced from [ckau-book](https://github.com/CkauNui/ckau-book/tree/master) +* Some release date and manufacturer details were sourced from the [Launchbox](https://gamesdb.launchbox-app.com/) platforms list +* System colors were sourced from the great work done by [viking](https://forums.launchbox-app.com/profile/70421-viking/) from their work on the [Colorful](https://forums.launchbox-app.com/files/file/2081-colorful-bigbox-theme) theme for Launchbox and [@rogs123](https://github.com/rogs123) from their work on the [NSO Menu](https://github.com/anthonycaccese/nso-menu-interpreted-es-de) theme for ES-DE +* System Cover sizes were sourced from examples on screenscraper.fr + +## **License** +Creative Commons CC-BY-NC-SA - https://creativecommons.org/licenses/by-nc-sa/2.0/ +You are free to share and adapt these files as long as you provide attribution back as well share any updates you make under the same licence terms. \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/_default.xml b/themes/linear-es-de/system/metadata/_default.xml new file mode 100644 index 000000000..68d71ebcf --- /dev/null +++ b/themes/linear-es-de/system/metadata/_default.xml @@ -0,0 +1,17 @@ + + + ${system.fullName} + View and play the ${system.fullName} + + + + + System + 1-1 + 222222 + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/adam.xml b/themes/linear-es-de/system/metadata/adam.xml new file mode 100644 index 000000000..396c019cd --- /dev/null +++ b/themes/linear-es-de/system/metadata/adam.xml @@ -0,0 +1,17 @@ + + + Coleco Adam + The Coleco Adam is a home computer and expansion device for the ColecoVision by American toy and video game manufacturer Coleco. The Adam was an attempt to follow on the success of the company's ColecoVision video game console. It was available as Expansion Module #3 for the ColecoVision, converting it into a home computer, and as a standalone unit. As such, it had the benefit of being entirely compatible with all ColecoVision games and peripherals. The computer came with 64 KB of memory, a tape drive for a proprietary medium called Digital Data Packs, a daisy wheel printer, and productivity applications, along with two DDPs for SmartBASIC and Buck Rogers: Planet of Zoom Super Game. It was released in October 1983 with the initial price of $700. + Coleco + 1983 + 1983-10 + October 1983 + Computer + 1-1 + 5A93AF + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ags.xml b/themes/linear-es-de/system/metadata/ags.xml new file mode 100644 index 000000000..e3162e431 --- /dev/null +++ b/themes/linear-es-de/system/metadata/ags.xml @@ -0,0 +1,17 @@ + + + Adventure Game Studio + Adventure Game Studio (AGS) is an open source development tool primarily used to create graphic adventure games. It is aimed at intermediate-level game designers, and combines an integrated development environment (IDE) with a scripting language based on the C programming language to process game logic. + Chris Jones + 1997 + 1997 + 1997 + Engine + 1-1 + 4B73E0 + 9FCFFF + 63B6FF + 2C90FF + 9FCFFF + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/amiga.xml b/themes/linear-es-de/system/metadata/amiga.xml new file mode 100644 index 000000000..01e5c7565 --- /dev/null +++ b/themes/linear-es-de/system/metadata/amiga.xml @@ -0,0 +1,17 @@ + + + Amiga + The Amiga is a family of personal computers marketed by Commodore in the 1980s and 1990s. The first model was launched in 1985 as a high-end home computer and became popular for its graphical, audio and multi-tasking abilities. The Amiga provided a significant upgrade from 8-bit computers, such as the Commodore 64, and the platform quickly grew in popularity among computer enthusiasts. The best selling model, the Amiga 500, was introduced in 1987 and became the leading home computer of the late 1980s and early 1990s in much of Western Europe. + Commodore + 1985 + 1985-07-23 + July 23, 1985 + Computer + 3-4 + 3870c5 + 477AB1 + 82B030 + F3EB08 + E85629 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/amiga1200.xml b/themes/linear-es-de/system/metadata/amiga1200.xml new file mode 100644 index 000000000..463f91e3b --- /dev/null +++ b/themes/linear-es-de/system/metadata/amiga1200.xml @@ -0,0 +1,17 @@ + + + Amiga 1200 + The Amiga is a family of personal computers marketed by Commodore in the 1980s and 1990s. The first model was launched in 1985 as a high-end home computer and became popular for its graphical, audio and multi-tasking abilities. The Amiga provided a significant upgrade from 8-bit computers, such as the Commodore 64, and the platform quickly grew in popularity among computer enthusiasts. The best selling model, the Amiga 500, was introduced in 1987 and became the leading home computer of the late 1980s and early 1990s in much of Western Europe. + Commodore + 1985 + 1985-07-23 + July 23, 1985 + Computer + 3-4 + 2671C6 + 192753 + 5F87C0 + F3AD2D + ED2224 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/amiga600.xml b/themes/linear-es-de/system/metadata/amiga600.xml new file mode 100644 index 000000000..286272412 --- /dev/null +++ b/themes/linear-es-de/system/metadata/amiga600.xml @@ -0,0 +1,17 @@ + + + Amiga 600 + The Amiga is a family of personal computers marketed by Commodore in the 1980s and 1990s. The first model was launched in 1985 as a high-end home computer and became popular for its graphical, audio and multi-tasking abilities. The Amiga provided a significant upgrade from 8-bit computers, such as the Commodore 64, and the platform quickly grew in popularity among computer enthusiasts. The best selling model, the Amiga 500, was introduced in 1987 and became the leading home computer of the late 1980s and early 1990s in much of Western Europe. + Commodore + 1985 + 1985-07-23 + July 23, 1985 + Computer + 3-4 + C171A5 + 192753 + 5BA079 + F9EA38 + ED2224 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/amigacd32.xml b/themes/linear-es-de/system/metadata/amigacd32.xml new file mode 100644 index 000000000..73951ab09 --- /dev/null +++ b/themes/linear-es-de/system/metadata/amigacd32.xml @@ -0,0 +1,17 @@ + + + Amiga CD32 + The Amiga CD32, styled "CD32" and code-named "Spellbound", is the first 32-bit home video game console released in western Europe, Australia, Canada and Brazil. It was first announced at the Science Museum in London on July 16, 1993, and was released in September of the same year. The CD32 uses CD-ROM media, and was developed by Commodore, creator of the Commodore Amiga computer. It was based on Commodore's Advanced Graphics Architecture chipset, and is of similar specification to the Amiga 1200 computer. Using third party devices, it is possible to upgrade the CD32 with keyboard, floppy drive, hard drive, RAM and mouse, turning it into the equivalent of an Amiga 1200 personal computer. A hardware MPEG decompression module for playing Video CD was also released. In the Christmas period following its launch, the CD32 accounted for 38% of all CD-ROM drive sales in the UK, exceeding sales of the Mega-CD; however, it was soon overshadowed by CD-ROM based games consoles from other companies, and was discontinued as Commodore went into bankruptcy. + Commodore + 1993 + 1993-09-17 + September 17, 1993 + Console + 1-1 + DD4637 + FF5853 + 47DEBA + FFDF46 + 4A9BE4 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/amstradcpc.xml b/themes/linear-es-de/system/metadata/amstradcpc.xml new file mode 100644 index 000000000..684762920 --- /dev/null +++ b/themes/linear-es-de/system/metadata/amstradcpc.xml @@ -0,0 +1,17 @@ + + + Amstrad CPC + The Amstrad Colour Personal Computer, better known as the Amstrad CPC, is a series of 8-bit home computers designed by Amstrad. The first models were released in April 1984 in Europe at a retail price ranging from £199 to £299, depending on the package bought. The computers were not released outside of Europe. The CPC series had five distinct models: The CPC464, CPC664, CPC6128, 464plus, and 6128plus. The computers were manufactured until an unspecified time in 1990. + Amstrad + 1984 + 1984-01-01 + January 1, 1984 + Computer + 3-4 + 54819D + E91C23 + 00A651 + 1C75BC + 3E3E3E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/android.xml b/themes/linear-es-de/system/metadata/android.xml new file mode 100644 index 000000000..009e47045 --- /dev/null +++ b/themes/linear-es-de/system/metadata/android.xml @@ -0,0 +1,17 @@ + + + Google Android + Android is a mobile operating system based on a modified version of the Linux kernel and other open-source software, designed primarily for touchscreen mobile devices such as smartphones and tablets. Android is developed by a consortium of developers known as the Open Handset Alliance, though its most widely used version is primarily developed by Google. It was unveiled in November 2007, with the first commercial Android device, the HTC Dream, being launched in September 2008. + Google + 2008 + 2008-09-23 + September 23, 2008 + OS + 1-1 + 5A9035 + 4086F4 + EB4132 + FBBD00 + 31AA52 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/apple2.xml b/themes/linear-es-de/system/metadata/apple2.xml new file mode 100644 index 000000000..d0e4dfc02 --- /dev/null +++ b/themes/linear-es-de/system/metadata/apple2.xml @@ -0,0 +1,17 @@ + + + Apple II + In 1976, computer pioneers Steve Wozniak and Steve Jobs began selling their Apple I computer in kit form to computer stores. A month later, Wozniak was working on a design for an improved version, the Apple II. They demonstrated a prototype in December, and then introduced it to the public in April 1977. The Apple II started the boom in personal computer sales in the late 1970s, and pushed Apple into the lead among personal computer makers. + Apple + 1977 + 1977-06-01 + June 1, 1977 + Computer + 3-4 + 26A9E1 + 009DDC + E03A3E + FDB827 + 61BB46 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/apple2gs.xml b/themes/linear-es-de/system/metadata/apple2gs.xml new file mode 100644 index 000000000..5e63c847d --- /dev/null +++ b/themes/linear-es-de/system/metadata/apple2gs.xml @@ -0,0 +1,17 @@ + + + Apple IIGS + The Apple IIGS is a personal computer released by Apple Computer on September 15, 1986 that's compatible with the Apple II series, but otherwise has capabilities comparable to the Atari ST, Commodore Amiga, and Macintosh. The "GS" in the name stands for "Graphics" and "Sound," referring to its enhanced multimedia hardware, especially its state of the art sound and music synthesis. The machine is a radical departure from any previous Apple II, with its 16-bit processor, direct access to megabytes of RAM, and mouse. It's the first computer produced by Apple to use a color graphical user interface (color was introduced on the Macintosh II six months later) and Apple Desktop Bus interface for keyboards, mice, and other input devices. It is the first personal computer to come with a built-in wavetable synthesis chip, utilizing technology from Ensoniq. + Apple + 1986 + 1986-09-15 + September 15, 1986 + Computer + 1-1 + 4F65D2 + D27C35 + C44243 + E3AD3A + 8C3E8C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/arcade.xml b/themes/linear-es-de/system/metadata/arcade.xml new file mode 100644 index 000000000..401503f36 --- /dev/null +++ b/themes/linear-es-de/system/metadata/arcade.xml @@ -0,0 +1,17 @@ + + + Arcade + An arcade game or coin-op is a coin-operated entertainment machine typically installed in public businesses such as restaurants, bars and amusement arcades. Most arcade games are video games, pinball machines, electro-mechanical games, redemption games or merchandisers. While exact dates are debated, the golden age of arcade video games is usually defined as a period beginning sometime in the late 1970s and ending sometime in the mid-1980s. Excluding a brief resurgence in the early 1990s, the arcade industry subsequently declined in the Western hemisphere as competing home-based video game consoles such as Playstation and Xbox increased in their graphics and game-play capability and decreased in cost. + Various + Various + Various + Various + Collection + 3-4 + 5B60B7 + FA6E0D + FCCD0A + 032EC0 + 459FD0 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/arcadia.xml b/themes/linear-es-de/system/metadata/arcadia.xml new file mode 100644 index 000000000..a464f19f8 --- /dev/null +++ b/themes/linear-es-de/system/metadata/arcadia.xml @@ -0,0 +1,17 @@ + + + Arcadia 2001 + The Arcadia 2001 is a second-generation 8-bit home video game console released by Emerson Radio in May 1982 for a price of US$ 99, several months before the release of ColecoVision. It was discontinued only 18 months later, with a total of 35 games having been released. Emerson licensed the Arcadia 2001 to Bandai, which released it in Japan. Over 30 Arcadia 2001 clones exist. + Emerson Radio + 1982 + 1982-05 + May 1982 + Console + 1-1 + D59234 + 1E35A0 + 2FBB37 + C70A11 + 000000 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/archimedes.xml b/themes/linear-es-de/system/metadata/archimedes.xml new file mode 100644 index 000000000..d85cbf209 --- /dev/null +++ b/themes/linear-es-de/system/metadata/archimedes.xml @@ -0,0 +1,17 @@ + + + Acorn Archimedes + The Acorn Archimedes is a family of personal computers designed by Acorn Computers of Cambridge, England. The systems are based on Acorn's own ARM architecture processors and the proprietary operating systems Arthur and RISC OS. The first models were introduced in 1987, and systems in the Archimedes family were sold until the mid-1990s. + Acorn + 1987 + 1987-06 + June 1987 + Computer + 3-4 + 008CAC + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/arduboy.xml b/themes/linear-es-de/system/metadata/arduboy.xml new file mode 100644 index 000000000..3177871bb --- /dev/null +++ b/themes/linear-es-de/system/metadata/arduboy.xml @@ -0,0 +1,17 @@ + + + Arduboy + The Arduboy is a handheld game console with open source software, based on the Arduino hardware platform. + Kevin Bates + 2015 + 2015 + 2015 + Portable + 1-1 + 5F459C + BA6FDB + 8B2DB4 + 8664E3 + 6442C1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/astrocade.xml b/themes/linear-es-de/system/metadata/astrocade.xml new file mode 100644 index 000000000..4b763a2b7 --- /dev/null +++ b/themes/linear-es-de/system/metadata/astrocade.xml @@ -0,0 +1,20 @@ + + + Bally Astrocade + The Bally Astrocade (also known as Bally Arcade or initially as Bally ABA-1000) is a second-generation home video game console and simple computer system designed by a team at Midway, at that time the videogame division of Bally. +It was originally announced as the "Bally Home Library Computer" in October 1977 and initially made available for mail order in December 1977. But due to production delays, the units were first released to stores in April 1978 and its branding changed to "Bally Professional Arcade". + +It was marketed only for a limited time before Bally decided to exit the market. The rights were later picked up by a third-party company, who re-released it and sold it until around 1984. The Astrocade is particularly notable for its very powerful graphics capabilities for the time of release and for the difficulty in accessing those capabilities. + Bally + 1977 + 1977-12-01 + December 1, 1977 + Console + 1-1 + D59334 + F2B101 + FA0105 + F8F6EA + C47401 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atari2600.xml b/themes/linear-es-de/system/metadata/atari2600.xml new file mode 100644 index 000000000..ba5cf3dde --- /dev/null +++ b/themes/linear-es-de/system/metadata/atari2600.xml @@ -0,0 +1,17 @@ + + + Atari 2600 + The Atari Video Computer System (VCS), later named the Atari 2600, is a second generation (1976–1992) home video game console developed and distributed by Atari, Inc. It was released on September 11, 1977 in North America at a retail price of $199. The console was later released in Europe (1978) and Japan (1983 - as the Atari 2800). The Atari 2600 popularized the use of microprocessor-based hardware and games contained on ROM cartridges. The console was discontinued on January 1, 1992. + Atari + 1977 + 1977-09-11 + September 11, 1977 + Console + 3-4 + b92e35 + 6D391F + D4282D + D1E0EE + 222222 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atari5200.xml b/themes/linear-es-de/system/metadata/atari5200.xml new file mode 100644 index 000000000..cf98fdb9b --- /dev/null +++ b/themes/linear-es-de/system/metadata/atari5200.xml @@ -0,0 +1,17 @@ + + + Atari 5200 + The Atari 5200 SuperSystem, commonly known as the Atari 5200, is a second generation (1976–1992) video game console developed and distributed by Atari, Inc. It was released in November 1982 in North America at a retail price of $269. It was not released outside North America. The 5200's internal hardware was almost identical to Atari's 8-bit computers however it came with an innovative controller featuring a 360-degree non-centering joystick with a numeric keypad, start, pause, and reset buttons. The console was discontinued on May 21, 1984. + Atari + 1982 + 1982-11-01 + November 1, 1982 + Console + 3-4 + 3D5799 + 1E6547 + CFA634 + 973E3A + 1C6EB8 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atari7800.xml b/themes/linear-es-de/system/metadata/atari7800.xml new file mode 100644 index 000000000..f8bdb8315 --- /dev/null +++ b/themes/linear-es-de/system/metadata/atari7800.xml @@ -0,0 +1,17 @@ + + + Atari 7800 + The Atari 7800 Pro System, commonly known as the Atari 7800, is a third generation (1983-2003) video game console developed and distributed by Atari Corporation. It was released in May 1986 in North America at a retail price of $79.95. The console was later released in Europe (1987). The 7800 is considered one of the first backward-compatible consoles as it could play Atari 2600 games without the use of additional modules. The console was discontinued on January 1, 1992. + Atari + 1986 + 1986-05-01 + May 1, 1986 + Console + 3-4 + 2D7AC6 + BABBBD + AA2C39 + A7B0B5 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atari800.xml b/themes/linear-es-de/system/metadata/atari800.xml new file mode 100644 index 000000000..c1d37c8a9 --- /dev/null +++ b/themes/linear-es-de/system/metadata/atari800.xml @@ -0,0 +1,19 @@ + + + Atari 800 + The Atari 8-bit family is a series of 8-bit home computers introduced by Atari, Inc. in 1979 as the Atari 400 and Atari 800 and manufactured until 1992. All of the machines in the family are technically similar and differ primarily in packaging. They are based on the MOS Technology 6502 CPU running at 1.79 MHz, and were the first home computers designed with custom coprocessor chips. This architecture enabled graphics and sound more advanced than contemporary machines, and gaming was a major draw. First-person space combat simulator Star Raiders is considered the platform's killer app. The systems launched with plug and play peripherals using the Atari SIO serial bus, an early analog of USB. + +The Atari 400 was initially almost half the cost of the Atari 800. Instead of the 800's full-sized keyboard, the 400 has a pressure-sensitive panel. The 800 has a second cartridge slot and a larger case allowing RAM upgrades to 48K. Both models were replaced by the XL series in 1983, then–after the company was sold and reestablished as Atari Corporation–the XE models in 1985. The XL and XE are lighter in construction while having Atari BASIC built-in and 2 joystick ports instead of 4. The 130XE increased the memory to 128 KB of bank-switched RAM. + Atari + 1979 + 1979-11-01 + November 1, 1979 + Computer + 3-4 + CC9141 + B6B896 + EBD335 + 5D3615 + BF9438 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atarijaguar.xml b/themes/linear-es-de/system/metadata/atarijaguar.xml new file mode 100644 index 000000000..2ffb1221d --- /dev/null +++ b/themes/linear-es-de/system/metadata/atarijaguar.xml @@ -0,0 +1,17 @@ + + + Atari Jaguar + The Atari Jaguar is a fifth generation (1993–2005) video game console developed and distributed by Atari Corporation. It was released in November 1993 in North America at a retail price of $249.99. The console was later released in Europe (1994), Australia (1994), and Japan (1994). The Jaguar was marketed as being the first 64-bit video game console; however this claim was widely criticized. The console was discontinued in early 1996, possibly at the time of the company's sale on April 8, 1996. + Atari + 1993 + 1993-11-23 + November 23, 1993 + Console + 3-4 + CD3C3B + FF0000 + FDC007 + 232326 + 0F0E0E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atarijaguarcd.xml b/themes/linear-es-de/system/metadata/atarijaguarcd.xml new file mode 100644 index 000000000..064120dae --- /dev/null +++ b/themes/linear-es-de/system/metadata/atarijaguarcd.xml @@ -0,0 +1,17 @@ + + + Atari Jaguar CD + The Atari Jaguar CD is a fifth generation (1993–2005) CD-ROM peripheral for the Atari Jaguar video game console developed and distributed by Atari Corporation. It was released in September 1995 in North America at a retail price of $149.95. The peripheral was also released in Europe (1995). The Jaguar CD unit featured a double-speed (2×) drive and its own cartridge slot to allow cartridge games to be played without removing the CD drive. The peripheral was discontinued in early 1996, possibly at the time of the company's sale on April 8, 1996. + Atari + 1995 + 1995-11-21 + September 21, 1995 + Console + 3-4 + 2F7BC7 + FF0000 + 3F3E3E + FDC007 + 232326 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atarilynx.xml b/themes/linear-es-de/system/metadata/atarilynx.xml new file mode 100644 index 000000000..799c75866 --- /dev/null +++ b/themes/linear-es-de/system/metadata/atarilynx.xml @@ -0,0 +1,17 @@ + + + Atari Lynx + The Atari Lynx, usually just referred to as Lynx, is a fourth generation (1987-2004) handheld video game console developed in partnership with Epyx, Inc. and distributed by the Atari Corporation. It was released in September 1989 in North America at a retail price of $149.95. The handheld was also released in Europe (1990) and Japan (1990). The Lynx was the world's first handheld electronic game with a color LCD screen. The console was discontinued in early 1996, possibly at the time of the company's sale on April 8, 1996. + Atari + 1989 + 1989-09-01 + September 1, 1989 + Portable + 3-4 + E19735 + FD6420 + 404040 + F38900 + 262626 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atarist.xml b/themes/linear-es-de/system/metadata/atarist.xml new file mode 100644 index 000000000..89c4abaae --- /dev/null +++ b/themes/linear-es-de/system/metadata/atarist.xml @@ -0,0 +1,21 @@ + + + Atari ST + The Atari ST is a line of home computers from Atari Corporation and the successor to the Atari 8-bit family. The initial model, the 520ST, saw limited release in April–June 1985 and was widely available in July. The 520ST is the first personal computer to come with a bitmapped color GUI, using a version of Digital Research's GEM released in February 1985. The 1040ST, released in 1986, is the first personal computer to ship with a megabyte of RAM in the base configuration and also the first with a cost-per-kilobyte of less than US$1. + +The Atari ST is part of a mid-1980s generation of home computers that have 16 or 32-bit processors, 256 KB or more of RAM, and mouse-controlled graphical user interfaces. This generation includes the Macintosh, Amiga, Apple IIGS, and in some markets the Acorn Archimedes. "ST" officially stands for "Sixteen/Thirty-two", which refers to the Motorola 68000's 16-bit external bus and 32-bit internals. + +The ST was sold with either Atari's color monitor or the less expensive monochrome monitor. The system's color graphics modes are only available on the former while the highest-resolution mode needs the monochrome monitor. + Atari + 1985 + 1985-06-01 + June 1, 1985 + Computer + 3-4 + 0088D1 + 172E7E + 3C62A7 + 000000 + ECECEC + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atarixe.xml b/themes/linear-es-de/system/metadata/atarixe.xml new file mode 100644 index 000000000..d1cf3eb54 --- /dev/null +++ b/themes/linear-es-de/system/metadata/atarixe.xml @@ -0,0 +1,17 @@ + + + Atari XE + The Atari XE Video Game System (Atari XEGS) is an industrial redesign of the Atari 65XE home computer and the final model in the Atari 8-bit family. It was released by Atari Corporation in 1987 and marketed as a home video game console alongside the Nintendo Entertainment System, Sega's Master System, and Atari's own Atari 7800. The XEGS is compatible with existing Atari 8-bit family hardware and software. Without keyboard, the system operates as a stand-alone game console. With the keyboard, it boots identically to the Atari XE computers. Atari packaged the XEGS as a basic set consisting of only the console and joystick, and as a deluxe set consisting of the console, keyboard, CX40 joystick, and XG-1 light gun. + Atari + 1987 + 1987 + 1987 + Console + 1-1 + 2F7BC7 + E1D095 + ADC7EF + 8F8F91 + B9A9CE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/atomiswave.xml b/themes/linear-es-de/system/metadata/atomiswave.xml new file mode 100644 index 000000000..19988c263 --- /dev/null +++ b/themes/linear-es-de/system/metadata/atomiswave.xml @@ -0,0 +1,17 @@ + + + Atomiswave + The Atomiswave is a custom arcade system board and cabinet from Sammy Corporation. It is based on Sega's NAOMI system board (thus it's common to see the "Sega" logo on its boot up screen). The Atomiswave uses interchangeable game cartridges and the cabinet's control panel can be easily switched out with different control sets, including dual joysticks, dual lightguns and a steering wheel. With the retirement of the aging Neo Geo MVS system, SNK Playmore chose the Atomiswave as its next system to develop games for. In a contract with Sammy, SNK Playmore agreed to develop five games for the Atomiswave system. Metal Slug 6 was SNK Playmore's fifth game for the Atomiswave, after which SNK moved on to a Taito Type X2 arcade board. + Sammy + 2003 + 2003-01-01 + January 1, 2003 + Arcade + 3-4 + 37BD6E + C11127 + FF6B00 + 04EF94 + 029205 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/auto-allgames.xml b/themes/linear-es-de/system/metadata/auto-allgames.xml new file mode 100644 index 000000000..4dd9911aa --- /dev/null +++ b/themes/linear-es-de/system/metadata/auto-allgames.xml @@ -0,0 +1,12 @@ + + + All Games + View and play every game across your entire library. + Various + Various + Various + Various + Collection + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/auto-favorites.xml b/themes/linear-es-de/system/metadata/auto-favorites.xml new file mode 100644 index 000000000..9c130b77d --- /dev/null +++ b/themes/linear-es-de/system/metadata/auto-favorites.xml @@ -0,0 +1,12 @@ + + + Favorites + View and play your favorite games across the entire library. + Various + Various + Various + Various + Collection + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/auto-lastplayed.xml b/themes/linear-es-de/system/metadata/auto-lastplayed.xml new file mode 100644 index 000000000..fe49f6a50 --- /dev/null +++ b/themes/linear-es-de/system/metadata/auto-lastplayed.xml @@ -0,0 +1,12 @@ + + + Last Played + View your recently played games across the entire library. + Various + Various + Various + Various + Collection + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/bbcmicro.xml b/themes/linear-es-de/system/metadata/bbcmicro.xml new file mode 100644 index 000000000..2b25cca49 --- /dev/null +++ b/themes/linear-es-de/system/metadata/bbcmicro.xml @@ -0,0 +1,17 @@ + + + BBC Micro + The British Broadcasting Corporation Microcomputer System, BBC Microcomputer System, or best known as the BBC Micro is a series of microcomputers designed by Acorn Computers Ltd. and distributed by the BBC. The first models were released in December 1981 in Europe for £235 or £335, depending on the model. The computers were also released in North America (1983). The computers were designed with an emphasis on education, and being more rugged then other brands. The computers were manufactured until an unspecified time in 1994. + Acorn Computers + 1981 + 1981-12-01 + December 1, 1981 + Computer + 3-4 + 5B6559 + 1F0200 + F9F8E1 + AE492D + 635B4F + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/c64.xml b/themes/linear-es-de/system/metadata/c64.xml new file mode 100644 index 000000000..24eebe193 --- /dev/null +++ b/themes/linear-es-de/system/metadata/c64.xml @@ -0,0 +1,17 @@ + + + Commodore 64 + The Commodore 64 is an 8-bit home computer introduced in January 1982 by Commodore International. It is listed in the Guinness World Records as the highest-selling single computer model of all time, with independent estimates placing the number sold between 10 and 17 million units. Volume production started in early 1982, marketing in August for US$595 (equivalent to $1,461 in 2015). Preceded by the Commodore VIC-20 and Commodore PET, the C64 took its name from its 64 kilobytes (65,536 bytes) of RAM. It had superior sound and graphical specifications compared to other earlier systems such as the Apple II and Atari 800, with multi-color sprites and a more advanced sound processor. + Commodore + 1982 + 1982-01-01 + January 1, 1982 + Computer + 3-4 + 0F5BAD + BBAD93 + 968971 + FD4120 + 00A0C6 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cavestory.xml b/themes/linear-es-de/system/metadata/cavestory.xml new file mode 100644 index 000000000..64575a234 --- /dev/null +++ b/themes/linear-es-de/system/metadata/cavestory.xml @@ -0,0 +1,15 @@ + + + Cave Story, originally released as Dōkutsu Monogatari, is a 2004 Metroidvania platform-adventure game for Microsoft Windows. It was developed over five years by Japanese independent developer Daisuke "Pixel" Amaya in his free time. Cave Story features 2D platform mechanics and is reminiscent of the games Amaya played in his youth, such as Metroid and Castlevania. After its initial self-published release, the game slowly gained popularity on the internet. It received widespread critical acclaim for many polished aspects of its design, such as its compelling characters, setting, story, and gameplay. Cave Story is considered by many as the quintessential indie game because of its one-person development team and influence on the video gaming world. NXENGINE is a complete open-source clone/rewrite of the masterpiece jump-and-run platformer Doukutsu Monogatari (also known as Cave Story) + Studio Pixel + 2004 + 2004-12-20 + December 20, 2004 + Engine + CE413E + 648DBD + B63523 + 6F1312 + 182142 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cdimono1.xml b/themes/linear-es-de/system/metadata/cdimono1.xml new file mode 100644 index 000000000..0188e459a --- /dev/null +++ b/themes/linear-es-de/system/metadata/cdimono1.xml @@ -0,0 +1,17 @@ + + + Philips CD-i + The Philips CD-i (Compact Disc Interactive) is an interactive multimedia CD player developed and marketed by Royal Philips Electronics N.V. This category of device was created to provide more functionality than an audio CD player or game console, but at a lower price than a personal computer with CD-ROM drive at the time. The cost savings were due to the lack of a hard drive, floppy drive, keyboard, mouse, monitor (a standard television was used), and less operating system software. In addition to games, educational and multimedia reference titles were produced, such as interactive encyclopedias, museum tours, etc. before public Internet access was widespread. Competitors included the Tandy VIS and Commodore CDTV. Seen as a game console, the CD-i format proved to be a commercial failure. The company lost nearly one billion dollars on the entire project. The failure of the CD-i caused Philips to leave the video game industry after it was discontinued. The CD-i is also one of the earliest consoles to implement internet features, including subscriptions, web browsing, downloading, e-mail, and online play. This was facilitated by the use of an additional hardware modem that Philips released in 1996. + Philips + 1991 + 1991-12-03 + December 3, 1991 + Console + 1-1 + BE70A4 + 000000 + E70000 + FFFFFF + 0B5ED8 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cdtv.xml b/themes/linear-es-de/system/metadata/cdtv.xml new file mode 100644 index 000000000..4a1530504 --- /dev/null +++ b/themes/linear-es-de/system/metadata/cdtv.xml @@ -0,0 +1,17 @@ + + + CDTV + The CDTV (an acronym for "Commodore Dynamic Total Vision", a backronym of an acronym for "Compact Disc Television", giving it a double meaning) is a multimedia platform developed by Commodore International and launched in March 1991. The CDTV was intended as a media appliance rather than a personal computer. + Commodore + 1991 + 1991-03-01 + March 1, 1991 + Console + 1-1 + 775EBA + C86388 + 6F62E8 + 1CA6F1 + F62717 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/chailove.xml b/themes/linear-es-de/system/metadata/chailove.xml new file mode 100644 index 000000000..e742890b6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/chailove.xml @@ -0,0 +1,17 @@ + + + ChaiLove Framework + ChaiLove is an awesome framework you can use to make 2D games in ChaiScript. It's free, open-source, and works on Windows, Mac OS X, Linux, Android, and ARM through libretro/RetroArch. + ChaiLove Team + 2017 + 2017-11-30 + November 30, 2017 + Engine + 1-1 + 26AAE0 + 0080E8 + AEE7FF + EA316E + 25AAE1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/channelf.xml b/themes/linear-es-de/system/metadata/channelf.xml new file mode 100644 index 000000000..5263f93c0 --- /dev/null +++ b/themes/linear-es-de/system/metadata/channelf.xml @@ -0,0 +1,17 @@ + + + Fairchild Channel F + The Fairchild Channel F is a home video game console released by Fairchild Semiconductor in November 1976.
It has the distinction of being the first programmable ROM cartridge–based video game console, and the first console to use a microprocessor. It was launched as the Video Entertainment System, or VES, but when Atari released their VCS the next year, Fairchild renamed it's machine.
+ Fairchild Semiconductor + 1976 + 1976-11-01 + November 1, 1976 + Console + 3-4 + CC991A + E0E0E0 + 91FFA6 + CED0FF + 4B3FF3 +
+
\ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/coco.xml b/themes/linear-es-de/system/metadata/coco.xml new file mode 100644 index 000000000..1a9fb6484 --- /dev/null +++ b/themes/linear-es-de/system/metadata/coco.xml @@ -0,0 +1,17 @@ + + + Tandy Color Computer + The RadioShack TRS-80 Color Computer, later marketed as the Tandy Color Computer and sometimes nicknamed the CoCo, is a line of home computers developed and sold by Tandy Corporation. Despite sharing a name with the earlier TRS-80, the Color Computer is a completely different, incompatible system and a radical departure in design and compatibility with its Motorola 6809E processor rather than the Zilog Z80 earlier models were built around. + Tandy Corporation + 1980 + 1980-09 + September 1980 + Computer + 1-1 + D1AA41 + 498CC1 + 197123 + 555555 + AE1F19 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/colecovision.xml b/themes/linear-es-de/system/metadata/colecovision.xml new file mode 100644 index 000000000..e61ca735e --- /dev/null +++ b/themes/linear-es-de/system/metadata/colecovision.xml @@ -0,0 +1,17 @@ + + + ColecoVision + The ColecoVision is a second generation (1976–1992) home video game console developed and distributed by Coleco Industries. It was released in August 1982 in North America at a retail price of $175. The console was later released in Europe (1983). The ColecoVision offered a closer experience to arcade games than its competitors at the time. The console was discontinued in mid-1985. + Coleco + 1982 + 1982-08-01 + August 1, 1982 + Console + 3-4 + DD5B3E + EF8185 + F3994B + FADD2F + A4DDF0 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/completed.xml b/themes/linear-es-de/system/metadata/completed.xml new file mode 100644 index 000000000..ed11de3b4 --- /dev/null +++ b/themes/linear-es-de/system/metadata/completed.xml @@ -0,0 +1,13 @@ + + + Completed + Organize your completed games. + Various + Various + Various + Various + Collection + 222222 + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/consolearcade.xml b/themes/linear-es-de/system/metadata/consolearcade.xml new file mode 100644 index 000000000..1ac7d7a0a --- /dev/null +++ b/themes/linear-es-de/system/metadata/consolearcade.xml @@ -0,0 +1,17 @@ + + + Console Arcade Games + While arcade boards have traditionally been custom designs, there have been a number of systems that were instead based on home console platforms. The first such board was the Nintendo VS. System, based on the Famicom and released in 1984. The last console-based board was Namco System 369 which was released in 2011 and based on the Sony PlayStation 3. + Various + Various + Various + Various + Folder + 1-1 + 5B60B7 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cps.xml b/themes/linear-es-de/system/metadata/cps.xml new file mode 100644 index 000000000..0f2a6c534 --- /dev/null +++ b/themes/linear-es-de/system/metadata/cps.xml @@ -0,0 +1,19 @@ + + + Capcom Play System + The CP System (CPシステム, shīpī shisutemu, CPS for short) is an arcade system board developed by Capcom that ran game software stored on removable daughterboards. More than two dozen arcade titles were released for CPS-1, before Capcom shifted game development over to its successor, the CP System II. + +Among the 33 titles released for the original CP System included Street Fighter II: The World Warrior and its first two follow-ups, Street Fighter II: Champion Edition and Street Fighter II: Hyper Fighting. + Capcom + 1988 + 1988-05-13 + May 13, 1988 + Arcade + 3-4 + ECD04C + FFCB04 + 034EA2 + FAFAFA + 111111 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cps1.xml b/themes/linear-es-de/system/metadata/cps1.xml new file mode 100644 index 000000000..542607cd1 --- /dev/null +++ b/themes/linear-es-de/system/metadata/cps1.xml @@ -0,0 +1,19 @@ + + + CPS-I + The CP System (CPシステム, shīpī shisutemu, CPS for short) is an arcade system board developed by Capcom that ran game software stored on removable daughterboards. More than two dozen arcade titles were released for CPS-1, before Capcom shifted game development over to its successor, the CP System II. + +Among the 33 titles released for the original CP System included Street Fighter II: The World Warrior and its first two follow-ups, Street Fighter II: Champion Edition and Street Fighter II: Hyper Fighting. + Capcom + 1988 + 1988-05-13 + May 13, 1988 + Arcade + 3-4 + ECD04C + FAFAFA + FFCB04 + 034EA2 + 111111 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cps2.xml b/themes/linear-es-de/system/metadata/cps2.xml new file mode 100644 index 000000000..83361ad5b --- /dev/null +++ b/themes/linear-es-de/system/metadata/cps2.xml @@ -0,0 +1,17 @@ + + + CPS-II + The CP System II (CPシステムII, shīpī shisutemu tsū) or CPS-2 is an arcade system board that Capcom first used in 1993 for Super Street Fighter II. It was the successor to their previous CP System and Capcom Power System Changer arcade hardware and was succeeded by the CP System III hardware in 1996, of which the CPS-2 would outlive by over four years. The arcade system had new releases for it until the end of 2003, ending with Hyper Street Fighter II. + Capcom + 1993 + 1993-09-10 + September 10, 1993 + Arcade + 3-4 + ECD04C + 034EA2 + FAFAFA + FFCB04 + 111111 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/cps3.xml b/themes/linear-es-de/system/metadata/cps3.xml new file mode 100644 index 000000000..0834a39ef --- /dev/null +++ b/themes/linear-es-de/system/metadata/cps3.xml @@ -0,0 +1,17 @@ + + + CPS-III + The CP System III (CPシステムIII, shīpī shisutemu surī) or CPS-3 is an arcade system board that was first used by Capcom in 1996 with the arcade game Red Earth. It was the second successor to the CP System arcade hardware, following the CP System II. It would be the last proprietary system board Capcom would produce before moving on to the Dreamcast-based Naomi platform. + Capcom + 1996 + 1996-11-21 + November 11, 1996 + Arcade + 3-4 + ECD04C + FAFAFA + 034EA2 + 111111 + FFCB04 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/crvision.xml b/themes/linear-es-de/system/metadata/crvision.xml new file mode 100644 index 000000000..878a5a0a5 --- /dev/null +++ b/themes/linear-es-de/system/metadata/crvision.xml @@ -0,0 +1,17 @@ + + + CreatiVision + The Video Technology CreatiVision is a hybrid computer and home video game console introduced by VTech in 1981 and released in 1982 during the Second generation of video game consoles. It was built by the Finnish company Salora. It cost $295 Australian Dollars. The hybrid unit was similar in concept to computers such as the APF Imagination Machine, the older VideoBrain Family Computer, and to a lesser extent the Intellivision game console and Coleco Adam computer, all of which anticipated the trend of video game consoles becoming more like low-end computers. It was discontinue in 1986. + VTech + 1982 + 1982 + 1982 + Console + 3-4 + D59234 + CCA656 + 9F7C64 + E0CC75 + F09734 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/custom-collections.xml b/themes/linear-es-de/system/metadata/custom-collections.xml new file mode 100644 index 000000000..53d3670c2 --- /dev/null +++ b/themes/linear-es-de/system/metadata/custom-collections.xml @@ -0,0 +1,12 @@ + + + Custom Collections + View and play games you have added to your custom collections. + Various + Various + Various + Various + Collection + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/daphne.xml b/themes/linear-es-de/system/metadata/daphne.xml new file mode 100644 index 000000000..072018df8 --- /dev/null +++ b/themes/linear-es-de/system/metadata/daphne.xml @@ -0,0 +1,17 @@ + + + Daphne + Daphne is an arcade emulator application that emulates a variety of laserdisc video games with the intent of preserving these games and making the play experience as faithful to the originals as possible. The developer calls Daphne the "First Ever Multiple Arcade Laserdisc Emulator" ("FEMALE"). It derives its name from Princess Daphne, the heroine of Dragon's Lair. + Matt Ownby + 2007 + 2007-02-06 + February, 6th 2007 + Emulator + 3-4 + F6C126 + DEBA27 + 856125 + DC110B + D8D3BD + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/desktop.xml b/themes/linear-es-de/system/metadata/desktop.xml new file mode 100644 index 000000000..6020d9f02 --- /dev/null +++ b/themes/linear-es-de/system/metadata/desktop.xml @@ -0,0 +1,17 @@ + + + Desktop Shorcuts + View and run your Desktop shortcuts + Various + Various + Various + Various + Folder + 1-1 + 39B1DE + 5475B7 + 503E7A + A05745 + 5C5599 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/doom.xml b/themes/linear-es-de/system/metadata/doom.xml new file mode 100644 index 000000000..16109c04c --- /dev/null +++ b/themes/linear-es-de/system/metadata/doom.xml @@ -0,0 +1,17 @@ + + + Doom + Doom is a 1993 first-person shooter (FPS) game developed by id Software for MS-DOS. Players assume the role of a space marine, popularly known as Doomguy, fighting their way through hordes of invading demons from hell. Id began developing Doom after the release of their previous FPS, Wolfenstein 3D (1992). + id Software + 1993 + 1993-12-10 + December 10, 1993 + Engine + 1-1 + A11321 + 33709F + DFDED1 + D37112 + A63417 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/dos.xml b/themes/linear-es-de/system/metadata/dos.xml new file mode 100644 index 000000000..8f8ae4739 --- /dev/null +++ b/themes/linear-es-de/system/metadata/dos.xml @@ -0,0 +1,17 @@ + + + MS-DOS + MS-DOS, short for Microsoft Disk Operating System, was an operating system for x86-based personal computers mostly developed by Microsoft. It was the most commonly used member of the DOS family of operating systems, and was the main operating system for IBM PC compatible personal computers during the 1980s to the mid-1990s, when it was gradually superseded by operating systems offering a graphical user interface (GUI), in various generations of the Microsoft Windows operating system. + Microsoft + 1981 + 1981-08-01 + August 1, 1981 + OS + 3-4 + 3161BC + FDC20F + 8461A9 + CA1A15 + 111111 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/dragon32.xml b/themes/linear-es-de/system/metadata/dragon32.xml new file mode 100644 index 000000000..ab2473d22 --- /dev/null +++ b/themes/linear-es-de/system/metadata/dragon32.xml @@ -0,0 +1,19 @@ + + + Dragon 32 + The Dragon 32 and Dragon 64 are home computers that were built in the 1980s. The Dragons are very similar to the TRS-80 Color Computer, and were produced for the European market by Dragon Data, Ltd., initially in Swansea, Wales before moving to Port Talbot, Wales (until 1984) and by Eurohard S.A. in Casar de Cáceres, Spain (from 1984 to 1987), and for the US market by Tano of New Orleans, Louisiana. + +The model numbers reflect the primary difference between the two machines, which have 32 and 64 kilobytes (32,768 and 65,536 bytes) of RAM, respectively. + Dragon Data, Ltd. + 1982 + 1982-08 + August 1982 + Computer + 3-4 + 309496 + F50019 + FBFA35 + 74B719 + 3262D9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/dreamcast.xml b/themes/linear-es-de/system/metadata/dreamcast.xml new file mode 100644 index 000000000..bf04bc04e --- /dev/null +++ b/themes/linear-es-de/system/metadata/dreamcast.xml @@ -0,0 +1,19 @@ + + + Dreamcast + The Dreamcast is a home video game console released by Sega on November 27, 1998 in Japan, September 9, 1999 in North America, and October 14, 1999 in Europe. It was the first in the sixth generation of video game consoles, preceding Sony's PlayStation 2, Nintendo's GameCube, and Microsoft's Xbox. The Dreamcast was Sega's final home console, marking the end of the company's eighteen years in the console market. + +In contrast to the expensive hardware of the unsuccessful Sega Saturn, the Dreamcast was designed to reduce costs with "off-the-shelf" components, including a Hitachi SH-4 CPU and an NEC PowerVR2 GPU. Released in Japan to a subdued reception, the Dreamcast enjoyed a successful U.S. launch backed by a large marketing campaign, but interest in the system steadily declined as Sony built hype for the upcoming PlayStation 2. Sales did not meet Sega's expectations despite several price cuts, and the company continued to incur significant financial losses. After a change in leadership, Sega discontinued the Dreamcast on March 31, 2001, withdrawing from the console business and restructuring itself as a third-party publisher. In total, 9.13 million Dreamcast units were sold worldwide. + Sega + 1998 + 1998-11-27 + November 27, 1998 + Console + 1-1 + 4C7ED6 + C1C3C2 + 3E649F + 030303 + E4E5E4 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/easyrpg.xml b/themes/linear-es-de/system/metadata/easyrpg.xml new file mode 100644 index 000000000..0d8e2be28 --- /dev/null +++ b/themes/linear-es-de/system/metadata/easyrpg.xml @@ -0,0 +1,17 @@ + + + EasyRPG + EasyRPG is a free, open source engine to create RPG games, aiming to be also compatible with all RPG Maker 2000 and RPG Maker 2003 games. RPG Maker 2000/2003 games tend to have mechanics and visuals similar to 16-bit JRPGs, though custom scripts can be made by the creators to modify how the game feels and looks. + EasyRPG Team + 2007 + 2007 + 2007 + Engine + 1-1 + 5B9036 + 88BA68 + 555554 + 838382 + 4B6D35 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/electron.xml b/themes/linear-es-de/system/metadata/electron.xml new file mode 100644 index 000000000..111af5ba1 --- /dev/null +++ b/themes/linear-es-de/system/metadata/electron.xml @@ -0,0 +1,16 @@ + + + Acorn Electron + The Acorn Electron (nicknamed the Elk inside Acorn and beyond) was a lower-cost alternative to the BBC Micro educational/home computer, also developed by Acorn Computers Ltd, to provide many of the features of that more expensive machine at a price more competitive with that of the ZX Spectrum. It had 32 kilobytes of RAM, and its ROM included BBC BASIC II together with the operating system. Announced in 1982 for a possible release the same year, it was eventually introduced on 25 August 1983 priced at £199 + Acorn + 1983 + 1983-10-25 + August 25, 1983 + Computer + 3F9B5B + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/emulators.xml b/themes/linear-es-de/system/metadata/emulators.xml new file mode 100644 index 000000000..8079e7508 --- /dev/null +++ b/themes/linear-es-de/system/metadata/emulators.xml @@ -0,0 +1,17 @@ + + + Emulators + Modify your Emulator settings and configurations + Various + Various + Various + Various + Folder + 1-1 + 39B1DE + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/epic.xml b/themes/linear-es-de/system/metadata/epic.xml new file mode 100644 index 000000000..8b1f03f91 --- /dev/null +++ b/themes/linear-es-de/system/metadata/epic.xml @@ -0,0 +1,17 @@ + + + Epic Games Store + The Epic Games Store is a digital video game storefront for Microsoft Windows and macOS, operated by Epic Games. It launched in December 2018 as both a website and a standalone launcher, of which the latter is required to download and play games. The storefront provides a basic catalog, friends list management, matchmaking, and other features. Epic Games has further plans to expand the feature set of the storefront but it does not plan to add as many features as other digital distribution platforms, such as discussion boards or user reviews, instead using existing social media platforms to support these. + Epic + 2018 + 2018-12 + December 2018 + Folder + 3-4 + 8BA7AE + FFFFFF + 777777 + 343434 + 35C4EE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/famicom.xml b/themes/linear-es-de/system/metadata/famicom.xml new file mode 100644 index 000000000..4d5790d9c --- /dev/null +++ b/themes/linear-es-de/system/metadata/famicom.xml @@ -0,0 +1,24 @@ + + + Famicom + The Family Computer (ファミリーコンピュータ) or Famicom (ファミコン) hit the Japanese gaming market in 1983. The brainchild of Masayuki Uemura, Famicom was Nintendo’s first cartridge-based home video game console. It became an instant hit, with game titles like legendary designer Shigeru Miyamoto’s arcade classic Donkey Kong fueling sales. + +The Famicom began life as the “GameCom” before system designer Masayuki Uemura’s wife suggested the moniker we know and love today. During development several ideas were bandied about, including the concept of creating a powerful home computer complete with a keyboard and disk drive, but ultimately the console became the diminutive red-and-white wonder that has become so iconic over the years; the colour scheme was apparently chosen by Nintendo president Hiroshi Yamauchi after he spotted a billboard advertisement which used the same hues. + +The Famicom was designed to be both cheap and impressive. Nintendo aimed to be thrifty where possible but did not want to sacrifice performance. The aim was for their console to be unsurpassed in terms of quality and cost-effectiveness by their competitors for at least a year, if not longer. The console was purposefully designed to look like a toy – with a design scheme similar to the Game and Watch series of portable games they had released a couple of years prior to the Famicom. + +The only direct competition to the Famicom was Sega’s SG-1000, which the Famicom was easily outselling. Within two years the Famicom had already sold 2.5 million units in Japan. This success emboldened Nintendo, who started to look towards international markets. Overall Nintendo sold more than 10 million units in Japan. + https://www.museumofplay.org/blog/first-there-was-famicom/, https://retrogaming.tech.blog/2016/12/03/a-history-of-the-nintendo-famicom/, https://www.nintendolife.com/news/2013/07/feature_the_history_of_the_famicom_the_console_that_changed_nintendos_fortunes + Nintendo + 1983 + 1983-07-15 + July 15, 1983 + Console + 4-3 + B93041 + EA2C27 + E6E7E8 + C0A987 + AA1A41 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fba.xml b/themes/linear-es-de/system/metadata/fba.xml new file mode 100644 index 000000000..0671b4574 --- /dev/null +++ b/themes/linear-es-de/system/metadata/fba.xml @@ -0,0 +1,21 @@ + + + FinalBurn Alpha + This source-available project is based on FinalBurn, created by Dave in 2000. It has been programmed by a team composed of Barry Harris (Old username: TrebleWinner), Jan_Klaassen, KEV, LoopMaster, Mike Haggar, Hyper Yagami and Ayeye. + +FinalBurn was one of the first Capcom CPS2 emulators. When this project came to a halt in 2001, its sources were widely disseminated, allowing the development of many unofficial versions, of which FBA is the most successful. + +Differentiated from other emulators by a very large number of supported systems, FB Alpha also offers a clear interface (simple like that of Kawaks) and excellent performance. The icing on the cake; it's not resource-intensive, and you don't need to indulge in complex settings to take it in hand immediately, although its menus are natively in English. + FBA Team + 2000 + 2000 + 2000 + Emulator + 3-4 + 5B60B7 + CF8A61 + FE7B07 + 231F20 + FFFFFF + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fbneo.xml b/themes/linear-es-de/system/metadata/fbneo.xml new file mode 100644 index 000000000..0f3381385 --- /dev/null +++ b/themes/linear-es-de/system/metadata/fbneo.xml @@ -0,0 +1,21 @@ + + + FinalBurn Neo + FinalBurn Neo is a Multiple Arcade Emulator most popular for emulating Neo-Geo, Capcom, Konami, and Cave games. It is developed by the FinalBurn team and originated from FinalBurn by Dave and old MAME versions. + +FinalBurn Neo is an active fork of the FinalBurn Alpha emulator, created by many of the former FBA developers. + +The reason for the separation of the older branch, FB Alpha, and new spin-off branch, FB Neo, was due to an apparent disagreement between one Barry Harris and the rest of the main FBA team members over a licensing issue. + FBA Team + 2002 + 2002 + 2002 + Emulator + 3-4 + 5B60B7 + C0392B + CF8A61 + 231F20 + FFFFFF + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fds.xml b/themes/linear-es-de/system/metadata/fds.xml new file mode 100644 index 000000000..a9021e061 --- /dev/null +++ b/themes/linear-es-de/system/metadata/fds.xml @@ -0,0 +1,20 @@ + + + Famicom Disk System + The Family Computer Disk System, commonly shortened to the Famicom Disk System or just Disk System, is a peripheral for Nintendo's Family Computer home video game console, released only in Japan on February 21, 1986. It uses proprietary floppy disks called "Disk Cards" for cheaper data storage and it adds a new high-fidelity sound channel for supporting Disk System games. + +Fundamentally, the Disk System serves simply to enhance some aspects already inherent to the base Famicom system, with better sound and cheaper games—though with the disadvantages of high initial price, slow speed, and lower reliability. However, this boost to the market of affordable and writable mass storage temporarily served as an enabling technology for the creation of new types of video games. This includes the vast, open world, progress-saving adventures of the best-selling The Legend of Zelda (1986) and Metroid (1986), games with a cost-effective and swift release such as the best-selling Super Mario Bros. 2, and nationwide leaderboards and contests via the in-store Disk Fax kiosks, which are considered to be forerunners of today's online achievement and distribution systems. + https://en.wikipedia.org/wiki/Famicom_Disk_System + Nintendo + 1986 + 1986-11 + February 21, 1986 + Peripheral + 1-1 + B93041 + A71636 + C7AF89 + 3C3C3B + F4B600 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/flash.xml b/themes/linear-es-de/system/metadata/flash.xml new file mode 100644 index 000000000..fb816c953 --- /dev/null +++ b/themes/linear-es-de/system/metadata/flash.xml @@ -0,0 +1,17 @@ + + + Adobe Flash + Adobe Flash (formerly Macromedia Flash and FutureSplash) was a multimedia software platform used for production of animations, rich web applications, desktop applications, mobile apps, mobile games, and embedded web browser video players. Flash displays text, vector graphics, and raster graphics to provide animations, video games, and applications. It allows streaming of audio and video, and can capture mouse, keyboard, microphone, and camera input. + Macromedia + 1996 + 1996-11 + November 1996 + Engine + 1-1 + B92E34 + FFFFFF + 4A0000 + B11313 + 710000 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fm7.xml b/themes/linear-es-de/system/metadata/fm7.xml new file mode 100644 index 000000000..6d912997b --- /dev/null +++ b/themes/linear-es-de/system/metadata/fm7.xml @@ -0,0 +1,17 @@ + + + FM-7 + The FM-7 ("Fujitsu Micro 7") is a home computer created by Fujitsu. It was first released in 1982 and was sold in Japan and Spain. It is a stripped-down version of Fujitsu's earlier FM-8 computer, and during development it was referred to as the "FM-8 Jr.". + Fujitsu + 1982 + 1982-11 + November 1982 + Computer + 3-4 + E8B229 + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fmtowns.xml b/themes/linear-es-de/system/metadata/fmtowns.xml new file mode 100644 index 000000000..548de677a --- /dev/null +++ b/themes/linear-es-de/system/metadata/fmtowns.xml @@ -0,0 +1,19 @@ + + + FM Towns + The FM Towns (Japanese: エフエムタウンズ, Hepburn: Efu Emu Taunzu) is a Japanese personal computer built by Fujitsu from February 1989 to the summer of 1997. It started as a proprietary PC variant intended for multimedia applications and PC games, but later became more compatible with IBM PC compatibles. In 1993, the FM Towns Marty was released, a game console compatible with existing FM Towns games. + +The "FM" part of the name means "Fujitsu Micro" like their earlier products, while the "Towns" part is derived from the code name the system was assigned while in development, "Townes". This refers to Charles Townes, one of the winners of the 1964 Nobel Prize in Physics, following a custom of Fujitsu at the time to code name PC products after Nobel Prize winners. The e in "Townes" was dropped when the system went into production to make it clearer that the term was to be pronounced like the word "towns" rather than the potential "tow-nes". + Fujitsu + 1989 + 1989-02-28 + February 28, 1989 + Computer + 3-4 + 6F90FE + 9D9D9D + 009971 + 606875 + 151619 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/fpinball.xml b/themes/linear-es-de/system/metadata/fpinball.xml new file mode 100644 index 000000000..d5839fec2 --- /dev/null +++ b/themes/linear-es-de/system/metadata/fpinball.xml @@ -0,0 +1,17 @@ + + + Future Pinball + Future Pinball ("FP") is a freeware 3D pinball editing and gaming application for Microsoft Windows. It is similar to Visual Pinball ("VP") and other modern pinball simulation applications. Just as with VP's partnership with Visual PinMAME, FP uses partner applications to emulate original pinball ROM code. In FP's case, the end results of ROM code are simulated by Better Arcade Mode ("BAM") and tools such as "Pinball Browser" and dot-matrix display software plugins. Core FP development was discontinued in 2010, but resumed in 2013 via BAM. BAM features many new developments, such as enhanced physics, optics, and virtual reality support. + Christopher Leathley + 2005 + 2005-10-22 + October 22, 2005 + Engine + 1-1 + 3871C5 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gamate.xml b/themes/linear-es-de/system/metadata/gamate.xml new file mode 100644 index 000000000..cf6711699 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gamate.xml @@ -0,0 +1,17 @@ + + + Gamate + The Gamate, known as 超級小子 (pinyin: chāojí xiǎozi, literally "Super Boy") in Taiwan and 超级神童 (pinyin: chāojí shéntóng, literally "Super Child Prodigy") in China, is a handheld game console manufactured by Bit Corporation in the early 1990s, and released in Australia, some parts of Europe, Asia (Taiwan and China), Argentina, and the United States. + Bit Corporation + 1990 + 1990 + 1990 + Portable + 3-4 + C53745 + 999999 + 777777 + 555555 + 333333 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gameandwatch.xml b/themes/linear-es-de/system/metadata/gameandwatch.xml new file mode 100644 index 000000000..438f7dc1a --- /dev/null +++ b/themes/linear-es-de/system/metadata/gameandwatch.xml @@ -0,0 +1,24 @@ + + + Game & Watch + The Game & Watch is a series of handheld electronic games developed, manufactured, released and marketed by Nintendo from 1980 to 1991. Created by game designer Gunpei Yokoi, the product derived its name from its featuring a single game as well as a clock on a LCD screen. The models from 1981 onwards featured an alarm in addition. It was the earliest Nintendo video game product to gain major success. + +The units are based on a 4-bit CPU, from the Sharp SM5xx family, that include a small ROM and RAM area and an LCD screen driver circuit, although, prior to its simulation in MAME, there was a misconception in that every unit used a custom ASIC instead of a proper microcontroller. + +The series sold a combined of 43.4 million units worldwide. + https://en.wikipedia.org/wiki/Game_%26_Watch + Nintendo + 1980 + 1980-04-28 + April 28, 1980 + Portable + 4-3 + 8DA6AD + C4353D + C2904A + 853641 + 4C301C + + + + diff --git a/themes/linear-es-de/system/metadata/gamecom.xml b/themes/linear-es-de/system/metadata/gamecom.xml new file mode 100644 index 000000000..225113f26 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gamecom.xml @@ -0,0 +1,20 @@ + + + Game.com + The Game.com is a fifth-generation handheld game console released by Tiger Electronics in August 1997. A smaller version, the Game.com Pocket Pro, was released in mid-1999. +The first version of the Game.com can be connected to a 14.4 kbit/s modem for Internet connectivity, hence its name referencing the top level domain .com. + +It was the first video game console to include a touchscreen and the first handheld console to include Internet connectivity. + Tiger Electronics + 1997 + 1997-08 + August 1997 + Portable + 3-4 + 58ACB4 + 71829A + 293039 + AE2B2B + 186DA4 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gamegear.xml b/themes/linear-es-de/system/metadata/gamegear.xml new file mode 100644 index 000000000..4fb293e47 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gamegear.xml @@ -0,0 +1,19 @@ + + + Game Gear + The Game Gear is an 8-bit fourth generation handheld game console released by Sega on October 6, 1990 in Japan, in April 1991 throughout North America and Europe, and during 1992 in Australia. The Game Gear primarily competed with Nintendo's Game Boy, the Atari Lynx, and NEC's TurboExpress. It shares much of its hardware with the Master System, and can play Master System games by the use of an adapter. Sega positioned the Game Gear, which had a full-color backlit screen with a landscape format, as a technologically superior handheld to the Game Boy. + +Though the Game Gear was rushed to market, its unique game library and price point gave it an edge over the Atari Lynx and TurboExpress. However, due to its short battery life, lack of original games, and weak support from Sega, the Game Gear was unable to surpass the Game Boy, selling 10.62 million units by March 1996. The Game Gear was discontinued on April 30, 1997. It was re-released as a budget system by Majesco Entertainment in 2000, under license from Sega. + Sega + 1990 + 1990-10-06 + October 6, 1990 + Portable + 3-4 + 356FAF + CCCBCB + D41808 + 008200 + 0000FE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gb.xml b/themes/linear-es-de/system/metadata/gb.xml new file mode 100644 index 000000000..de0631f42 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gb.xml @@ -0,0 +1,20 @@ + + + Game Boy + The Game Boy is an 8-bit handheld game console developed and manufactured by Nintendo. It was first released in Japan on April 21, 1989, in North America later the same year, and in Europe in late 1990. It was designed by the same team that developed the Game & Watch series of handheld electronic games and several Nintendo Entertainment System (NES) games: Satoru Okada, Gunpei Yokoi, and Nintendo Research & Development 1. + +It was the first handheld game to use video game cartridges since Milton Bradley's Microvision handheld console. Despite many other, technologically superior handheld consoles introduced during its lifetime, the Game Boy was a tremendous success. The Game Boy and Game Boy Color combined have sold 118 million units worldwide. Upon its release in the United States, it sold its entire shipment of one million units within weeks. + https://en.wikipedia.org/wiki/Game_Boy + Nintendo + 1989 + 1989-04-21 + April 21, 1989 + Portable + 1-1 + 3E518A + 9B2063 + 2D308E + D9D9D9 + A3A3A3 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gba.xml b/themes/linear-es-de/system/metadata/gba.xml new file mode 100644 index 000000000..92c3cd0d8 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gba.xml @@ -0,0 +1,17 @@ + + + Game Boy Advance + The Game Boy Advance (abbreviated as GBA) is a 32-bit handheld video game console developed, manufactured and marketed by Nintendo as the successor to the Game Boy Color. It was released in Japan on March 21, 2001, in North America on June 11, 2001, in Australia and Europe on June 22, 2001, and in mainland China on June 8, 2004 (iQue Player). Nintendo's competitors in the handheld market at the time were the Neo Geo Pocket Color, WonderSwan, GP32, Tapwave Zodiac, and the N-Gage. Despite the competitors' best efforts, Nintendo maintained a majority market share with the Game Boy Advance. As of June 30, 2010, the Game Boy Advance series has sold 81.51 million units worldwide. Its successor, the Nintendo DS, was released in November 2004 and is also compatible with Game Boy Advance software. + Nintendo + 2001 + 2001-06-11 + June 11, 2001 + Portable + 1-1 + 4C74D6 + 5C67A9 + 280FBE + BCBCBC + 212121 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gbc.xml b/themes/linear-es-de/system/metadata/gbc.xml new file mode 100644 index 000000000..11c17bbc2 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gbc.xml @@ -0,0 +1,17 @@ + + + Game Boy Color + The Game Boy Color, (abbreviated as GBC) is a handheld game console manufactured by Nintendo, which was released on October 21, 1998 in Japan and was released in November of the same year in international markets. It is the successor of the Game Boy. The Game Boy Color, as suggested by the name, features a color screen, but no backlight. It is slightly thicker and taller than the Game Boy Pocket, which is a redesigned Game Boy released in 1996. As with the original Game Boy, it has a custom 8-bit processor somewhat related to a Zilog Z80 central processing unit (CPU). The original name - with its American English spelling of "color" - remained unchanged even in markets where "colour" was the accepted English spelling. The Game Boy Color's primary competitors were the much more advanced Neo Geo Pocket by SNK and the WonderSwan by Bandai (both released in Japan only), though the Game Boy Color outsold these by a wide margin. The Game Boy and Game Boy Color combined have sold 118.69 million units worldwide. It was discontinued in 2003, shortly after the release of the Game Boy Advance SP. + Nintendo + 1998 + 1998-10-21 + October 21, 1998 + Portable + 1-1 + F3B92A + F63B77 + 2D308E + 00B3DE + 7642B6 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gc.xml b/themes/linear-es-de/system/metadata/gc.xml new file mode 100644 index 000000000..9ff6f1124 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gc.xml @@ -0,0 +1,19 @@ + + + GameCube + The Nintendo GameCube is a home video game console released by Nintendo in Japan and North America in 2001 and in PAL territories in 2002. The GameCube is Nintendo's entry in the sixth generation of video game consoles and is the successor to their previous console, the Nintendo 64. The GameCube competed with Sony's PlayStation 2 and Microsoft's Xbox. + +The GameCube is the first Nintendo console to use optical discs as its primary storage medium. The discs are in a miniDVD-based format but the system was not designed to play full-sized DVDs or audio CDs unlike its competitors, and mainly focused on gaming instead. The console supports limited online gaming for a small number of games via a GameCube broadband or modem adapter and can connect to a Game Boy Advance with a link cable, which allows players to access exclusive in-game features using the handheld as a second screen and controller like a Wii U. + Nintendo + 2001 + 2001-08-14 + November 18, 2001 + Console + 243-340 + 9382EE + 7B79AA + 524C82 + CBC9E0 + 1E1C11 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/genesis.xml b/themes/linear-es-de/system/metadata/genesis.xml new file mode 100644 index 000000000..7c674a7e5 --- /dev/null +++ b/themes/linear-es-de/system/metadata/genesis.xml @@ -0,0 +1,17 @@ + + + Sega Genesis + The Sega Genesis, known as the Mega Drive in most regions outside North America, is a 16-bit home video game console which was developed and sold by Sega Enterprises, Ltd. The Genesis was Sega's third console and the successor to the Master System. Sega first released the console as the Mega Drive in Japan in 1988, followed by a North American debut under the Genesis moniker in 1989. In 1990, the console was distributed as the Mega Drive by Virgin Mastertronic in Europe, by Ozisoft in Australasia, and by Tec Toy in Brazil. In South Korea, the systems were distributed by Samsung and were known as the Super Gam*Boy, and later the Super Aladdin Boy. The main microprocessor of the Genesis is a 16/32-bit Motorola 68000 CPU clocked at 7.6 MHz. The console also includes a Zilog Z80 sub-processor, which was mainly used to control the sound hardware and also provides backwards compatibility with the Master System. + Sega + 1989 + 1989-08-14 + August 14, 1989 + Console + 243-340 + B52D2E + D2D2D2 + 488277 + 3E64AE + 811B15 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gmaster.xml b/themes/linear-es-de/system/metadata/gmaster.xml new file mode 100644 index 000000000..9cc7fa6cf --- /dev/null +++ b/themes/linear-es-de/system/metadata/gmaster.xml @@ -0,0 +1,19 @@ + + + Game Master + The Game Master is a handheld game console manufactured by Hartung, and designed to compete with the Nintendo Game Boy. In Germany, it was marketed by Hartung itself, while in the UK it was released as the Systema 2000 by the already well-established maker of cheap LCD games Systema. It was also sold a few under alternate names in France, including the Videojet Game Master as well as for a few released by Hartung as the Hartung Super Game and the Hartung Game Tronic. The Game Master has a 64x64 monochrome LCD screen. + +The design was much like the Game Gear with a D-Pad and two action buttons, although another variation, the Game Plus, features a more Game Boy-like design which is backed by a company called Caterpillar and was sold by Delplay in France. The cartridges resemble those used by the Watara Supervision, with the card edge of the cartridge jutted out past the plastic of the cartridge. The Game Master utilizes a 40-pin cartridge port like the Supervision but is not compatible with Supervision games. + Hartung + 1990 + 1990 + 1990 + Portable + 3-4 + 83A9B0 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/gx4000.xml b/themes/linear-es-de/system/metadata/gx4000.xml new file mode 100644 index 000000000..0d192edc9 --- /dev/null +++ b/themes/linear-es-de/system/metadata/gx4000.xml @@ -0,0 +1,17 @@ + + + GX4000 + The Amstrad GX4000, commonly known as the GX4000, is a third generation (1983-2003) video game console developed and distributed by Amstrad. It was released in September of 1990 in Europe at a retail price of £99.99. The console was not released outside Europe. The GX4000 was Amstrad's short-lived attempt to enter the games console market, being primarily a home computer manufacturer. The console was discontinued in late 1991. + Amstrad + 1990 + 1990-09-01 + September 1, 1990 + Console + 3-4 + DA4A3B + E5B3B2 + 9E4968 + DBD9D4 + C02520 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/intellivision.xml b/themes/linear-es-de/system/metadata/intellivision.xml new file mode 100644 index 000000000..e34fa6c72 --- /dev/null +++ b/themes/linear-es-de/system/metadata/intellivision.xml @@ -0,0 +1,17 @@ + + + Intellivision + The Mattel Intellivision is a second generation (1976–1992) home video game console developed and distributed by Mattel Electronics. It was released in summer 1979 in North America at a retail price of $299. The console was later released in Europe (1981), South America (1982), and Japan (1982). The Intellivision was the first home console to use a tile based playfield and was the first game console to provide real-time human voices in the middle of gameplay, courtesy of the IntelliVoice module. The console was discontinued in early-1990. + Mattel + 1979 + 1979-12-03 + December 3, 1979 + Console + 3-4 + E67E17 + D4C1A0 + 2B201D + C81A7C + C8D463 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/j2me.xml b/themes/linear-es-de/system/metadata/j2me.xml new file mode 100644 index 000000000..26aed22df --- /dev/null +++ b/themes/linear-es-de/system/metadata/j2me.xml @@ -0,0 +1,17 @@ + + + J2ME + Java Platform, Micro Edition or Java ME is a computing platform for development and deployment of portable code for embedded and mobile devices (micro-controllers, sensors, gateways, mobile phones, personal digital assistants, TV set-top boxes, printers). Java ME was formerly known as Java 2 Platform, Micro Edition or J2ME. As of December 22, 2006, the Java ME source code is licensed under the GNU General Public License, and is released under the project name phoneME. + Oracle + 1998 + 1998-12-08 + December 8, 1998 + OS + 1-1 + F8981D + F58219 + 4E7896 + EE3537 + 1F4394 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/kodi.xml b/themes/linear-es-de/system/metadata/kodi.xml new file mode 100644 index 000000000..83ac30878 --- /dev/null +++ b/themes/linear-es-de/system/metadata/kodi.xml @@ -0,0 +1,17 @@ + + + Kodi + Kodi is a free and open-source media player software application developed by the XBMC Foundation, a non-profit technology consortium. Kodi is available for multiple operating systems and hardware platforms, with a software 10-foot user interface for use with televisions and remote controls. + XBMC Foundation + 2002 + 2002 + 2002 + Folder + 3-4 + 00141F + 186AAC + 36A2CD + 448F38 + BF2E31 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/laserdisc.xml b/themes/linear-es-de/system/metadata/laserdisc.xml new file mode 100644 index 000000000..a98f3f8a1 --- /dev/null +++ b/themes/linear-es-de/system/metadata/laserdisc.xml @@ -0,0 +1,17 @@ + + + LaserDisc Games + LaserDisc arcade games use pre-recorded video, either in combination with overlaid sprites or simply as sections of video controllable by the player. The first major LaserDisc game was Sega's Astron Belt, released in 1983. It was closely followed by Dragon's Lair the same year, which is doubtlessly the most famous LaserDisc game. A number of releases followed and to this day there is a community making similar homebrew games, although they no longer technically run on LaserDiscs. + Various + Various + Various + Various + Folder + 3-4 + 222222 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/lcdgames.xml b/themes/linear-es-de/system/metadata/lcdgames.xml new file mode 100644 index 000000000..8d09eddbc --- /dev/null +++ b/themes/linear-es-de/system/metadata/lcdgames.xml @@ -0,0 +1,21 @@ + + + LCD Games + Handheld electronic games are very small, portable devices for playing interactive electronic games, often miniaturized versions of video games. The controls, display and speakers are all part of a single unit. + +Rather than a general-purpose screen made up of a grid of small pixels, they usually have custom displays designed to play one game. This simplicity means they can be made as small as a smartwatch, and sometimes are. The visual output of these games can range from a few small light bulbs or LED lights to calculator-like alphanumerical screens; later these were mostly displaced by liquid crystal and vacuum fluorescent display screens with detailed images and in the case of VFD games, color. + +Handhelds' popularity was at its peak from the late 1970s into the early 1990s before declining. They are the precursors to the handheld game console. + Various + Various + Various + Various + Portable + 1-1 + CE413E + B3A98B + A24F41 + C3C9C7 + 3D6F78 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/lowresnx.xml b/themes/linear-es-de/system/metadata/lowresnx.xml new file mode 100644 index 000000000..4fd43f9e4 --- /dev/null +++ b/themes/linear-es-de/system/metadata/lowresnx.xml @@ -0,0 +1,17 @@ + + + LowRes NX + LowRes NX was inspired by real 8-bit and 16-bit systems and simulates chips for graphics, sound and I/O, which actually work like classic hardware. It supports hardware sprites as well as hardware parallax scrolling, and even offers vertical blank and raster interrupts to create authentic retro effects. Imagine LowRes NX as a handheld game console with a d-pad, two action buttons and a little rubber keyboard below a slidable touchscreen. + Timo Kloss + 2017 + 2017 + 2017 + Engine + 1-1 + 00AAAA + FF8300 + 56A0A2 + F8EA32 + FF5700 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/lutris.xml b/themes/linear-es-de/system/metadata/lutris.xml new file mode 100644 index 000000000..06d731a91 --- /dev/null +++ b/themes/linear-es-de/system/metadata/lutris.xml @@ -0,0 +1,19 @@ + + + Lutris + Lutris is a free and open source game manager for Linux-based operating systems developed and maintained by Mathieu Comandon and the community, released under the GNU General Public License. + +Lutris began as a piece of software called Oblivion Launcher, which was created in 2009 by Mathieu Comandon. He wanted an easier way to manage his games running on Linux, especially the ones that ran using Wine. Lutris began development on Launchpad, with the repository being created on May 5th, 2009. The first public release, 0.1, was on November 29th, 2009.[8] In 2010, development moved to GitHub. + Mathieu Comandon + 2010 + 2010-02-23 + February 23, 2010 + Engine + 3-4 + AA9D96 + FF9900 + 704631 + 222222 + FFB700 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/lutro.xml b/themes/linear-es-de/system/metadata/lutro.xml new file mode 100644 index 000000000..4825f5dad --- /dev/null +++ b/themes/linear-es-de/system/metadata/lutro.xml @@ -0,0 +1,17 @@ + + + Lutro + Lutro is a 2D game framework that aims for simplicity and extreme portability. Using lutro, you can develop any kind of 2D retro games, like NES or Genesis games, and run them on a wide range of platforms through RetroArch. Lutro makes it easy to write games by using Lua and following the LÖVE API. Portability is achieved through the libretro API: Lutro is just loaded as a plugin in a frontend like RetroArch which takes care of display, audio and inputs. + libretro + 2015 + 2015-02-15 + February 17, 2015 + Engine + 1-1 + 926183 + 74282B + AE353A + F2D8B5 + 00007F + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/macintosh.xml b/themes/linear-es-de/system/metadata/macintosh.xml new file mode 100644 index 000000000..9e0cd1153 --- /dev/null +++ b/themes/linear-es-de/system/metadata/macintosh.xml @@ -0,0 +1,19 @@ + + + Macintosh + The Macintosh (mainly Mac since 1998) is a family of personal computers designed, manufactured, and sold by Apple Inc. (originally as Apple Computer, Inc.) since January 1984. + +The original Macintosh is the first successful mass-market all-in-one desktop personal computer to have featured a graphical user interface, built-in screen, and mouse. Apple sold the Macintosh alongside its popular Apple II, Apple IIGS, Apple III, and Apple Lisa families of computers until the other models were discontinued in the 1990s. + Apple + 1984 + 1984-01 + January 1984 + Computer + 3-4 + 1EAEDA + 76B845 + E19433 + 009DDD + C45152 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/mame-advmame.xml b/themes/linear-es-de/system/metadata/mame-advmame.xml new file mode 100644 index 000000000..d115c061c --- /dev/null +++ b/themes/linear-es-de/system/metadata/mame-advmame.xml @@ -0,0 +1,17 @@ + + + AdvanceMAME + AdvanceMAME, is a port of the MAME 0.106 and MESS 0.106 emulators for Arcade Monitors and TVs but also for LCDs and PC monitors. + AdvanceMAME + 1998 + 1998-05 + May 1998 + Emulator + 3-4 + 5B60B7 + 00ADEF + 84849C + 231F20 + FFFFFF + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/mame.xml b/themes/linear-es-de/system/metadata/mame.xml new file mode 100644 index 000000000..10ed97d83 --- /dev/null +++ b/themes/linear-es-de/system/metadata/mame.xml @@ -0,0 +1,19 @@ + + + MAME + MAME (formerly an acronym of Multiple Arcade Machine Emulator) is a free and open-source emulator designed to recreate the hardware of arcade game systems in software on modern personal computers and other platforms. Its intention is to preserve gaming history by preventing vintage games from being lost or forgotten. It does this by emulating the inner workings of the emulated arcade machines; the ability to actually play the games is considered "a nice side effect". Joystiq has listed MAME as an application that every Windows and Mac gamer should have. + +The first public MAME release was by Nicola Salmoria on 5 February 1997. It now supports over 7,000 unique games and 10,000 actual ROM image sets, though not all of the games are playable. MESS, an emulator for many video game consoles and computer systems, based on the MAME core, was integrated into MAME in 2015. + MAME Team + 1997 + 1997-02-05 + February 5, 1997 + Emulator + 3-4 + 5B60B7 + 00ADEF + 84849C + 231F20 + FFFFFF + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/mastersystem.xml b/themes/linear-es-de/system/metadata/mastersystem.xml new file mode 100644 index 000000000..ca1133ef7 --- /dev/null +++ b/themes/linear-es-de/system/metadata/mastersystem.xml @@ -0,0 +1,19 @@ + + + Master System + The Sega Master System is a third-generation 8-bit home video game console manufactured by Sega. It was originally a remodeled export version of the Sega Mark III, the third iteration of the SG-1000 series of consoles, which was released in Japan in 1985 and featured enhanced graphical capabilities over its predecessors. The Master System launched in North America in 1986, followed by Europe in 1987, and Brazil in 1989. A Japanese version of the Master System was also launched in 1987, which features a few enhancements over the export models (and by proxy the original Mark III): a built-in FM audio chip, a rapid-fire switch, and a dedicated port for the 3D glasses. The Master System II, a cheaper model, was released in 1990 in North America and Europe. + +The original Master System models use both cartridges and a credit card-sized format known as Sega Cards. Accessories for the consoles include a light gun and 3D glasses that work with a range of specially designed games. The later Master System II redesign removed the card slot, turning it into a strictly cartridge-only system and is incompatible with the 3D glasses. + Sega + 1986 + 1986-09-01 + September 1, 1986 + Console + 243-340 + C03F3B + CBCBCB + 165193 + E60000 + 1A1A1A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/megacd.xml b/themes/linear-es-de/system/metadata/megacd.xml new file mode 100644 index 000000000..f18eb3333 --- /dev/null +++ b/themes/linear-es-de/system/metadata/megacd.xml @@ -0,0 +1,19 @@ + + + Mega CD + The Sega CD, released as the Mega-CD in most regions outside North America and Brazil, is a CD-ROM accessory for the Mega Drive/Genesis designed and produced by Sega as part of the fourth generation of video game consoles. It was released on December 12, 1991 in Japan, October 15, 1992 in North America, and April 2, 1993 in Europe. The Sega CD plays CD-based games and adds hardware functionality such as a faster central processing unit and graphic enhancements like sprite scaling and rotation. It can also play audio CDs and CD+G discs. + +The main benefit of CD technology was greater storage, which allowed for games to be nearly 320 times larger than Genesis cartridges. This benefit manifested as full motion video (FMV) games such as the controversial Night Trap, which became a focus of the 1993 congressional hearings on issues of video game violence and ratings. Sega of Japan partnered with JVC to design the Sega CD and refused to consult with Sega of America until the project was complete. Sega of America assembled parts from various "dummy" units to obtain a working prototype. It was redesigned several times by Sega and licensed third-party developers. + Sega + 1993 + 1993-04-02 + April 2, 1993 + Peripheral + 1-1 + 0C7BCB + DCE3E6 + D5202C + C0C1C4 + 212122 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/megacdjp.xml b/themes/linear-es-de/system/metadata/megacdjp.xml new file mode 100644 index 000000000..4b0dac499 --- /dev/null +++ b/themes/linear-es-de/system/metadata/megacdjp.xml @@ -0,0 +1,19 @@ + + + Mega-CD + The Sega CD, released as the Mega-CD in most regions outside North America and Brazil, is a CD-ROM accessory for the Mega Drive/Genesis designed and produced by Sega as part of the fourth generation of video game consoles. It was released on December 12, 1991 in Japan, October 15, 1992 in North America, and April 2, 1993 in Europe. The Sega CD plays CD-based games and adds hardware functionality such as a faster central processing unit and graphic enhancements like sprite scaling and rotation. It can also play audio CDs and CD+G discs. + +The main benefit of CD technology was greater storage, which allowed for games to be nearly 320 times larger than Genesis cartridges. This benefit manifested as full motion video (FMV) games such as the controversial Night Trap, which became a focus of the 1993 congressional hearings on issues of video game violence and ratings. Sega of Japan partnered with JVC to design the Sega CD and refused to consult with Sega of America until the project was complete. Sega of America assembled parts from various "dummy" units to obtain a working prototype. It was redesigned several times by Sega and licensed third-party developers. + Sega + 1991 + 1991-12-12 + December 12, 1991 + Peripheral + 1-1 + 0C7BCB + 5A97D0 + 1D46A5 + DEAD2C + 732A46 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/megadrive.xml b/themes/linear-es-de/system/metadata/megadrive.xml new file mode 100644 index 000000000..dfb80e2d6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/megadrive.xml @@ -0,0 +1,13 @@ + + + Mega Drive + The Mega Drive is a 16-bit fourth-generation home video game console developed and sold by Sega. It's Sega's third console and the successor to the Master System. The Mega Drive was adapted from Sega's System 16 arcade board. + Sega + 1990 + 1990 + 1990 + Console + 243-340 + 0C7BCB + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/megadrivejp.xml b/themes/linear-es-de/system/metadata/megadrivejp.xml new file mode 100644 index 000000000..e2b1b2a7c --- /dev/null +++ b/themes/linear-es-de/system/metadata/megadrivejp.xml @@ -0,0 +1,13 @@ + + + Mega Drive + The Mega Drive is a 16-bit fourth-generation home video game console developed and sold by Sega. It's Sega's third console and the successor to the Master System. The Mega Drive was adapted from Sega's System 16 arcade board. + Sega + 1988 + 1988-10-29 + October 29, 1988 + Console + 243-340 + 0C7BCB + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/megaduck.xml b/themes/linear-es-de/system/metadata/megaduck.xml new file mode 100644 index 000000000..784595233 --- /dev/null +++ b/themes/linear-es-de/system/metadata/megaduck.xml @@ -0,0 +1,17 @@ + + + Mega Duck + The Welback Holdings Mega Duck, usually just referred to as Mega Duck, is a fourth generation (1987-2004) handheld video game console developed and distributed by Welback Holdings, but marketed under different names like Creatronic, Videojet, Cougar USA, and Hartung. It was released in August 1993 in Netherlands at a retail price of fl 129 as the Creatronic Mega Duck. The console was also released in Germany (1993) distributed by Hartung, France (1993) distributed by Videojet, and Brazil (1993) but as the Cougar USA Cougar Boy. The Mega Duck was an obvious clone of the Game Boy in looks, and it sadly lacked any innovative games to set it apart to become a competitor. The console was discontinued quietly sometime in early 1995. + Welback Holdings + 1993 + 1993 + 1993 + Portable + 4-3 + 17999A + 415E81 + EAEAEA + 51BABB + 819B73 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/mess.xml b/themes/linear-es-de/system/metadata/mess.xml new file mode 100644 index 000000000..3237ead96 --- /dev/null +++ b/themes/linear-es-de/system/metadata/mess.xml @@ -0,0 +1,17 @@ + + + MESS + Multi Emulator Super System (MESS) is an emulator for various consoles and computer systems, based on the MAME core. It used to be a standalone program (which has since been discontinued), but is now integrated into MAME (which is actively developed). MESS emulates portable and console gaming systems, computer platforms, and calculators. The project strives for accuracy and portability and therefore is not always the fastest emulator for any one particular system. Its accuracy makes it also useful for homebrew game development. + MESS Team + 1998 + 1998 + 1998 + Emulator + 3-4 + 5B60B7 + FFA102 + A05F00 + FFEFD5 + FFD183 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/model2.xml b/themes/linear-es-de/system/metadata/model2.xml new file mode 100644 index 000000000..34c0cfd2e --- /dev/null +++ b/themes/linear-es-de/system/metadata/model2.xml @@ -0,0 +1,17 @@ + + + Sega Model 2 + The Sega Model 2 is an arcade system board originally debuted by Sega in 1993 as a successor to the Sega Model 1 board. It is an extension of the Model 1 hardware, most notably introducing the concept of texture-mapped polygons, allowing for more realistic 3D graphics (for its time). The Model 2 board was an important milestone for the arcade industry, and helped launch several key arcade franchises of the 90s, including Daytona USA, Virtua Cop, Sega Rally Championship, Dead or Alive, Virtua Striker, Cyber Troopers Virtual-On and The House of the Dead. The Model 2 was engineered with help from GE Aerospace (acquired by Martin Marietta in 1993, now part of Lockheed Martin), who designed the texture-mapping technology incorporated by the Model 2. The Model 2's development was led by famed game designer Yu Suzuki. The Model 2 arcade board debuted along with Daytona USA, a game which was finished, copyrighted and debuted at the JAMMA arcade show in 1993. There four versions of the system: the original Model 2 and the Model 2A-CRX, Model 2B-CRX and Model 2C-CRX variants. Model 2 and 2A-CRX used a custom DSP with internal code for the geometrizer while 2B-CRX and 2C-CRX used well documented DSPs and uploaded the geometrizer code at startup to the DSP. + Sega + 1993 + 1993-01-01 + January 1, 1993 + Arcade + 3-4 + 439AE9 + 034693 + F7ED18 + F4133D + 199A40 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/model3.xml b/themes/linear-es-de/system/metadata/model3.xml new file mode 100644 index 000000000..44669a463 --- /dev/null +++ b/themes/linear-es-de/system/metadata/model3.xml @@ -0,0 +1,17 @@ + + + Sega Model 3 + The Sega Model 3 is an arcade platform produced by Sega in partnership with Lockheed Martin. It is a successor to the Sega Model 2 platform, and was released in 1996. The Model 3 hardware is very different to the Model 1 and Model 2 boards which preceded it. It was desinged with one purpose in mind - to push as many textured polygons as possible for as least money as possible. Upon release, the Model 3 board was more powerful than any other arcade platform on the market, as well as any home console or computer. + Sega + 1996 + 1996-01-01 + January 1, 1996 + Arcade + 3-4 + 439AE9 + 034693 + FFFFFF + 000000 + 4C9EFB + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/moonlight.xml b/themes/linear-es-de/system/metadata/moonlight.xml new file mode 100644 index 000000000..70b6f3b6e --- /dev/null +++ b/themes/linear-es-de/system/metadata/moonlight.xml @@ -0,0 +1,15 @@ + + + Moonlight (formerly Limelight) is an open source implementation of NVIDIA's GameStream protocol. We implemented the protocol used by the NVIDIA Shield and wrote a set of 3rd party clients. Moonlight allows you to play your PC games on almost any device, whether you're in another room or miles away from your gaming rig. + CWR University + 2014 + 2014 + 2014 + Folder + 738092 + 82BD0F + 003366 + A4A1A4 + DEDDDE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/moto.xml b/themes/linear-es-de/system/metadata/moto.xml new file mode 100644 index 000000000..a4c9bbb81 --- /dev/null +++ b/themes/linear-es-de/system/metadata/moto.xml @@ -0,0 +1,17 @@ + + + Thomson MOTO + The Thomson MOTO line of computers were a series of 8-bit computers sold in the 1980s by French electronics company Thomson, which has been nationalized in 1982. The MOTO computers became an integral part of the French Government's plan informatique pour tous (IPT) to make computers widespread throughout France by bringing computers and programming classes to French school children. A number of computer makers, including Apple, were considered before Thomson won the contract. + Thomson SA + 1984 + 1984 + 1984 + Computer + 3-4 + 2C5299 + E6F0EF + F0C73B + 4F8E5C + 2C2D2C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/msx.xml b/themes/linear-es-de/system/metadata/msx.xml new file mode 100644 index 000000000..b032169eb --- /dev/null +++ b/themes/linear-es-de/system/metadata/msx.xml @@ -0,0 +1,19 @@ + + + MSX + MSX is a standardized home computer architecture, announced by Microsoft and ASCII Corporation on June 16, 1983. It was initially conceived by Microsoft as a product for the Eastern sector, and jointly marketed by Kazuhiko Nishi, then vice-president at Microsoft and director at ASCII Corporation. Microsoft and Nishi conceived the project as an attempt to create unified standards among various home computing system manufacturers of the period, in the same fashion as the VHS standard for home video tape machines. + +MSX systems were popular in Japan and several other countries. Sony was the primary manufacturer of MSX systems at the time of release, and throughout most of the products lifespan, producing more units than any other manufacturer. Eventually 5 million MSX-based units were sold in Japan alone. Despite Microsoft's involvement, few MSX-based machines were released in the United States. + Microsoft + 1983 + 1983-16-27 + June 27, 1983 + Computer + 3-4 + 30A8EB + EAD598 + 212324 + 656266 + DEE0E0 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/msx1.xml b/themes/linear-es-de/system/metadata/msx1.xml new file mode 100644 index 000000000..f62f33796 --- /dev/null +++ b/themes/linear-es-de/system/metadata/msx1.xml @@ -0,0 +1,19 @@ + + + MSX 1 + MSX is a standardized home computer architecture, announced by Microsoft and ASCII Corporation on June 16, 1983. It was initially conceived by Microsoft as a product for the Eastern sector, and jointly marketed by Kazuhiko Nishi, then vice-president at Microsoft and director at ASCII Corporation. Microsoft and Nishi conceived the project as an attempt to create unified standards among various home computing system manufacturers of the period, in the same fashion as the VHS standard for home video tape machines. + +MSX systems were popular in Japan and several other countries. Sony was the primary manufacturer of MSX systems at the time of release, and throughout most of the products lifespan, producing more units than any other manufacturer. Eventually 5 million MSX-based units were sold in Japan alone. Despite Microsoft's involvement, few MSX-based machines were released in the United States. + Microsoft + 1983 + 1983-16-27 + June 27, 1983 + Computer + 3-4 + 30A8EB + EAD598 + 212324 + 656266 + DEE0E0 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/msx2.xml b/themes/linear-es-de/system/metadata/msx2.xml new file mode 100644 index 000000000..17fdbd2c9 --- /dev/null +++ b/themes/linear-es-de/system/metadata/msx2.xml @@ -0,0 +1,19 @@ + + + MSX 2 + MSX is a standardized home computer architecture, announced by Microsoft and ASCII Corporation on June 16, 1983. It was initially conceived by Microsoft as a product for the Eastern sector, and jointly marketed by Kazuhiko Nishi, then vice-president at Microsoft and director at ASCII Corporation. Microsoft and Nishi conceived the project as an attempt to create unified standards among various home computing system manufacturers of the period, in the same fashion as the VHS standard for home video tape machines. + +MSX systems were popular in Japan and several other countries. Sony was the primary manufacturer of MSX systems at the time of release, and throughout most of the products lifespan, producing more units than any other manufacturer. Eventually 5 million MSX-based units were sold in Japan alone. Despite Microsoft's involvement, few MSX-based machines were released in the United States. + Microsoft + 1985 + 1985-01-01 + January 1, 1985 + Computer + 3-4 + 30A8EB + D6D4D4 + B7B7B7 + 515050 + 2323DC + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/msxturbor.xml b/themes/linear-es-de/system/metadata/msxturbor.xml new file mode 100644 index 000000000..9b0f0763c --- /dev/null +++ b/themes/linear-es-de/system/metadata/msxturbor.xml @@ -0,0 +1,17 @@ + + + MSX Turbo R + The MSX Turbo R is the last generation of MSX computers that was put to market by a household electronic brand. Only Panasonic was brave enough to put faith in the standard once again, by releasing two different models: the Panasonic FS-A1ST and the Panasonic FS-A1GT. MSX Turbo R computers were produced until 1994. + Microsoft + 1991 + 1991 + 1991 + Computer + 3-4 + 3F599B + 637080 + 28292B + 99784B + 32100F + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/mugen.xml b/themes/linear-es-de/system/metadata/mugen.xml new file mode 100644 index 000000000..f088e438f --- /dev/null +++ b/themes/linear-es-de/system/metadata/mugen.xml @@ -0,0 +1,17 @@ + + + M.U.G.E.N + Mugen (stylized as M.U.G.E.N) is a freeware 2D fighting game engine designed by Elecbyte. Content is created by the community, and thousands of fighters, both original and from popular fiction, have been created. It is written in C and originally used the Allegro library. The latest versions of the engine use the SDL library. + Elecbyte + 1999 + 1999-07-27 + July 27, 1999 + Engine + 1-1 + CA5617 + B5B8F1 + E5F5FE + FFFFFF + A1B687 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/multivision.xml b/themes/linear-es-de/system/metadata/multivision.xml new file mode 100644 index 000000000..9f41e6c8e --- /dev/null +++ b/themes/linear-es-de/system/metadata/multivision.xml @@ -0,0 +1,17 @@ + + + Othello Multivision + The Othello Multivision (オセロマルチビジョン) is a licensed SG-1000 clone manufactured by Tsukuda Original. It exists because Sega's original intention for the SC-3000 computer was to allow other manufacturers to produce compatible computers in the hope of having a worldwide standard. Unfortunately, possibly with the emergance of the MSX, this tactic failed, and very few SG-1000/SC-3000 compatible machines were produced. The Othello Multivision was one of those machines. + Tsukuda Original + 1983 + 1983 + 1983 + Console + 3-4 + 4959A0 + EFEBE1 + 571229 + 183B67 + E8E342 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/n3ds.xml b/themes/linear-es-de/system/metadata/n3ds.xml new file mode 100644 index 000000000..5ed5c7191 --- /dev/null +++ b/themes/linear-es-de/system/metadata/n3ds.xml @@ -0,0 +1,17 @@ + + + Nintendo 3DS + The Nintendo 3DS, abbreviated to 3DS, is a portable game console produced by Nintendo. It is capable of displaying stereoscopic 3D effects without the use of 3D glasses or additional accessories. Nintendo announced the device in March 2010 and officially unveiled it at E3 2010 on June 15, 2010. The console succeeds the Nintendo DS, featuring backward compatibility with older Nintendo DS and Nintendo DSi video games. + Nintendo + 2011 + 2011-02-26 + February 26, 2011 + Portable + 257-229 + 697583 + 929497 + C02424 + 221D1F + 347A7A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/n64.xml b/themes/linear-es-de/system/metadata/n64.xml new file mode 100644 index 000000000..3f1f2fda2 --- /dev/null +++ b/themes/linear-es-de/system/metadata/n64.xml @@ -0,0 +1,17 @@ + + + Nintendo 64 + Named for its 64-bit central processing unit, it was released in June 1996 in Japan, September 1996 in North America, March 1997 in Europe and Australia, September 1997 in France and December 1997 in Brazil. As part of the fifth generation of gaming, the N64 competed primarily with the PlayStation and the Sega Saturn. The Nintendo 64 was launched with three games: Super Mario 64 and Pilotwings 64, released worldwide; and Saikyo Habu Shogi, released only in Japan. While the N64 was succeeded by Nintendo's MiniDVD-based GameCube in November 2001, N64 consoles remained available until the system was retired in late 2003. + Nintendo + 1996 + 1996-06-23 + June 23, 1996 + Console + 4-3 + 19B65F + 143F9E + 00935C + CA2E39 + E1C245 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/n64dd.xml b/themes/linear-es-de/system/metadata/n64dd.xml new file mode 100644 index 000000000..90589e9fe --- /dev/null +++ b/themes/linear-es-de/system/metadata/n64dd.xml @@ -0,0 +1,17 @@ + + + 64DD + The 64DD, colloquially referred to as the Nintendo 64DD, is a magnetic disk drive peripheral for the Nintendo 64 game console developed by Nintendo. It was originally announced in 1995, prior to the Nintendo 64's 1996 launch, and after numerous delays was finally released only in Japan on December 1, 1999. Only ten software titles were released until the unit was discontinued in February 2001. It was a commercial failure, with at least 15,000 total units sold and another 85,000 units unsold. + Nintendo + 1999 + 1999-12-01 + December 1, 1999 + Peripheral + 1-1 + 19B65F + DCAF36 + 268340 + 20317F + B73E3A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/naomi.xml b/themes/linear-es-de/system/metadata/naomi.xml new file mode 100644 index 000000000..2fd25f5c1 --- /dev/null +++ b/themes/linear-es-de/system/metadata/naomi.xml @@ -0,0 +1,19 @@ + + + Naomi + The NAOMI (New Arcade Operation Machine Idea) is an arcade system released by Sega in 1998. It was designed as a successor to Sega Model 3 hardware, using a similar architecture to the Sega Dreamcast. + +The NAOMI was succeeded by the Sega Hikaru and Sega NAOMI 2 boards, though having out-lasted the NAOMI 2, Hikaru and Sega Aurora. The Sega Chihiro, or possibly even the Sega Lindbergh, could also be seen as successors. + Sega + 1998 + 1998-01-01 + January 1, 1998 + Arcade + 3-4 + EE820D + E4E7D7 + FD95B0 + 48B3EB + 35FF90 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/naomi2.xml b/themes/linear-es-de/system/metadata/naomi2.xml new file mode 100644 index 000000000..4b592f224 --- /dev/null +++ b/themes/linear-es-de/system/metadata/naomi2.xml @@ -0,0 +1,19 @@ + + + Naomi 2 + The Sega NAOMI 2 is an arcade board developed by Sega and is a successor to Sega NAOMI hardware. It was originally released in 2000. Since it uses similar NAOMI architecture (but significantly beefed up), it is also fully backwards compatible with its predecessor. + +The NAOMI 2 is significantly more powerful than the NAOMI, including a dual CPU setup, new T&L GPU, dual rasterizer GPU, increased memory, and faster bandwidth. This leads to games with much more polygons than a NAOMI game, rendered at much faster speeds, while the new T&L GPU adds advanced lighting and particle effects. It was also more affordable than the very expensive (and difficult to program) Sega Hikaru arcade system that preceded it. The NAOMI 2 was nevertheless more powerful than home systems at the time. + Sega + 2000 + 2000 + 2000 + Arcade + 3-4 + E27E16 + E4E7D7 + FD95B0 + 48B3EB + 35FF90 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/naomigd.xml b/themes/linear-es-de/system/metadata/naomigd.xml new file mode 100644 index 000000000..18024e293 --- /dev/null +++ b/themes/linear-es-de/system/metadata/naomigd.xml @@ -0,0 +1,19 @@ + + + Naomi GD-ROM + The NAOMI (New Arcade Operation Machine Idea) is an arcade system released by Sega in 1998. It was designed as a successor to Sega Model 3 hardware, using a similar architecture to the Sega Dreamcast. + +The NAOMI was succeeded by the Sega Hikaru and Sega NAOMI 2 boards, though having out-lasted the NAOMI 2, Hikaru and Sega Aurora. The Sega Chihiro, or possibly even the Sega Lindbergh, could also be seen as successors. + Sega + 1998 + 1998-01-01 + January 1, 1998 + Arcade + 3-4 + EE820D + E4E7D7 + A39B7C + C75433 + 243551 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/nds.xml b/themes/linear-es-de/system/metadata/nds.xml new file mode 100644 index 000000000..896882161 --- /dev/null +++ b/themes/linear-es-de/system/metadata/nds.xml @@ -0,0 +1,17 @@ + + + Nintendo DS + The Nintendo DS or simply, DS, is a 32-bit dual-screen handheld game console developed and released by Nintendo. The device went on sale in North America on November 21, 2004. The DS, short for "Developers' System" or "Dual Screen", introduced distinctive new features to handheld gaming: two LCD screens working in tandem (the bottom one featuring a touchscreen), a built-in microphone, and support for wireless connectivity. Both screens are encompassed within a clamshell design similar to the Game Boy Advance SP. The Nintendo DS also features the ability for multiple DS consoles to directly interact with each other over Wi-Fi within a short range without the need to connect to an existing wireless network. Alternatively, they could interact online using the now-closed Nintendo Wi-Fi Connection service. + Nintendo + 2004 + 2004-12-01 + November 21, 2004 + Portable + 257-229 + B4CAD4 + 5C67A9 + 280FBE + BCBCBC + 212121 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/neogeo.xml b/themes/linear-es-de/system/metadata/neogeo.xml new file mode 100644 index 000000000..dff8a5ab7 --- /dev/null +++ b/themes/linear-es-de/system/metadata/neogeo.xml @@ -0,0 +1,17 @@ + + + Neo Geo + The Advanced Entertainment System (AES), originally known just as the Neo Geo, is the first video game console in the family. The hardware features comparatively colorful 2D graphics. The hardware was in part designed by Alpha Denshi (later ADK). Initially, the home system was only available for rent to commercial establishments, such as hotel chains, bars and restaurants, and other venues. When customer response indicated that some gamers were willing to buy a US$650 console, SNK expanded sales and marketing into the home console market. The Neo Geo console was officially launched on 31 January 1990 in Osaka, Japan. The AES is identical to its arcade counterpart, the MVS, so arcade games released for the home market are nearly identical conversions. + SNK + 1990 + 1990-01-31 + January 31, 1990 + Console + 3-4 + 7A838B + BF9328 + 494949 + 2D2D2D + E8E2E9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/neogeocd.xml b/themes/linear-es-de/system/metadata/neogeocd.xml new file mode 100644 index 000000000..67a933739 --- /dev/null +++ b/themes/linear-es-de/system/metadata/neogeocd.xml @@ -0,0 +1,17 @@ + + + Neo Geo CD + The Neo Geo CD (Japanese: ネオジオCD, Hepburn: Neo Jio Shī Dī) is the second home video game console of SNK Corporation's Neo Geo family, released in September 9, 1994, four years after its cartridge-based equivalent. This is the same platform, converted to the cheaper CD format retailing at $49 to $79 per title, compared to the $300 cartridges. The system was originally priced at US$399, or £399 in the UK. The unit's 1× CD-ROM drive is slow, with very long loading times. The system can also play Audio CDs. All three versions of the system have no region-lock. The Neo Geo CD was launched bundled with a control pad instead of a joystick like the AES version. However, the original AES joystick can be used with all three Neo Geo CD models. + SNK + 1994 + 1994-09-09 + September 9, 1994 + Console + 1-1 + AD90E2 + 878880 + FFD400 + 0088CD + 24241E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/neogeocdjp.xml b/themes/linear-es-de/system/metadata/neogeocdjp.xml new file mode 100644 index 000000000..67a933739 --- /dev/null +++ b/themes/linear-es-de/system/metadata/neogeocdjp.xml @@ -0,0 +1,17 @@ + + + Neo Geo CD + The Neo Geo CD (Japanese: ネオジオCD, Hepburn: Neo Jio Shī Dī) is the second home video game console of SNK Corporation's Neo Geo family, released in September 9, 1994, four years after its cartridge-based equivalent. This is the same platform, converted to the cheaper CD format retailing at $49 to $79 per title, compared to the $300 cartridges. The system was originally priced at US$399, or £399 in the UK. The unit's 1× CD-ROM drive is slow, with very long loading times. The system can also play Audio CDs. All three versions of the system have no region-lock. The Neo Geo CD was launched bundled with a control pad instead of a joystick like the AES version. However, the original AES joystick can be used with all three Neo Geo CD models. + SNK + 1994 + 1994-09-09 + September 9, 1994 + Console + 1-1 + AD90E2 + 878880 + FFD400 + 0088CD + 24241E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/nes.xml b/themes/linear-es-de/system/metadata/nes.xml new file mode 100644 index 000000000..643ec09db --- /dev/null +++ b/themes/linear-es-de/system/metadata/nes.xml @@ -0,0 +1,18 @@ + + + Nintendo Entertainment System + The history of the Nintendo Entertainment System (NES) spans the 1982 development of the Family Computer, to the 1985 launch of the NES, to Nintendo's rise to global dominance based upon this platform throughout the late 1980s. The Family Computer (ファミリーコンピュータ) or Famicom (ファミコン) was developed in 1982 and launched in 1983 in Japan. Following the North American video game crash of 1983, the Famicom was adapted into the NES which was launched in North America in 1985. Transitioning the company from its arcade game history into this combined global 8-bit home video game console platform, the Famicom and NES continued to aggressively compete with the next-generation 16-bit consoles including the 1988 Sega Genesis. The platform was succeeded by the Super Famicom in 1990 and the Super Nintendo Entertainment System in 1991, but its support and production continued until 1995. Interest in the NES has been renewed by collectors and emulators, including Nintendo's own Virtual Console platform. + https://en.wikipedia.org/wiki/History_of_the_Nintendo_Entertainment_System + Nintendo + 1985 + 1985-10-18 + October 18, 1985 + Console + 3-4 + B93041 + CD3332 + FFFFFF + 666666 + 212121 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ngage.xml b/themes/linear-es-de/system/metadata/ngage.xml new file mode 100644 index 000000000..ca6da083e --- /dev/null +++ b/themes/linear-es-de/system/metadata/ngage.xml @@ -0,0 +1,19 @@ + + + N-Gage + The N-Gage is a smartphone combining features of a mobile phone and a handheld game system developed by Nokia, announced on 4 November 2002 and released on 7 October 2003. It runs the original Series 60 platform on Symbian OS v6.1. + +N-Gage attempted to lure gamers away from the Game Boy Advance by including telephone functionality. This was unsuccessful, partly because the buttons, designed for a telephone, were not well-suited for gaming. The original N-Gage was described as resembling a taco, which led to its mocking nickname "taco phone". + Nokia + 2003 + 2003-10-07 + October 7th, 2003 + Portable + 3-4 + CC7236 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ngp.xml b/themes/linear-es-de/system/metadata/ngp.xml new file mode 100644 index 000000000..f64aac52e --- /dev/null +++ b/themes/linear-es-de/system/metadata/ngp.xml @@ -0,0 +1,19 @@ + + + Neo Geo Pocket + The Neo Geo Pocket is a monochrome handheld game console released by SNK. It was the company's first handheld system and is part of the Neo Geo family. It debuted in Japan in late 1998 but never saw an American release, being exclusive to Japan, Asia and Europe. + +The Neo Geo Pocket is considered to be an unsuccessful console. Lower than expected sales resulted in its discontinuation in 1999, and was immediately succeeded by the Neo Geo Pocket Color, a full color device allowing the system to compete more easily with the dominant Game Boy Color handheld, and which also saw an American release. Though the system enjoyed only a short life, there were some significant games released on the system such as Samurai Shodown, and King of Fighters R-1. + SNK + 1998 + 1998-12-31 + December 31, 1998 + Portable + 1-1 + ECA045 + B2B8BD + E92A30 + 25374A + 0F1520 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ngpc.xml b/themes/linear-es-de/system/metadata/ngpc.xml new file mode 100644 index 000000000..1e9d4cb29 --- /dev/null +++ b/themes/linear-es-de/system/metadata/ngpc.xml @@ -0,0 +1,19 @@ + + + Neo Geo Pocket Color + The Neo Geo Pocket Color is a 16-bit color handheld video game console manufactured by SNK. It is a successor to SNK's monochrome Neo Geo Pocket handheld which debuted in 1998 in Japan, with the Color being fully backward compatible. The Neo Geo Pocket Color was released on March 16, 1999 in Japan, August 6, 1999 in North America, and on October 1, 1999 in Europe, entering markets all dominated by Nintendo, competing with Nintendo's Game Boy Color. + +After a good sales start in both the U.S. and Japan with 14 launch titles (a record at the time), subsequent low retail support in the U.S., lack of communication with third-party developers by SNK's American management, the popularity of Nintendo's Pokémon franchise and anticipation of the 32-bit Game Boy Advance, and strong competition from Bandai's WonderSwan in Japan, led to a sales decline in both regions. + SNK + 1999 + 1999-03-16 + March 16, 1999 + Portable + 1-1 + ECA045 + E92A30 + 18A94E + 1D9ED8 + 25374A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/now-playing.xml b/themes/linear-es-de/system/metadata/now-playing.xml new file mode 100644 index 000000000..e740e0223 --- /dev/null +++ b/themes/linear-es-de/system/metadata/now-playing.xml @@ -0,0 +1,12 @@ + + + Now Playing + Quickly access and complete the games on your backlog. + Various + Various + Various + Various + Collection + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/odyssey2.xml b/themes/linear-es-de/system/metadata/odyssey2.xml new file mode 100644 index 000000000..ea28fc808 --- /dev/null +++ b/themes/linear-es-de/system/metadata/odyssey2.xml @@ -0,0 +1,17 @@ + + + Odyssey² + The Magnavox Odyssey 2 is a second generation (1976–1992) home video game console developed and distributed by Magnavox. It was released in February 1979 in North America at a retail price of $179. The console was also released in Europe (1979), and later South America (1983), and Japan (1982). The Odyssey 2 included a full alphanumeric membrane keyboard, which was to be used for educational games, selecting options, or programming. The console was discontinued on March 20, 1984. + Magnavox & Philips + 1978 + 1978-12-01 + December 1, 1978 + Console + 3-4 + EE820D + 8C1914 + 89918F + DC3114 + F8D239 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/openbor.xml b/themes/linear-es-de/system/metadata/openbor.xml new file mode 100644 index 000000000..cbfe1e145 --- /dev/null +++ b/themes/linear-es-de/system/metadata/openbor.xml @@ -0,0 +1,17 @@ + + + Open Beats of Rage + Beats of Rage is a fan-made tribute game to Sega's Streets of Rage series. It supplants the original graphics and characters with resources taken from The King of Fighters series, albeit with tongue-in-cheek renames. Originally developed by Senile Team, the underlying engine powering Beats of Rage later went on to become the Open Beats of Rage (OpenBOR) game engine project. + Senile Team + 2003 + 2003-11 + November 2003 + Engine + 1-1 + 8BA7AE + E17930 + 407AC0 + EBE470 + 404040 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/oric.xml b/themes/linear-es-de/system/metadata/oric.xml new file mode 100644 index 000000000..11fe58aa9 --- /dev/null +++ b/themes/linear-es-de/system/metadata/oric.xml @@ -0,0 +1,17 @@ + + + Oric + Oric was the name used by UK-based Tangerine Computer Systems for a series of 6502-based home computers sold in the 1980s, primarily in Europe. With the success of the ZX Spectrum from Sinclair Research, Tangerine's backers suggested a home computer and Tangerine formed Oric Products International Ltd to develop the Oric-1. The computer was introduced in 1982.[5] During 1983, approximately 160,000 Oric-1 computers were sold in the UK, plus another 50,000 in France (where it was the year's top-selling machine). This resulted in Oric being acquired and given funding for a successor model, the 1984 Oric Atmos. + Tangerine + 1982 + 1982-09-01 + September 1, 1982 + Computer + 3-4 + 7C848D + BFB8A8 + 207EA4 + 77776D + 9E9C8F + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/palm.xml b/themes/linear-es-de/system/metadata/palm.xml new file mode 100644 index 000000000..970e0957f --- /dev/null +++ b/themes/linear-es-de/system/metadata/palm.xml @@ -0,0 +1,17 @@ + + + Palm + The PalmPilot Personal and PalmPilot Professional are the second generation of Palm PDA devices produced by Palm Inc (then a subsidiary of U.S. Robotics, later 3Com). These devices were launched on March 10, 1997 + Palm Inc + 1997 + 1997-03-10 + March 10, 1997 + OS + 1-1 + 324A42 + B2AFAC + 242443 + 345A89 + 363636 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pc.xml b/themes/linear-es-de/system/metadata/pc.xml new file mode 100644 index 000000000..c27a81f75 --- /dev/null +++ b/themes/linear-es-de/system/metadata/pc.xml @@ -0,0 +1,21 @@ + + + IBM PC + The IBM Personal Computer (model 5150, commonly known as the IBM PC) is the first microcomputer released in the IBM PC model line and the basis for the IBM PC compatible de facto standard. Released on August 12, 1981, it was created by a team of engineers and designers directed by Don Estridge in Boca Raton, Florida. + +The machine was based on open architecture and third-party peripherals. Over time, expansion cards and software technology increased to support it. + +The PC had a substantial influence on the personal computer market. The specifications of the IBM PC became one of the most popular computer design standards in the world. The only significant competition it faced from a non-compatible platform throughout the 1980s was from the Apple Macintosh product line. The majority of modern personal computers are distant descendants of the IBM PC. + IBM + 1981 + 1981-08-12 + August 12, 1981 + Computer + 3-4 + 3161BC + 1F70C1 + FFFFFF + 666870 + 201D1D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pc88.xml b/themes/linear-es-de/system/metadata/pc88.xml new file mode 100644 index 000000000..6849279cf --- /dev/null +++ b/themes/linear-es-de/system/metadata/pc88.xml @@ -0,0 +1,19 @@ + + + PC-88 + The PC-8800 series (Japanese: PC-8800シリーズ, Hepburn: Pī Shī Hassen Happyaku Shirīzu), commonly shortened to PC-88, are a brand of Zilog Z80-based 8-bit home computers released by Nippon Electric Company (NEC) in 1981 and primarily sold in Japan. + +The PC-8800 series sold extremely well and became one of the four major Japanese home computers of the 1980s, along with the Fujitsu FM-7, Sharp X1 and the MSX computers. It was later eclipsed by NEC's 16-bit PC-9800 series, although it still maintained strong sales up until the early 90s. + NEC + 1981 + 1981-11 + November 1981 + Computer + 3-4 + 3C518B + B6A781 + 342B22 + 938CAA + 77B7C6 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pc98.xml b/themes/linear-es-de/system/metadata/pc98.xml new file mode 100644 index 000000000..4277d911b --- /dev/null +++ b/themes/linear-es-de/system/metadata/pc98.xml @@ -0,0 +1,21 @@ + + + PC-98 + The NEC PC-9800 was line of personal computers developed in 1982 in Japan by NEC Corporation based on IBM, aimed exclusively at the Japanese market. + +The first model was a 16-bit architecture with an Intel 8086 processor clocked at 5 MHz and 128 KB of RAM. It shipped with graphics cards capable of displaying 8 colors at 640x400 resolution - a clear performance differentiator compared to PCs of the time. + +Initially conceived as a solution for industrial and office applications, by 1987 the PC-9801 series captured nearly 90% of the Japanese personal computer market. Over time, as power increased and graphics and sound effects were appreciated by home users (especially gamers), it also became popular for non-commercial applications - the Touhou Project series, for example, made its debut. + NEC + 1982 + 1982-10-01 + October 1, 1982 + Computer + 3-4 + 5185B2 + 951610 + 16643C + 00499A + 3B3431 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pcarcade.xml b/themes/linear-es-de/system/metadata/pcarcade.xml new file mode 100644 index 000000000..82fbc59f3 --- /dev/null +++ b/themes/linear-es-de/system/metadata/pcarcade.xml @@ -0,0 +1,17 @@ + + + PC Arcade Games + In the beginning of the 2000s arcade system manufacturers started to move away from custom board designs, and as part of this change many instead adapted the standard PC architecture. There were numerous such designs running Linux or Windows, for instance Sega Lindbergh, Namco System N2 and Taito Type X. + Various + Various + Various + Various + Folder + 3-4 + 5B60B7 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pcengine.xml b/themes/linear-es-de/system/metadata/pcengine.xml new file mode 100644 index 000000000..fd00ed93b --- /dev/null +++ b/themes/linear-es-de/system/metadata/pcengine.xml @@ -0,0 +1,19 @@ + + + PC Engine + The PC Engine is a 16-bit fourth-generation home video game console designed by Hudson Soft and sold by NEC Home Electronics. It was released in Japan in 1987 and in North America in 1989. The Japanese model was imported and distributed in France in 1989, and the United Kingdom and Spain received a version based on the American model known as simply TurboGrafx. It was the first console released in the 16-bit era, although it used a modified 8-bit CPU. In Japan, the system was launched as a competitor to the Famicom, but the delayed United States release meant that it ended up competing with the Sega Genesis and later the Super Nintendo Entertainment System. + +The PC Engine has an 8-bit CPU, a 16-bit video color encoder, and a 16-bit video display controller. The GPUs are capable of displaying 482 colors simultaneously, out of 512. With dimensions of just 14 cm × 14 cm × 3.8 cm (5.5 in × 5.5 in × 1.5 in), the Japanese PC Engine is the smallest major home game console ever made. Games were released on HuCard cartridges and later the CD-ROM optical format. + NEC + 1987 + 1987-10-30 + October 30, 1987 + Console + 1-1 + BB3F41 + B2B2B2 + FE0000 + 333333 + D9D9D9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pcenginecd.xml b/themes/linear-es-de/system/metadata/pcenginecd.xml new file mode 100644 index 000000000..d887c549e --- /dev/null +++ b/themes/linear-es-de/system/metadata/pcenginecd.xml @@ -0,0 +1,19 @@ + + + PC Engine CD-ROM² + The CD-ROM² (pronounced CD-ROM-ROM) is an add-on attachment for the PC Engine that was released in Japan on December 4, 1988. The add-on allows the core versions of the console to play PC Engine games in CD-ROM format in addition to standard HuCards. This made the PC Engine the first video game console to use CD-ROMs as a storage media. The add-on consisted of two devices - the CD player itself and the interface unit, which connects the CD player to the console and provides a unified power supply and output for both. + +It was later released as the TurboGrafx-CD in the United States in November 1989, with a remodeled interface unit in order to suit the different shape of the TurboGrafx-16 console. The TurboGrafx-CD had a launch price of $399.99 and did not include any bundled games. Fighting Street and Monster Lair were the TurboGrafx-CD launch titles; Ys Book I and II soon followed. + NEC + 1988 + 1988-12-04 + December 4, 1988 + Console + 1-1 + 5E8FC8 + B2B2B2 + FE0000 + 333333 + D9D9D9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pcfx.xml b/themes/linear-es-de/system/metadata/pcfx.xml new file mode 100644 index 000000000..722a96809 --- /dev/null +++ b/themes/linear-es-de/system/metadata/pcfx.xml @@ -0,0 +1,19 @@ + + + PC-FX + The PC-FX is a 32-bit home video game console developed by both NEC and Hudson Soft and released in Japan in 1994. Powered by an NEC V810 CPU and using CD-ROMs, the PC-FX was intended as the successor to the PC Engine and its international counterpart the TurboGrafx-16, two successful video game consoles from the late 1980s. It is NEC's final foray into the home console market. + +The console is shaped like a tower PC and was meant to be similarly upgradeable. However the PC-FX lacked a 3D polygon-based graphics chip which rendered the system underpowered in comparison to its competitors. It was also expensive and lacked developer support, and as a result it was unable to compete effectively with its fifth generation peers. The PC-FX was NEC's last home video game console, and was discontinued in February 1998. It was considered a commercial failure. + NEC + 1994 + 1994-12-23 + December 23, 1994 + Console + 3-4 + 9378DA + FEC101 + 01015B + 5C3073 + F00020 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pico8.xml b/themes/linear-es-de/system/metadata/pico8.xml new file mode 100644 index 000000000..6e0550779 --- /dev/null +++ b/themes/linear-es-de/system/metadata/pico8.xml @@ -0,0 +1,17 @@ + + + PICO-8 + PICO-8 is a virtual machine and game engine created by Lexaloffle Games. It is a fantasy video game console that mimics the limited graphical and sound capabilities of 8-bit systems of the 1980s. + Lexaloffle + 2015 + 2015-04 + April 2015 + Engine + 3-4 + 140C1C + E69E20 + 77DF41 + F0D7BD + DF739E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/playdate.xml b/themes/linear-es-de/system/metadata/playdate.xml new file mode 100644 index 000000000..6370af3f8 --- /dev/null +++ b/themes/linear-es-de/system/metadata/playdate.xml @@ -0,0 +1,17 @@ + + + Playdate + Playdate is a handheld video game console developed by Panic. As well as buttons and a directional pad, the device has a mechanical crank on its side. The console was first announced on May 22, 2019 on the cover of Edge magazine, and was released on April 18, 2022. The name references its weekly release schedule of games. + Panic + 2022 + 2022-04-18 + April 18, 2022 + Portable + 4-3 + 6c00ff + 6c00ff + ffc833 + 6c00ff + ffc833 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/plus4.xml b/themes/linear-es-de/system/metadata/plus4.xml new file mode 100644 index 000000000..270d92414 --- /dev/null +++ b/themes/linear-es-de/system/metadata/plus4.xml @@ -0,0 +1,19 @@ + + + Commodore Plus/4 + The Commodore Plus/4 is a home computer released by Commodore International in 1984. The "Plus/4" name refers to the four-application ROM-resident office suite (word processor, spreadsheet, database, and graphing); it was billed as "the productivity computer with software built in". + +Internally, the Plus/4 shared the same basic architecture as the lower-end Commodore 16 and 116 models, and was able to use software and peripherals designed for them. The Plus/4 was incompatible with the Commodore 64's software and some of its hardware. Although the Commodore 64 was more established, the Plus/4 was aimed at the more business-oriented part of the personal computer market. + Commodore + 1984 + 1984 + 1984 + Computer + 3-4 + 5891AE + BBAD93 + 968971 + FD4120 + 00A0C6 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pokemini.xml b/themes/linear-es-de/system/metadata/pokemini.xml new file mode 100644 index 000000000..51b4b713c --- /dev/null +++ b/themes/linear-es-de/system/metadata/pokemini.xml @@ -0,0 +1,17 @@ + + + Pokémon Mini + The Pokémon Mini is a handheld game console that was designed and manufactured by Nintendo and themed around the Pokémon media franchise. It is the smallest game system with interchangeable cartridges ever produced by Nintendo, weighing just under two and a half ounces (70 grams). It was first released in North America on November 16, 2001, then in Japan on December 14, 2001, and in Europe on March 15, 2002. The systems were released in three colors: Wooper Blue, Chikorita Green, and Smoochum Purple. Features of the Pokémon mini include an internal real-time clock, an infrared port used to facilitate multiplayer gaming, a reed switch for detecting shakes, and a motor used to implement force feedback. The GameCube game Pokémon Channel features playable demo versions of several Pokémon mini games via console emulation. Also included in the game is Snorlax's Lunch Time, a Pokémon Channel exclusive. Some games were only released in Japan, such as Togepi's Adventure. + Nintendo + 2001 + 2001-11-16 + November 16, 2001 + Portable + 1-1 + 3F5088 + FCE200 + 004F8A + 999998 + 8C8C8C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ports.xml b/themes/linear-es-de/system/metadata/ports.xml new file mode 100644 index 000000000..091907faa --- /dev/null +++ b/themes/linear-es-de/system/metadata/ports.xml @@ -0,0 +1,17 @@ + + + Ports + View and play all of your favorite game ports. + Various + Various + Various + Various + Folder + 3-4 + 3161BC + 4F5054 + 737375 + F4BE46 + E45B12 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ps2.xml b/themes/linear-es-de/system/metadata/ps2.xml new file mode 100644 index 000000000..bf2043a3a --- /dev/null +++ b/themes/linear-es-de/system/metadata/ps2.xml @@ -0,0 +1,19 @@ + + + PlayStation 2 + The PlayStation 2 (PS2) is a home video game console developed and marketed by Sony Computer Entertainment. It was first released in Japan on March 4, 2000, in North America on October 26, 2000, in Europe on November 24, 2000, and Australia on November 24, 2000. It is the successor to the original PlayStation, as well as the second installment in the PlayStation console line-up. A sixth-generation console, it competed with Sega's Dreamcast, Nintendo's GameCube, and Microsoft's original Xbox. + +Announced in 1999, the PS2 offered backward-compatibility for its predecessor's DualShock controller, as well as its games. The PS2 is the best-selling video game console of all time, having sold over 155 million units worldwide. Over 3,800 game titles have been released for the PS2, with over 1.5 billion copies sold. Sony later manufactured several smaller, lighter revisions of the console known as Slimline models in 2004. + Sony + 2000 + 2000-03-04 + March 4, 2000 + Console + 243-340 + 2E69BE + 33438A + 0098DF + 40A9A8 + 849DCA + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ps3.xml b/themes/linear-es-de/system/metadata/ps3.xml new file mode 100644 index 000000000..bc9022b92 --- /dev/null +++ b/themes/linear-es-de/system/metadata/ps3.xml @@ -0,0 +1,19 @@ + + + PlayStation 3 + The PlayStation 3 (PS3) is a home video game console developed by Sony Computer Entertainment. It is the successor to PlayStation 2, and is part of the PlayStation brand of consoles. It was first released on November 11, 2006 in Japan, November 17, 2006 in North America, and March 23, 2007 in Europe and Australia. The PlayStation 3 competed primarily against Microsoft's Xbox 360 and Nintendo's Wii as part of the seventh generation of video game consoles. + +The console was first officially announced at E3 2005, and was released at the end of 2006. It was the first console to use Blu-ray Disc as its primary storage medium. The console was the first PlayStation to integrate social gaming services, including the PlayStation Network, as well as the first to be controllable from a handheld console, through its remote connectivity with PlayStation Portable and PlayStation Vita. In September 2009, the Slim model of the PlayStation 3 was released. It no longer provided the hardware ability to run PS2 games. It was lighter and thinner than the original version, and featured a redesigned logo and marketing design, as well as a minor start-up change in software. A Super Slim variation was then released in late 2012, further refining and redesigning the console. + Sony + 2006 + 2006-11-11 + November 11, 2006 + Console + 3-4 + 367EDB + 94B8F2 + 1A15FF + 0095D5 + 3DD3C8 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ps4.xml b/themes/linear-es-de/system/metadata/ps4.xml new file mode 100644 index 000000000..ed58aa085 --- /dev/null +++ b/themes/linear-es-de/system/metadata/ps4.xml @@ -0,0 +1,17 @@ + + + PlayStation 4 + The PlayStation 4 (PS4) is a home video game console developed by Sony Interactive Entertainment. Announced as the successor to the PlayStation 3 in February 2013, it was launched on November 15, 2013, in North America, November 29, 2013 in Europe, South America and Australia, and on February 22, 2014 in Japan. A console of the eighth generation, it competes with Microsoft's Xbox One and Nintendo's Wii U and Switch. + Sony + 2013 + 2013-11-15 + November 15, 2013 + Console + 3-4 + 1E74C2 + 18191E + 5B6171 + 0123A1 + EBECEE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/psp.xml b/themes/linear-es-de/system/metadata/psp.xml new file mode 100644 index 000000000..d79638f98 --- /dev/null +++ b/themes/linear-es-de/system/metadata/psp.xml @@ -0,0 +1,19 @@ + + + PlayStation Portable + The PlayStation Portable (PSP) is a handheld game console developed and marketed by Sony Computer Entertainment. It was first released in Japan on December 12, 2004, in North America on March 24, 2005, and in PAL regions on September 1, 2005, and is the first handheld installment in the PlayStation line of consoles. As a seventh generation console it competed with the Nintendo DS. + +Development of the PSP was announced during E3 2003, and the console was unveiled at a Sony press conference on May 11, 2004. The system was the most powerful portable console when it was introduced, and was the first real competitor of Nintendo's handheld consoles after many challengers, such as Nokia's N-Gage, had failed. The PSP's advanced graphics capabilities made it a popular mobile entertainment device, which could connect to the PlayStation 2 and PlayStation 3 consoles, any computer with USB interface, other PSP systems, and the Internet. The PSP also had a vast array of multimedia features such as video playback, and so has been considered a portable media player as well. The PSP is the only handheld console to use an optical disc format – Universal Media Disc (UMD) – as its primary storage medium; both games and movies have been released on the format. + Sony + 2004 + 2004-12-12 + December 12, 2004 + Portable + 3-5 + 366DA7 + 313131 + 0F1012 + 97A9BA + F9F7F7 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/psvita.xml b/themes/linear-es-de/system/metadata/psvita.xml new file mode 100644 index 000000000..3a6fe5cd6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/psvita.xml @@ -0,0 +1,17 @@ + + + PlayStation Vita + The PlayStation Vita (PS Vita, or Vita) is a handheld video game console developed and marketed by Sony Interactive Entertainment. It was first released in Japan on December 17, 2011, and in North America, Europe, and other international territories beginning on February 22, 2012. The console is the successor to the PlayStation Portable, and a part of the PlayStation brand of gaming devices; as part of the eighth generation of video game consoles, it primarily competed with the Nintendo 3DS. + Sony + 2011 + 2011-12-17 + December 17, 2011 + Portable + 3-4 + 0966BC + 03477C + 6CAAD8 + D0DFF2 + 2C2C2C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/psx.xml b/themes/linear-es-de/system/metadata/psx.xml new file mode 100644 index 000000000..1f2a99724 --- /dev/null +++ b/themes/linear-es-de/system/metadata/psx.xml @@ -0,0 +1,19 @@ + + + PlayStation + The Sony PlayStation, or PS for short, is a fifth generation (1993–2005) home video game console developed and distributed by Sony Interactive Entertainment. It was released on December 3, 1994 in Japan at a retail price of ¥37,000. The console was later released in North America (1995), Europe (1995), Australia (1995), and Korea (1996). The PlayStation was known for standardizing disc based games over cartridges, as well as controllers with two analog sticks and vibration feedback. The console was discontinued on March 23, 2006. + +PlayStation (Japanese: プレイステーション, Hepburn: Pureisutēshon, officially abbreviated as PS) is a Japanese video game brand that consists of five home video game consoles, as well as a media center, an online service, a line of controllers, two handhelds and a phone, as well as multiple magazines. The brand is produced by Sony Interactive Entertainment, a division of Sony, with the first console releasing as the PlayStation in Japan released in December 1994, and worldwide the following year. + Sony + 1994 + 1994-12-03 + December 3, 1994 + Console + 1-1 + 858B90 + DC0029 + F1C002 + 00A79B + 326BB1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/pv1000.xml b/themes/linear-es-de/system/metadata/pv1000.xml new file mode 100644 index 000000000..ac73c8356 --- /dev/null +++ b/themes/linear-es-de/system/metadata/pv1000.xml @@ -0,0 +1,21 @@ + + + PV-1000 + The Casio PV-1000 (ぴーぶいせん, Pi Bui-Sen) is a third-generation home video game console manufactured by Casio and released in Japan in 1983. It was discontinued less than a year after release. + +The PV-1000 was released in October 1983. It was only released in Japan where it sold for 14,800 yen. Casio failed to achieve a significant market share. According to retrogames.co.uk the console was pulled after several weeks; due to low sales. + +The PV-1000 is powered by a Zilog Z80 CPU, with 2 KB RAM, with 1 KB allocated as VRAM. It also has an additional 1 KB devoted to a character generator. Graphics were provided by a Texas Instruments TMS9918, generating a 256x192 pixel resolution with 8 colours. The console contains a NEC D65010G031 chip used to output video and sound. It had three square wave voices with 6 bits to control the period. + Casio + 1983 + 1983-10-01 + October 1, 1983 + Console + 3-4 + 972F32 + 2A4E78 + 4FBBB2 + DCD9D1 + D13931 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/quake.xml b/themes/linear-es-de/system/metadata/quake.xml new file mode 100644 index 000000000..32a68e976 --- /dev/null +++ b/themes/linear-es-de/system/metadata/quake.xml @@ -0,0 +1,17 @@ + + + Quake + Quake is a first-person shooter game developed by id Software and published by GT Interactive. The first game in the Quake series, it was originally released for MS-DOS, Microsoft Windows and Linux in 1996, followed by Mac OS and Sega Saturn in 1997 and Nintendo 64 in 1998. In the game, players must find their way through various maze-like, medieval environments while battling monsters using an array of weaponry. The overall atmosphere is dark and gritty, with many stone textures and a rusty, capitalized font. Quake takes inspiration from gothic fiction and the works of H. P. Lovecraft. + id Software + 1996 + 1996-06-22 + June 22, 1996 + Engine + 3-4 + B32E34 + 905630 + 6A3822 + 3A0901 + 111111 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/samcoupe.xml b/themes/linear-es-de/system/metadata/samcoupe.xml new file mode 100644 index 000000000..7ad1de4d1 --- /dev/null +++ b/themes/linear-es-de/system/metadata/samcoupe.xml @@ -0,0 +1,17 @@ + + + SAM Coupé + The SAM Coupé (pronounced /sæm ku:peɪ/ from its original British English branding) is an 8-bit British home computer that was first released in late 1989. It was based on and designed to have compatibility with the ZX Spectrum 48K and marketed as a logical upgrade from the Spectrum. It was originally manufactured by Miles Gordon Technology (MGT), based in Swansea in the United Kingdom. + MGT + 1989 + 1989 + 1989 + Computer + 3-4 + 597FC1 + 2A46A5 + C60000 + D3D8D3 + 96958C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/satellaview.xml b/themes/linear-es-de/system/metadata/satellaview.xml new file mode 100644 index 000000000..1427bf241 --- /dev/null +++ b/themes/linear-es-de/system/metadata/satellaview.xml @@ -0,0 +1,17 @@ + + + Satellaview + The Satellaview is a satellite modem peripheral for Nintendo's Super Famicom system that was released in Japan in 1995. Available for pre-release orders beginning February 13, 1995, the Satellaview retailed for between ¥14,000 and 18,000 (at the time between USD$141 and 182) and came bundled with the BS-X Game Pak and an 8M Memory Pak. The Satellaview system was developed and released by Nintendo to receive signals broadcast from satellite TV station WOWOW's satellite radio subsidiary, St.GIGA. St.GIGA was responsible for file server management, maintenance, and vocalization for "SoundLink" games. Nintendo data broadcasts were given a fixed time slot known as the Super Famicom Hour during which scrambled Satellaview-related data was streamed via radio waves to be unscrambled by St.GIGA's "BS digital hi-vision TV." As a subscription-based station for ambient and New Age music, St.GIGA listeners were already equipped with "BS tuners" prior to St.GIGA's contract with Nintendo. Satellaview owners who lacked a "BS tuner" had to purchase one separately from St.GIGA at a price of ¥33,000, as well as sign up for Nintendo's and St.GIGA's monthly joint membership fees. Alternatively, users could rent "BS tuners" from St.GIGA for a 6-month period at a price of ¥5,400. Even at this premium price, St.GIGA reported subscriptions peaking at 116,378 households by March 1997, and dropping to around 46,000 by June 2001. + Nintendo + 1995 + 1995-04-23 + April 23, 1995 + Peripheral + 3-4 + D3AF41 + 37336C + CD2943 + FFDF68 + 647A54 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/saturn.xml b/themes/linear-es-de/system/metadata/saturn.xml new file mode 100644 index 000000000..67b1b910e --- /dev/null +++ b/themes/linear-es-de/system/metadata/saturn.xml @@ -0,0 +1,19 @@ + + + Sega Saturn + The Sega Saturn is a home video game console developed by Sega and released on November 22, 1994 in Japan, May 11, 1995 in North America, and July 8, 1995 in Europe. Part of the fifth generation of video game consoles, it was the successor to the successful Sega Genesis. The Saturn has a dual-CPU architecture and eight processors. Its games are in CD-ROM format, and its game library contains several ports of arcade games as well as original games. + +Development of the Saturn began in 1992, the same year Sega's groundbreaking 3D Model 1 arcade hardware debuted. The Saturn was designed around a new CPU from Japanese electronics company Hitachi. Sega added another video display processor in early 1994 to better compete with Sony's forthcoming PlayStation. + Sega + 1995 + 1995-05-11 + May 11, 1995 + Console + 1-1 + 597BD8 + 0D7176 + D1AE44 + 2740A5 + 86254A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/saturnjp.xml b/themes/linear-es-de/system/metadata/saturnjp.xml new file mode 100644 index 000000000..823ceecba --- /dev/null +++ b/themes/linear-es-de/system/metadata/saturnjp.xml @@ -0,0 +1,19 @@ + + + Sega Saturn + The Sega Saturn is a home video game console developed by Sega and released on November 22, 1994 in Japan, May 11, 1995 in North America, and July 8, 1995 in Europe. Part of the fifth generation of video game consoles, it was the successor to the successful Sega Genesis. The Saturn has a dual-CPU architecture and eight processors. Its games are in CD-ROM format, and its game library contains several ports of arcade games as well as original games. + +Development of the Saturn began in 1992, the same year Sega's groundbreaking 3D Model 1 arcade hardware debuted. The Saturn was designed around a new CPU from Japanese electronics company Hitachi. Sega added another video display processor in early 1994 to better compete with Sony's forthcoming PlayStation. + Sega + 1994 + 1994-11-22 + November 22, 1994 + Console + 1-1 + 597BD8 + 4FA66A + FDE862 + 2E5CCF + BD3786 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/scummvm.xml b/themes/linear-es-de/system/metadata/scummvm.xml new file mode 100644 index 000000000..5a6ecf477 --- /dev/null +++ b/themes/linear-es-de/system/metadata/scummvm.xml @@ -0,0 +1,17 @@ + + + ScummVM + Script Creation Utility for Maniac Mansion Virtual Machine (ScummVM) is a set of game engine recreations. Originally designed to play LucasArts adventure games that use the SCUMM system, it also supports a variety of non-SCUMM games by companies like Revolution Software and Adventure Soft. It was originally written by Ludvig Strigeus. Released under the terms of the GNU General Public License, ScummVM is free software. ScummVM is a reimplementation of the part of the software used to interpret the scripting languages such games used to describe the game world rather than emulating the hardware the games ran on; as such, ScummVM allows the games it supports to be played on platforms other than those for which they were originally released. + ScummVM + 2001 + 2001-10-05 + October 5, 2001 + Engine + 3-4 + 4DBD51 + FFEB32 + F17C38 + EFEDE3 + 95C93E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/scv.xml b/themes/linear-es-de/system/metadata/scv.xml new file mode 100644 index 000000000..713001f9a --- /dev/null +++ b/themes/linear-es-de/system/metadata/scv.xml @@ -0,0 +1,17 @@ + + + Super Cassette Vision + Epoch's original Cassette Vision was introduced in Japan by Epoch in 1981, which had steady sales and took over 70% of the Japanese home console market at the time, with around 400,000 units sold. However, the introduction of next-generation systems from Nintendo, Casio and Sega quickly pushed back the original Cassette Vision, leading Epoch to quickly develop a successor. The Super Cassette Vision was released in 1984 at a cost of ¥14,800 yen, featuring an 8-bit processor and better performance more in line with its competitors. It was later released in France by ITMC under the Yeno branding. At least 16 games were brought over from Japan for a European release. A version of the system targeted the young female market, the Super Lady Cassette Vision. The console came packed in a pink carrying case, alongside the game Milky Princess. The system did not take off, and was unable to match the massive popularity of the Nintendo Famicom, leading Epoch to drop out of the console market by 1987. + Epoch Co. + 1984 + 1984-07-17 + July 17, 1984 + Console + 4-3 + 6D9D4D + FF8300 + 56A0A2 + F8EA32 + FF5700 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sega32x.xml b/themes/linear-es-de/system/metadata/sega32x.xml new file mode 100644 index 000000000..1647be379 --- /dev/null +++ b/themes/linear-es-de/system/metadata/sega32x.xml @@ -0,0 +1,19 @@ + + + Mega Drive 32X + The 32X is an add-on for the Sega Mega Drive/Genesis video game console. Codenamed "Project Mars", the 32X was designed to expand the power of the Mega Drive/Genesis and serve as a transitional console into the 32-bit era until the release of the Sega Saturn. Independent of the console, the 32X uses its own ROM cartridges and has its own library of games. It was distributed under the name Super 32X in Japan, Genesis 32X in North America, Mega Drive 32X in the PAL region, and Mega 32X in Brazil. + +Unveiled by Sega at June 1994's Consumer Electronics Show, the 32X was presented as a low-cost option for consumers looking to play 32-bit games. It was developed in response to the Atari Jaguar and concerns that the Saturn would not make it to market by the end of 1994. Though it was conceived as an entirely new console, at the suggestion of Sega of America executive Joe Miller and his team, it was converted into an add-on for the Genesis and made more powerful. The final design contained two 32-bit central processing units and a 3D graphics processor. + Sega + 1994 + 1994-12-03 + December 3, 1994 + Peripheral + 3-4 + 0C7BCB + DCE3E6 + D5202C + C0C1C4 + 212122 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sega32xjp.xml b/themes/linear-es-de/system/metadata/sega32xjp.xml new file mode 100644 index 000000000..450d6a83f --- /dev/null +++ b/themes/linear-es-de/system/metadata/sega32xjp.xml @@ -0,0 +1,19 @@ + + + Super 32X + The 32X is an add-on for the Sega Mega Drive/Genesis video game console. Codenamed "Project Mars", the 32X was designed to expand the power of the Mega Drive/Genesis and serve as a transitional console into the 32-bit era until the release of the Sega Saturn. Independent of the console, the 32X uses its own ROM cartridges and has its own library of games. It was distributed under the name Super 32X in Japan, Genesis 32X in North America, Mega Drive 32X in the PAL region, and Mega 32X in Brazil. + +Unveiled by Sega at June 1994's Consumer Electronics Show, the 32X was presented as a low-cost option for consumers looking to play 32-bit games. It was developed in response to the Atari Jaguar and concerns that the Saturn would not make it to market by the end of 1994. Though it was conceived as an entirely new console, at the suggestion of Sega of America executive Joe Miller and his team, it was converted into an add-on for the Genesis and made more powerful. The final design contained two 32-bit central processing units and a 3D graphics processor. + Sega + 1994 + 1994-12-03 + December 3, 1994 + Peripheral + 3-4 + 0C7BCB + 6177B3 + 1D46A5 + F2BA5C + FBE627 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sega32xna.xml b/themes/linear-es-de/system/metadata/sega32xna.xml new file mode 100644 index 000000000..b4ca8164b --- /dev/null +++ b/themes/linear-es-de/system/metadata/sega32xna.xml @@ -0,0 +1,19 @@ + + + Sega 32X + The 32X is an add-on for the Sega Mega Drive/Genesis video game console. Codenamed "Project Mars", the 32X was designed to expand the power of the Mega Drive/Genesis and serve as a transitional console into the 32-bit era until the release of the Sega Saturn. Independent of the console, the 32X uses its own ROM cartridges and has its own library of games. It was distributed under the name Super 32X in Japan, Genesis 32X in North America, Mega Drive 32X in the PAL region, and Mega 32X in Brazil. + +Unveiled by Sega at June 1994's Consumer Electronics Show, the 32X was presented as a low-cost option for consumers looking to play 32-bit games. It was developed in response to the Atari Jaguar and concerns that the Saturn would not make it to market by the end of 1994. Though it was conceived as an entirely new console, at the suggestion of Sega of America executive Joe Miller and his team, it was converted into an add-on for the Genesis and made more powerful. The final design contained two 32-bit central processing units and a 3D graphics processor. + Sega + 1994 + 1994-11-21 + November 21, 1994 + Peripheral + 3-4 + 0C7BCB + 0084E2 + ED0A0A + FFE607 + 212122 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/segacd.xml b/themes/linear-es-de/system/metadata/segacd.xml new file mode 100644 index 000000000..53d133079 --- /dev/null +++ b/themes/linear-es-de/system/metadata/segacd.xml @@ -0,0 +1,19 @@ + + + Sega CD + The Sega CD, released as the Mega-CD in most regions outside North America and Brazil, is a CD-ROM accessory for the Mega Drive/Genesis designed and produced by Sega as part of the fourth generation of video game consoles. It was released on December 12, 1991 in Japan, October 15, 1992 in North America, and April 2, 1993 in Europe. The Sega CD plays CD-based games and adds hardware functionality such as a faster central processing unit and graphic enhancements like sprite scaling and rotation. It can also play audio CDs and CD+G discs. + +The main benefit of CD technology was greater storage, which allowed for games to be nearly 320 times larger than Genesis cartridges. This benefit manifested as full motion video (FMV) games such as the controversial Night Trap, which became a focus of the 1993 congressional hearings on issues of video game violence and ratings. Sega of Japan partnered with JVC to design the Sega CD and refused to consult with Sega of America until the project was complete. Sega of America assembled parts from various "dummy" units to obtain a working prototype. It was redesigned several times by Sega and licensed third-party developers. + Sega + 1992 + 1992-10-15 + October 15, 1992 + Peripheral + 3-4 + 0C7BCB + 4B95D1 + 2B83C5 + B2AE85 + 212122 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sfc.xml b/themes/linear-es-de/system/metadata/sfc.xml new file mode 100644 index 000000000..b4c220c91 --- /dev/null +++ b/themes/linear-es-de/system/metadata/sfc.xml @@ -0,0 +1,17 @@ + + + Super Famicom + The Super Famicom is a 16-bit home video game console developed by Nintendo that was released in 1990 in Japan, 1991 in North America, 1992 in Europe and Australasia (Oceania), and 1993 in South America. + Nintendo + 1990 + 1990-11-21 + November 21, 1990 + Console + 3-5 + 3F549D + FED01B + BA2318 + 0A2A8D + 007544 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sg-1000.xml b/themes/linear-es-de/system/metadata/sg-1000.xml new file mode 100644 index 000000000..4427741ea --- /dev/null +++ b/themes/linear-es-de/system/metadata/sg-1000.xml @@ -0,0 +1,19 @@ + + + SG-1000 + The SG-1000 is a home video game console manufactured by Sega and released in Japan, Australia, New Zealand, and other regions. It was Sega's first entry into the home video game hardware business. Introduced in 1983, the SG-1000 was released on the same day that Nintendo released the Family Computer in Japan. The SG-1000 was released in several forms, including the SC-3000 computer and the redesigned SG-1000 II released in 1984. A third iteration of the console, the Sega Mark III, was released in 1985. It provided a custom video display processor over previous iterations and served as the basis for the Master System in 1986, Sega's first internationally released console. + +Developed in response to a downturn in arcades in 1982, the SG-1000 was created on the advice of Hayao Nakayama, president of Sega Enterprises, Ltd. Shortly after the release, Sega Enterprises was sold to CSK Corporation, which was followed by the release of the SG-1000 II. The SC-3000 and the SG-1000 line both support a library of 76 ROM cartridge games and 29 Sega My Card games, all of which are fully compatible with the Mark III and the Japanese version of the Master System. + Sega + 1983 + 1983-07-15 + July 15, 1983 + Console + 3-4 + 48589F + FF0000 + 17569B + D4D6C9 + 1A1E21 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sgb.xml b/themes/linear-es-de/system/metadata/sgb.xml new file mode 100644 index 000000000..29bc84dea --- /dev/null +++ b/themes/linear-es-de/system/metadata/sgb.xml @@ -0,0 +1,21 @@ + + + Super Game Boy + The Super Game Boy (スーパーゲームボーイ, Sūpā Gēmu Bōi) is a peripheral that allows Game Boy cartridges to be played on a Super Nintendo Entertainment System console, compatible with the same cartridges as the original Game Boy: original Game Boy cartridges, the Game Boy Camera, and dual-mode Game Boy Color cartridges (in Game Boy-mode). + +The unit could map the four shades of green to various colors on the screen. Later Game Boy games that were optimized to use the Super Game Boy had additional color information and could override the on-screen colors, display a graphical border around the screen, and display special background sprites. Those games would have printed a small "Super Game Boy Game Pak" logo on the box and cartridge. The adaptor could support up to 64 colors for the border, and 12 colors for the screen. Static screens could display all 10 colors. Certain games can load multiple borders depending on the player's location in the game. + +It is also possible for Super Game Boy games to make use of the Super NES hardware for extra effects: these games had expanded sound when used with the Super Game Boy. Some titles even allowed the second Super NES controller to be used for two-player action; using the Super Multitap, some games even supported four players. + Nintendo + 1994 + 1994-06-28 + June 28, 1994 + Peripheral + 1-1 + 40518A + 30308F + D9D9D9 + EA2427 + A3A3A3 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/snes.xml b/themes/linear-es-de/system/metadata/snes.xml new file mode 100644 index 000000000..9b91ff5f9 --- /dev/null +++ b/themes/linear-es-de/system/metadata/snes.xml @@ -0,0 +1,17 @@ + + + Super Nintendo Entertainment System + The Super Nintendo Entertainment System (also known as the Super NES, SNES or Super Nintendo) is a 16-bit home video game console developed by Nintendo that was released in 1990 in Japan, 1991 in North America, 1992 in Europe and Australasia (Oceania), and 1993 in South America. In Japan, the system is called the Super Famicom, officially adopting the abbreviated name of its predecessor, the Family Computer, or SFC for short. In South Korea, it is known as the Super Comboy and was distributed by Hyundai Electronics. Although each version is essentially the same, several forms of regional lockout prevent the different versions from being compatible with one another. + Nintendo + 1992 + 1992-04-11 + April 11, 1992 + Console + 4-3 + 3F549D + FED01B + BA2318 + 0A2A8D + 007544 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/snesna.xml b/themes/linear-es-de/system/metadata/snesna.xml new file mode 100644 index 000000000..ea8bef4e0 --- /dev/null +++ b/themes/linear-es-de/system/metadata/snesna.xml @@ -0,0 +1,17 @@ + + + Super Nintendo Entertainment System + The Super Nintendo Entertainment System (also known as the Super NES, SNES or Super Nintendo) is a 16-bit home video game console developed by Nintendo that was released in 1990 in Japan, 1991 in North America, 1992 in Europe and Australasia (Oceania), and 1993 in South America. In Japan, the system is called the Super Famicom, officially adopting the abbreviated name of its predecessor, the Family Computer, or SFC for short. In South Korea, it is known as the Super Comboy and was distributed by Hyundai Electronics. Although each version is essentially the same, several forms of regional lockout prevent the different versions from being compatible with one another. + Nintendo + 1991 + 1991-08-23 + August 23, 1991 + Console + 4-3 + 7365B0 + A59EF7 + 47449E + CCCCCC + 4C4C4C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/solarus.xml b/themes/linear-es-de/system/metadata/solarus.xml new file mode 100644 index 000000000..e07541a05 --- /dev/null +++ b/themes/linear-es-de/system/metadata/solarus.xml @@ -0,0 +1,25 @@ + + + Solarus + Solarus was specifically designed with cult 2D action-RPG classics in mind, such as The Legend of Zelda: A Link to the Past and Secret of Mana on the Super Nintendo, or Soleil on the Sega Megadrive/Genesis. + +The engine is programmed in C++, with the SDL library and an OpenGL backend. Games made with Solarus are called quests, and are programmed in Lua. + +The engine does all the heavy computations (for example, collision checks) and the low-level operations like drawing the screen, animating sprites and playing sounds. + +As a quest maker, you are not much interested in implementing these algorithms. On the contrary, you want to define the game logic. Your Lua scripts describe the behavior of enemies, what happens when pressing a switch on a specific map. They will also implement such things as the title screen and the head-up display. + +Both parts (the C++ engine and the Lua scripts of your quest) communicate through the Solarus Lua API. The communication works in both ways: you can call functions of the engine (example: you want to move a non-playing character) and the engine calls your own functions (example: be informed that an enemy was just killed). But before using this Solarus API, you have to learn the basics of Lua (easy and minimal, yet powerful language). + Christopho + 2021 + 2021-04-06 + April 6, 2021 + Engine + 1-1 + 271658 + 37336C + CD2943 + FFDF68 + 647A54 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/spectravideo.xml b/themes/linear-es-de/system/metadata/spectravideo.xml new file mode 100644 index 000000000..4d6dbc7f4 --- /dev/null +++ b/themes/linear-es-de/system/metadata/spectravideo.xml @@ -0,0 +1,17 @@ + + + Spectravideo + Spectravideo International Limited (SVI) was an American computer manufacturer and software house. It was originally called SpectraVision, a company founded by Harry Fox in 1981. The company produced video games and other software for the VIC-20 home computer, the Atari 2600 home video game console, and its CompuMate peripheral. Some of their own computers were compatible with the Microsoft MSX or the IBM PC. + Spectravideo + 1983 + 1983 + 1983 + Console + 3-4 + C12E3D + B74E6C + C23435 + D17733 + E9E439 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/steam.xml b/themes/linear-es-de/system/metadata/steam.xml new file mode 100644 index 000000000..7d08d9656 --- /dev/null +++ b/themes/linear-es-de/system/metadata/steam.xml @@ -0,0 +1,17 @@ + + + Steam + Steam is a video game digital distribution service and storefront by Valve. It was launched as a software client in September 2003 as a way for Valve to provide automatic updates for their games, and expanded to distributing and offering third-party game publishers' titles in late 2005. + Valve + 2003 + 2003-09-12 + September 12, 2003 + Folder + 3-4 + 215D90 + 2F3B50 + 0A7CAF + EEEEEE + 2A2E33 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/stratagus.xml b/themes/linear-es-de/system/metadata/stratagus.xml new file mode 100644 index 000000000..73e0cde4c --- /dev/null +++ b/themes/linear-es-de/system/metadata/stratagus.xml @@ -0,0 +1,15 @@ + + + Stratagus is a free and open-source cross-platform game engine used to build real-time strategy video games. Licensed under the GNU GPL-2.0-only,[2] it is written mostly in C++ with the configuration language being Lua. + Stratagus Team + 1998 + 1998-06-15 + June 15, 1998 + Engine + CE3D3D + A40000 + DB4C4C + F57900 + 26353C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/stv.xml b/themes/linear-es-de/system/metadata/stv.xml new file mode 100644 index 000000000..df5a4ba01 --- /dev/null +++ b/themes/linear-es-de/system/metadata/stv.xml @@ -0,0 +1,19 @@ + + + ST-V + ST-V (Sega Titan Video) is an arcade system board released by Sega, in 1994 for Japan and 1995 worldwide. Departing from their usual process of building custom arcade hardware, Sega's ST-V is essentially identical to the Sega Saturn home console system. The only difference is the media; ST-V used ROM cartridges instead of CD-ROM discs to store games, with the exception of Sports Fishing 2. Being derived from the Saturn hardware, the ST-V was presumably named after the moon Titan, a satellite of Saturn. + +The majority of ST-V titles were released only in Japan, but a notable exception was the port of Dynamite Deka, which became Die Hard Arcade. Games released for the ST-V include the arcade versions of Virtua Fighter Remix, Radiant Silvergun, Golden Axe: The Duel, and Final Fight Revenge. The shared hardware between Saturn and ST-V allowed for very "pure" ports for the Saturn console. + Sega + 1994 + 1994 + 1994 + Arcade + 3-4 + 4A529D + 034693 + F7ED18 + F4133D + 199A40 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/sufami.xml b/themes/linear-es-de/system/metadata/sufami.xml new file mode 100644 index 000000000..d998a95fa --- /dev/null +++ b/themes/linear-es-de/system/metadata/sufami.xml @@ -0,0 +1,21 @@ + + + SuFami Turbo + The SuFami Turbo (スーファミターボ), often compared to the Aladdin Deck Enhancer, is an accessory released by Bandai for Nintendo's Super Famicom system and was released in 1996. + +This device is designed to sit on top of the Super Famicom, and features two cartridge slots. The premise is that games could be produced at a much lower cost and development time, not having to rely on Nintendo for cartridge production. Unlike the Aladdin Deck Enhancer, this device was officially approved by Nintendo under the provision that Bandai handle all the hardware manufacturing itself. + +The two cartridge slots are designed to share data between the games. The cartridge placed in slot 1 is the game that will be played, while the cartridge in slot 2 supplies additional data for use in the main game. Of the thirteen games released, nine of them can link up, within each game series. + Bandai + 1996 + 1996-06-28 + June 28, 1996 + Peripheral + 3-5 + 3F549D + FF0000 + EDDFDE + A0C0CF + 1E2881 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/supergrafx.xml b/themes/linear-es-de/system/metadata/supergrafx.xml new file mode 100644 index 000000000..541dafe1e --- /dev/null +++ b/themes/linear-es-de/system/metadata/supergrafx.xml @@ -0,0 +1,19 @@ + + + SuperGrafx + The PC Engine SuperGrafx (PCエンジンスーパーグラフィックス, Pī Shī Enjin SūpāGurafikkusu), also known as simply the SuperGrafx, is a fourth-generation home video game console manufactured by NEC Home Electronics and released in Japan and France in 1989. It is the successor system to the PC Engine, released two years prior. Originally known as the PC Engine 2 during production stages, it was purported as a true 16-bit home console, featuring improved graphics and audio capabilities over its predecessor. + +The console was rushed to market, released several months before its initial release date of 1990, only having modest updates to the hardware. With only six retail games released that took advantage of the console's hardware updates, the SuperGrafx was a commercial failure, selling only 75,000 units total in both regions. None of the hardware advancements it possessed were carried over to NEC's later consoles, such as the TurboDuo. + NEC + 1989 + 1989-12-08 + December 8, 1989 + Console + 1-1 + 69b5dc + B2B2B2 + 0091AD + 000000 + D9D9D9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/supervision.xml b/themes/linear-es-de/system/metadata/supervision.xml new file mode 100644 index 000000000..a93da5916 --- /dev/null +++ b/themes/linear-es-de/system/metadata/supervision.xml @@ -0,0 +1,17 @@ + + + Supervision + The Watara Supervision, also known as the QuickShot Supervision in the UK, is a monochrome handheld game console, originating from Asia, and introduced in 1992 as a cut-price competitor for Nintendo's Game Boy. It came packaged with a game called Crystball, which is similar to Breakout. One unique feature of the Supervision was that it could be linked up to a television via a link cable. Games played in this way would display in four colors, much like Nintendo's Super Game Boy add-on for the SNES. A full color TV link was also in the works, but because of the Supervision's failure to make a major impression among gamers it was cancelled, along with the games which were in development for it. + Watara + 1992 + 1992-12-31 + December 31, 1992 + Portable + 3-4 + 2ba9a0 + 000000 + 718E2C + 9A9A9A + 00FFEE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/supracan.xml b/themes/linear-es-de/system/metadata/supracan.xml new file mode 100644 index 000000000..6079eea7a --- /dev/null +++ b/themes/linear-es-de/system/metadata/supracan.xml @@ -0,0 +1,17 @@ + + + Super A'can + The Super A'can is a home video game console released exclusively in Taiwan in 1995 by Funtech/Dunhuang Technology. It is based around the Motorola 68000 microchip, which is also used in the Sega Genesis and Neo Geo. Twelve games have been confirmed to exist for the system. + Funtech + 1995 + 1995-10-25 + October 25, 1995 + Console + 3-4 + 0DBD91 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/switch.xml b/themes/linear-es-de/system/metadata/switch.xml new file mode 100644 index 000000000..467918533 --- /dev/null +++ b/themes/linear-es-de/system/metadata/switch.xml @@ -0,0 +1,17 @@ + + + Nintendo Switch + The Nintendo Switch is an eighth generation (2012-present) home video game console developed and distributed by Nintendo. It was released on March 3, 2017 in North America at a retail price of $299.99. The console was simultaneously released in Japan (2017), Europe (2017), South America (2017), Australia (2017) and other World Wide Markets (2017). The Switch is designed to be a hybrid console, allowing games to be played at a TV, and then on the go by undocking the system and playing from the handheld unit itself. As of this date, the console is still in production. + Nintendo + 2017 + 2017-03-03 + March 3, 2017 + Console + 3-5 + F95651 + DA4A4B + 65BADE + 000000 + EBECEE + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/symbian.xml b/themes/linear-es-de/system/metadata/symbian.xml new file mode 100644 index 000000000..d30b7b5d6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/symbian.xml @@ -0,0 +1,17 @@ + + + Symbian + Symbian is a discontinued mobile operating system (OS) and computing platform designed for smartphones. It was originally developed as a proprietary software OS for personal digital assistants in 1998 by the Symbian Ltd. consortium. Symbian OS is a descendant of Psion's EPOC, and was released exclusively on ARM processors, although an unreleased x86 port existed. Symbian was used by many major mobile phone brands, like Samsung, Motorola, Sony Ericsson, and above all by Nokia. It was also prevalent in Japan by brands including Fujitsu, Sharp and Mitsubishi. As a pioneer that established the smartphone industry, it was the most popular smartphone OS on a worldwide average until the end of 2010, at a time when smartphones were in limited use, when it was overtaken by iOS and Android. It was notably less popular in North America. + Symbian Ltd. + 1997 + 1997-06-05 + June 5, 1997 + OS + 1-1 + 222222 + 0082B5 + FBAB18 + 1F4394 + EE3537 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/tanodragon.xml b/themes/linear-es-de/system/metadata/tanodragon.xml new file mode 100644 index 000000000..9c6a4466c --- /dev/null +++ b/themes/linear-es-de/system/metadata/tanodragon.xml @@ -0,0 +1,17 @@ + + + Tano Dragon + The Dragon 32 and Dragon 64 are home computers that were built in the 1980s. The Dragons are very similar to the TRS-80 Color Computer, and were produced for the European market by Dragon Data, Ltd., initially in Swansea, Wales before moving to Port Talbot, Wales (until 1984) and by Eurohard S.A. in Casar de Cáceres, Spain (from 1984 to 1987), and for the US market by Tano of New Orleans, Louisiana. The model numbers reflect the primary difference between the two machines, which have 32 and 64 kilobytes of RAM, respectively. + Dragon Data, Ltd. + 1984 + 1984 + 1984 + Computer + 3-4 + 309496 + F50019 + FBFA35 + 74B719 + 3262D9 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/tg-cd.xml b/themes/linear-es-de/system/metadata/tg-cd.xml new file mode 100644 index 000000000..3280c92e7 --- /dev/null +++ b/themes/linear-es-de/system/metadata/tg-cd.xml @@ -0,0 +1,19 @@ + + + TurboGrafx-CD + The CD-ROM² (pronounced CD-ROM-ROM) is an add-on attachment for the PC Engine that was released in Japan on December 4, 1988. The add-on allows the core versions of the console to play PC Engine games in CD-ROM format in addition to standard HuCards. This made the PC Engine the first video game console to use CD-ROMs as a storage media. The add-on consisted of two devices - the CD player itself and the interface unit, which connects the CD player to the console and provides a unified power supply and output for both. + +It was later released as the TurboGrafx-CD in the United States in November 1989, with a remodeled interface unit in order to suit the different shape of the TurboGrafx-16 console. The TurboGrafx-CD had a launch price of $399.99 and did not include any bundled games. Fighting Street and Monster Lair were the TurboGrafx-CD launch titles; Ys Book I and II soon followed. + NEC + 1989 + 1989-11-01 + November 1, 1989 + Console + 1-1 + F2984B + F79226 + D5E14D + 604832 + 1E1C1A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/tg16.xml b/themes/linear-es-de/system/metadata/tg16.xml new file mode 100644 index 000000000..4c78fc03d --- /dev/null +++ b/themes/linear-es-de/system/metadata/tg16.xml @@ -0,0 +1,19 @@ + + + TurboGrafx-16 + The TurboGrafx-16, known as the PC Engine in Japan and France, is a 16-bit fourth-generation home video game console designed by Hudson Soft and sold by NEC Home Electronics. It was released in Japan in 1987 and in North America in 1989. The Japanese model was imported and distributed in France in 1989, and the United Kingdom and Spain received a version based on the American model known as simply TurboGrafx. It was the first console released in the 16-bit era, although it used a modified 8-bit CPU. In Japan, the system was launched as a competitor to the Famicom, but the delayed United States release meant that it ended up competing with the Sega Genesis and later the Super Nintendo Entertainment System. + +The TurboGrafx-16 has an 8-bit CPU, a 16-bit video color encoder, and a 16-bit video display controller. The GPUs are capable of displaying 482 colors simultaneously, out of 512. With dimensions of just 14 cm × 14 cm × 3.8 cm (5.5 in × 5.5 in × 1.5 in), the Japanese PC Engine is the smallest major home game console ever made. Games were released on HuCard cartridges and later the CD-ROM optical format with the TurboGrafx-CD add-on. + NEC + 1989 + 1989-08-29 + August 29, 1989 + Console + 3-4 + F2984B + F79226 + ECF332 + FD5A17 + D5E14D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/ti99.xml b/themes/linear-es-de/system/metadata/ti99.xml new file mode 100644 index 000000000..1be425473 --- /dev/null +++ b/themes/linear-es-de/system/metadata/ti99.xml @@ -0,0 +1,19 @@ + + + TI-99/4 + The TI-99/4 is a home computer released in late 1979 by Texas Instruments. Based on the Texas Instruments TMS9900 microprocessor originally used in minicomputers, it was the first 16-bit home computer. The associated video display controller provides color graphics and among the best sprite support of its era. + +It includes a simplified internal design, a full-travel keyboard, improved graphics, and a unique expansion system. At half the price of the original model, sales picked up significantly. TI supported the 4A with peripherals, including a speech synthesizer and a "Peripheral Expansion System" box to contain hardware add-ons. TI released developer information and tools, but the insistence on remaining sole publisher continued to starve the platform of software. + Texas Instruments + 1981 + 1981-06 + June 1981 + Computer + 1-1 + 5E6064 + AAA6A7 + C7C2BE + 1F1F1F + FD7F34 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/tic80.xml b/themes/linear-es-de/system/metadata/tic80.xml new file mode 100644 index 000000000..aa55a3509 --- /dev/null +++ b/themes/linear-es-de/system/metadata/tic80.xml @@ -0,0 +1,17 @@ + + + TIC-80 + TIC-80 is a free and open source fantasy computer for making, playing and sharing tiny games. There are built-in tools for development: code, sprites, maps, sound editors and the command line, which is enough to create a mini retro game. At the exit you will get a cartridge file, which can be stored and played on the website. Also, the game can be packed into a player that works on all popular platforms and distribute as you wish. To make a retro styled game the whole process of creation takes place under some technical limitations: 240x136 pixels display, 16 color palette, 256 8x8 color sprites, 4 channel sound and etc. + Vadim Grigoruk + 2017 + 2017 + 2017 + Engine + 1-1 + 140C1C + 4E76B4 + C5494A + C7772F + 65A33D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/to8.xml b/themes/linear-es-de/system/metadata/to8.xml new file mode 100644 index 000000000..d85976fec --- /dev/null +++ b/themes/linear-es-de/system/metadata/to8.xml @@ -0,0 +1,17 @@ + + + Thomson TO8 + The Thomson TO8 is a home computer introduced by French company Thomson SA in 1986, with a cost of 2,990 FF. It replaces its predecessor, the Thomson TO7/70, while remaining essentially compatible. The new features of the TO8, like larger memory (256KB) and better graphics modes (powered by the Thomson EF9369 graphics chip), are shared with the other third generation Thomson computers ( MO6 and TO9+). The TO8 has a tape drive and Microsoft BASIC 1.0 (in standard and 512 KB versions)[9] on its internal ROM, and there is an optional external floppy drive. Graphics were provided by the Thomson EF9369 chip, allowing the display of 16 colors from a palette of 4096. More than 120 games exist for the system. + Thomson SA + 1986 + 1986 + 1986 + Computer + 3-4 + 2C5299 + E6F0EF + F0C73B + 4F8E5C + 2C2D2C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/tools.xml b/themes/linear-es-de/system/metadata/tools.xml new file mode 100644 index 000000000..82951ef72 --- /dev/null +++ b/themes/linear-es-de/system/metadata/tools.xml @@ -0,0 +1,12 @@ + + + Tools + Programs, scripts and utilities to manage your set up. + Various + Various + Various + Various + Folder + 1-1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/triforce.xml b/themes/linear-es-de/system/metadata/triforce.xml new file mode 100644 index 000000000..6be558c91 --- /dev/null +++ b/themes/linear-es-de/system/metadata/triforce.xml @@ -0,0 +1,17 @@ + + + Triforce Arcade System + The Triforce (トライフォース) is an arcade board developed in a joint venture between Sega, Nintendo, and Namco. It is based upon the Nintendo GameCube video game console to reduce development costs, and allowed for arcade ports of home console games, and vice versa. It is named after the magical, often sought-after object in Nintendo's popular The Legend of Zelda series. + Sega + 2002 + 2002 + 2002 + Arcade + 3-4 + 9867A8 + 7B79AA + 524C82 + CBC9E0 + 1E1C11 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/trs-80.xml b/themes/linear-es-de/system/metadata/trs-80.xml new file mode 100644 index 000000000..ae990766e --- /dev/null +++ b/themes/linear-es-de/system/metadata/trs-80.xml @@ -0,0 +1,17 @@ + + + TRS-80 + The TRS-80 Micro Computer System (TRS-80, later renamed the Model I to distinguish it from successors) is a desktop microcomputer launched in 1977 and sold by Tandy Corporation through their Radio Shack stores. The name is an abbreviation of Tandy Radio Shack, Z80 [microprocessor]. It is one of the earliest mass-produced and mass-marketed retail home computers. + Tandy Corporation + 1977 + 1977-08-03 + August 3, 1977 + Computer + 3-4 + 5E6064 + 233D98 + A8AAAE + CE2027 + 0F7C3E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/type-x.xml b/themes/linear-es-de/system/metadata/type-x.xml new file mode 100644 index 000000000..b27929194 --- /dev/null +++ b/themes/linear-es-de/system/metadata/type-x.xml @@ -0,0 +1,19 @@ + + + Taito Type X + The Taito Type X is an arcade system board released in 2004 by game developer and publisher Taito. + +Based on commodity personal computer hardware architecture, Type X is not a specification for a single set of hardware, but rather a modular platform supporting multiple hardware configurations with different levels of graphical capability. This flexibility allows game developers limited choice in selecting a configuration to fit the game's specific requirements, and allows the platform as a whole to more efficiently support gaming titles with vastly different computing needs. For example, the Type X+ and Type X2 models have upgrade graphics processing power, which could be put toward better game visuals, or outputting to higher-resolution (HDTV) displays. The Type X7 board is used primarily for pachinko machines in Japan. Rawiya co-owned the company that produced this system board. + Sega + 2004 + 2004 + 2004 + Arcade + 3-4 + 2A7FBD + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/uzebox.xml b/themes/linear-es-de/system/metadata/uzebox.xml new file mode 100644 index 000000000..5e7c8f8ae --- /dev/null +++ b/themes/linear-es-de/system/metadata/uzebox.xml @@ -0,0 +1,19 @@ + + + Uzebox + The Uzebox is a retro-minimalist 8-bit open source game console. It is based on an AVR 8-bit general purpose microcontroller made by Atmel. The particularity of the system is that it uses an interrupt driven kernel and has no frame buffer. Functions such as video signal generation, tile rendering and music mixing is done in realtime by a background task so your game can easily be developed in C. + + The design goal was to be as simple as possible yet have good enough sound and graphics to implement interesting games. Emphasis was put on making it easy and fun to assemble and program for any hobbyists. The final design contains only two chips: an ATmega644 and an AD725 RGB-to-NTSC converter. + Belogic Software + 2008 + 2008-08-24 + August 24, 2008 + Console + 3-4 + CE3D3D + C43F32 + EDC63D + C9C2BF + 07336A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/vectrex.xml b/themes/linear-es-de/system/metadata/vectrex.xml new file mode 100644 index 000000000..158d10fd3 --- /dev/null +++ b/themes/linear-es-de/system/metadata/vectrex.xml @@ -0,0 +1,19 @@ + + + Vectrex + The Vectrex is a vector display-based home video game console–the only one ever designed and released for the home market, developed by Smith Engineering. It was first released for the North America market in November 1982 and then Europe and Japan in 1983. Originally manufactured by General Consumer Electronics, it was later licensed to Milton Bradley after they acquired the company. Bandai released the system in Japan. + +The Vectrex, in contrast to other video-game systems available at the time, featured an integrated monochrome CRT monitor and did not need to be hooked up to a television set as it provided its own built-in display. A detachable wired control pad was mounted at, and could be folded into, the lower base of the console. Games included translucent color sheet overlays that could be placed over the monochrome screen. A number of peripherals were produced, such as a pair of 3D goggles known as the "3D Imager" and a "light-pen" that allowed the player to draw directly on the screen. A built-in game, Mine Storm, was playable without inserting a cartridge. + Smith Engineering + 1982 + 1982-11 + November 1982 + Console + 3-4 + 4D98D8 + EEF020 + EC1D25 + 11192E + 166FC1 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/vic20.xml b/themes/linear-es-de/system/metadata/vic20.xml new file mode 100644 index 000000000..0c601673a --- /dev/null +++ b/themes/linear-es-de/system/metadata/vic20.xml @@ -0,0 +1,19 @@ + + + VIC-20 + The Commodore VIC-20 (known as the VC-20 in Germany and the VIC-1001 in Japan) is an 8-bit home computer that was sold by Commodore Business Machines. The VIC-20 was announced in 1980, roughly three years after Commodore's first personal computer, the PET. The VIC-20 was the first computer of any description to sell one million units. It was described as "one of the first anti-spectatorial, non-esoteric computers by design...no longer relegated to hobbyist/enthusiasts or those with money, the computer Commodore developed was the computer of the future. + +The VIC-20 was called VC-20 in Germany because the pronunciation of VIC with a German accent sounds like the German expletives "fick" or "wichsen". The term VC was marketed as though it was an abbreviation of VolksComputer ("people's computer," similar to Volkswagen and Volksempfänger). + Commodore + 1980 + 1980-06 + June 1980 + Computer + 3-4 + 5F8FC8 + 896841 + D3D3C9 + FFCD1C + DC2770 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/videopac.xml b/themes/linear-es-de/system/metadata/videopac.xml new file mode 100644 index 000000000..8025358aa --- /dev/null +++ b/themes/linear-es-de/system/metadata/videopac.xml @@ -0,0 +1,21 @@ + + + Videopac + The Magnavox Odyssey 2 (stylized as Magnavox Odyssey²), also known as Philips Odyssey 2, is a second generation home video game console that was released in 1978. It was sold in Europe as the Philips Videopac G7000, in Brazil as the Philips Odyssey and in Japan as Odyssey2 (オデッセイ2 odessei2). The Odyssey 2 was one of the major three home consoles prior to the 1983 video game market crash, along with Atari 2600 and Intellivision. + +In the early 1970s, Magnavox pioneered the home video game industry by successfully bringing the first home console to market, the Odyssey, which was quickly followed by a number of later models, each with a few technological improvements. In 1978, Magnavox, now a subsidiary of North American Philips, decided to release an all-new successor, Odyssey 2. + +In 2009, the video game website IGN named the Odyssey 2 the 21st greatest video game console, out of its list of 25. + Philips + 1978 + 1978-12-01 + December 1, 1978 + Console + 3-4 + f08211 + F6DD08 + 800000 + FF0000 + 4C504E + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/virtualboy.xml b/themes/linear-es-de/system/metadata/virtualboy.xml new file mode 100644 index 000000000..2f7c0ba51 --- /dev/null +++ b/themes/linear-es-de/system/metadata/virtualboy.xml @@ -0,0 +1,19 @@ + + + Virtual Boy + The Virtual Boy is a 32-bit tabletop portable video game console developed and manufactured by Nintendo. Released in 1995, it was marketed as the first console capable of displaying stereoscopic "3D" graphics. The player uses the console like a head-mounted display, placing the head against the eyepiece to see a red monochrome display. + +The games use a parallax effect to create the illusion of depth. Sales failed to meet targets, and Nintendo ceased distribution and game development in 1996, having released only 22 games for the system. + Nintendo + 1995 + 1995-07-21 + July 21, 1995 + Portable + 1-1 + E1414A + 363636 + FE0016 + 8A8C8E + 232323 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/vpinball.xml b/themes/linear-es-de/system/metadata/vpinball.xml new file mode 100644 index 000000000..c19d56669 --- /dev/null +++ b/themes/linear-es-de/system/metadata/vpinball.xml @@ -0,0 +1,17 @@ + + + Visual Pinball + Visual Pinball is a freeware and source available video game engine for pinball tables and similar games such as pachinko machines. It includes a table editor as well as the simulator itself, and runs on Microsoft Windows. It can be used with Visual PinMAME, an emulator for ROM images from real pinball machines. + Visual Pinball Team + 2000 + 2000-12-19 + December 19, 2000 + Engine + 1-1 + 3871C5 + F6DD08 + 800000 + FF0000 + 303030 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/vsmile.xml b/themes/linear-es-de/system/metadata/vsmile.xml new file mode 100644 index 000000000..7f9c983ce --- /dev/null +++ b/themes/linear-es-de/system/metadata/vsmile.xml @@ -0,0 +1,21 @@ + + + V.Smile + The V.Smile (stylized as V.SMILE TV LEARNING SYSTEM) is a sixth-generation educational home video game console manufactured and released by VTech. Titles are available on ROM cartridges called "Smartridges", to play off the system's educational nature. The graphics are primarily sprite-based. The console is often sold bundled with a particular game, with most of them having a game called Alphabet Park Adventure. + +Several variants of the V.Smile console are sold including handheld versions, or models with added functionality such as touch tablet integrated controllers or microphones. The V-Motion is a major variant with its own software lineup that includes motion sensitive controllers, and has Smartriges designed to take advantage of motion-related "active learning". The V-Motion and Smartridges however, are fully backwards compatible with other V.Smile variants and V.Smile Smartridges, and a V-Motion Smartridge can also be played on V.Smile console or handheld, albeit with limited functionality. However, in 2010, the new and old models of the V.Smile were discontinued. VTech still made games for the V.Smile until 2012. + +Some key differentiators between systems and the ability to fully utilize all game functions include the options of a microphone, touch tablet, additional joystick port (for 2-player gameplay), stylus-enhanced controller, or motion sensitive game pad (with V-Motion). + VTech + 2004 + 2004-08-04 + August 4, 2004 + Console + 3-4 + 544D77 + 007CB3 + 8A6AA2 + CBCFD0 + F0973A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/wasm4.xml b/themes/linear-es-de/system/metadata/wasm4.xml new file mode 100644 index 000000000..ed1728b34 --- /dev/null +++ b/themes/linear-es-de/system/metadata/wasm4.xml @@ -0,0 +1,17 @@ + + + WASM-4 + WASM-4 is a low-level fantasy game console for building small games with WebAssembly. Game cartridges (ROMs) are small, self-contained .wasm files that can be built with any programming language that compiles to WebAssembly. + Bruno Garcia + 2022 + 2022-06-21 + June 21, 2022 + Engine + 1-1 + 3A4E25 + 688535 + D3E3B7 + 4B5E2C + 8FC038 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/wii.xml b/themes/linear-es-de/system/metadata/wii.xml new file mode 100644 index 000000000..5afea091c --- /dev/null +++ b/themes/linear-es-de/system/metadata/wii.xml @@ -0,0 +1,19 @@ + + + Wii + The Wii (known unofficially as the Nintendo Wii) is a home video game console released by Nintendo on November 19, 2006. As a seventh generation console, the Wii competed with Microsoft's Xbox 360 and Sony's PlayStation 3. Nintendo stated that its console targets a broader demographic than that of the two others. + +As of the first quarter of 2016, the Wii led its generation over the PlayStation 3 and Xbox 360 in worldwide sales, with more than 101 million units sold; in December 2009, the console broke the sales record for a single month in the United States. + Nintendo + 2006 + 2006-12-02 + December 2, 2006 + Console + 243-340 + 7ECBE8 + 24A9E2 + D1D1D1 + 005C9A + 1E1C1A + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/wiiu.xml b/themes/linear-es-de/system/metadata/wiiu.xml new file mode 100644 index 000000000..091957651 --- /dev/null +++ b/themes/linear-es-de/system/metadata/wiiu.xml @@ -0,0 +1,19 @@ + + + Wii U + The Wii U (WEE YOO) is a home video game console developed by Nintendo as the successor to the Wii. Released in late 2012, it is the first eighth-generation video game console and competed with Microsoft's Xbox One and Sony's PlayStation 4. + +The Wii U is the first Nintendo console to support HD graphics. The system's primary controller is the Wii U GamePad, which features an embedded touchscreen, directional buttons, analog sticks, and action buttons. The screen can be used either as a supplement to the main display or in supported games to play the game directly on the GamePad. The Wii U Pro Controller can be used in its place as a more traditional alternative. The Wii U is backward compatible with all Wii software and accessories. Games can support any combination of the GamePad, Wii Remote, Nunchuk, Balance Board, or Nintendo's Classic Controller or Wii U Pro Controller. Online functionality centers around the Nintendo Network platform and Miiverse, an integrated social networking service which allows users to share content in game-specific communities. + Nintendo + 2012 + 2012-11-18 + November 18, 2012 + Console + 243-340 + 58AED1 + 1F9EBB + 3783BC + DDDCDC + 9D8354 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/windows.xml b/themes/linear-es-de/system/metadata/windows.xml new file mode 100644 index 000000000..dbf76f695 --- /dev/null +++ b/themes/linear-es-de/system/metadata/windows.xml @@ -0,0 +1,19 @@ + + + Windows + Windows is a group of several proprietary graphical operating system families developed and marketed by Microsoft. Each family caters to a certain sector of the computing industry. For example, Windows NT for consumers, Windows Server for servers, and Windows IoT for embedded systems. Defunct Windows families include Windows 9x, Windows Mobile, and Windows Phone. + +The first version of Windows was released on November 20, 1985, as a graphical operating system shell for MS-DOS in response to the growing interest in graphical user interfaces (GUIs). + Microsoft + 1985 + 1985-11-20 + November 20, 1985 + OS + 3-4 + 39B1DE + F8682C + 91C300 + 00B4F1 + FFC300 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/windows3x.xml b/themes/linear-es-de/system/metadata/windows3x.xml new file mode 100644 index 000000000..48ae24388 --- /dev/null +++ b/themes/linear-es-de/system/metadata/windows3x.xml @@ -0,0 +1,19 @@ + + + Windows 3.X + Windows is a group of several proprietary graphical operating system families developed and marketed by Microsoft. Each family caters to a certain sector of the computing industry. For example, Windows NT for consumers, Windows Server for servers, and Windows IoT for embedded systems. Defunct Windows families include Windows 9x, Windows Mobile, and Windows Phone. + +The first version of Windows was released on November 20, 1985, as a graphical operating system shell for MS-DOS in response to the growing interest in graphical user interfaces (GUIs). + Microsoft + 1992 + 1992-04-06 + April 6, 1992 + OS + 3-4 + 39B1DE + F8682C + 91C300 + 00B4F1 + FFC300 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/windows9x.xml b/themes/linear-es-de/system/metadata/windows9x.xml new file mode 100644 index 000000000..3c311a23b --- /dev/null +++ b/themes/linear-es-de/system/metadata/windows9x.xml @@ -0,0 +1,19 @@ + + + Windows 9X + Windows is a group of several proprietary graphical operating system families developed and marketed by Microsoft. Each family caters to a certain sector of the computing industry. For example, Windows NT for consumers, Windows Server for servers, and Windows IoT for embedded systems. Defunct Windows families include Windows 9x, Windows Mobile, and Windows Phone. + +The first version of Windows was released on November 20, 1985, as a graphical operating system shell for MS-DOS in response to the growing interest in graphical user interfaces (GUIs). + Microsoft + 1998 + 1998-06-25 + June 25, 1998 + OS + 3-4 + 709DC1 + F8682C + 91C300 + 00B4F1 + FFC300 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/wonderswan.xml b/themes/linear-es-de/system/metadata/wonderswan.xml new file mode 100644 index 000000000..da137c8b6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/wonderswan.xml @@ -0,0 +1,19 @@ + + + WonderSwan + The WonderSwan is a handheld game console released in Japan by Bandai. It was developed by Gunpei Yokoi's company Koto Laboratory and Bandai, and was the last piece of hardware Yokoi developed before his death in 1997. + +Released in 1999 in the fifth generation of video game consoles, the WonderSwan and its two later models, the WonderSwan Color and SwanCrystal were officially supported until being discontinued by Bandai in 2003. During its lifespan, no variation of the WonderSwan was released outside of Japan. + Bandai + 1999 + 1999-03-04 + March 4, 1999 + Portable + 5-7 + 76CDBE + 8797A4 + DBE0E1 + E72835 + 282827 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/wonderswancolor.xml b/themes/linear-es-de/system/metadata/wonderswancolor.xml new file mode 100644 index 000000000..7b138adc2 --- /dev/null +++ b/themes/linear-es-de/system/metadata/wonderswancolor.xml @@ -0,0 +1,19 @@ + + + WonderSwan Color + The WonderSwan is a handheld game console released in Japan by Bandai. It was developed by Gunpei Yokoi's company Koto Laboratory and Bandai, and was the last piece of hardware Yokoi developed before his death in 1997. + +Released in 1999 in the fifth generation of video game consoles, the WonderSwan and its two later models, the WonderSwan Color and SwanCrystal were officially supported until being discontinued by Bandai in 2003. During its lifespan, no variation of the WonderSwan was released outside of Japan. + Bandai + 2000 + 2000-12-09 + December 9, 2000 + Portable + 5-7 + 3FB0E6 + 009CD4 + EBA743 + D65757 + 162B4F + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/x1.xml b/themes/linear-es-de/system/metadata/x1.xml new file mode 100644 index 000000000..9c571b79b --- /dev/null +++ b/themes/linear-es-de/system/metadata/x1.xml @@ -0,0 +1,25 @@ + + + X1 + The X1 (エックスワン, Ekkusuwan), sometimes called the Sharp X1, is a series of home computers released by Sharp Corporation from 1982 to 1988. It was based on a Z80 CPU. + +Despite the fact that the Computer Division of Sharp Corporation had released the MZ series, suddenly the Television Division released a new computer series called the X1. At the time the original X1 was released, all other home computers generally had a BASIC language in ROM. However the X1 did not have a BASIC ROM, and it had to load the Hu-BASIC interpreter from a cassette tape. On the plus side however, this concept meant that a free RAM area was available that was as big as possible when not using BASIC. This policy was originally copied from the Sharp MZ series, and they were called clean computers in Japan. The cabinet shape of X1 was also much more stylish than others at that time and a range of cabinet colors (including Red) was selectable. + +The RGB display monitor for the X1 had a television tuner, and a computer screen could be super-imposed on TV. All the TV functions could be controlled from a computer program. The character font was completely programmable (A.K.A. PCG) with 4bit color, and was effectively used in many games. The entirety of the VRAM memory was mapped on to the I/O area, so it was controlled without bank switching. Since X1 had these features, it was very powerful for game software. + +While X1 was struggling to sell, the PC8801 (from NEC) was quickly becoming popular in the Japanese market. In 1984, Sharp released the X1 turbo series with high resolution graphics (640x400, while X1 had 640x200). It had many improvements, but the clock speed was still only 4 MHz. In 1986, Sharp released the X1 turbo Z series with a 4096 color analog RGB monitor. An X1 twin, which had a PC-Engine in the cabinet, was finally released as the last machine of the X1 series in 1987. Then this series was succeeded by the X68000 series. + +Sharp continues to sell desktop PC/TV combos in Japan through its Internet Aquos line, where an X1-style red color scheme is available. + Sharp + 1982 + 1982 + 1982 + Computer + 3-4 + B73538 + 752421 + 4A90CB + C1C3D1 + 28333D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/x68000.xml b/themes/linear-es-de/system/metadata/x68000.xml new file mode 100644 index 000000000..297485b6b --- /dev/null +++ b/themes/linear-es-de/system/metadata/x68000.xml @@ -0,0 +1,19 @@ + + + X68000 + The X68000 (Japanese: エックス ろくまんはっせん, Hepburn: Ekkusu Rokuman Hassen) is a home computer created by Sharp Corporation, first released in 1987, sold only in Japan. + +The first model features a 10 MHz Motorola 68000 CPU (hence the name), 1 MB of RAM, and no hard drive; the last model was released in 1993 with a 25 MHz Motorola 68030 CPU, 4 MB of RAM, and optional 80 MB SCSI hard drive. RAM in these systems is expandable to 12 MB, though most games and applications do not require more than 2 MB. + Sharp + 1987 + 1987-03-01 + March 1, 1987 + Computer + 3-4 + 6B6D70 + 3B3B3B + 838582 + C25F7F + 41BC83 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/xbox.xml b/themes/linear-es-de/system/metadata/xbox.xml new file mode 100644 index 000000000..0aa53735c --- /dev/null +++ b/themes/linear-es-de/system/metadata/xbox.xml @@ -0,0 +1,19 @@ + + + Xbox + Xbox is a video gaming brand created and owned by Microsoft. It represents a series of video game consoles developed by Microsoft, with three consoles released in the sixth, seventh, and eighth generations, respectively. The brand also represents applications (games), streaming services, an online service by the name of Xbox Live, and the development arm by the name of Xbox Game Studios. + +The brand was first introduced in the United States in November 2001, with the launch of the original Xbox console. + Microsoft + 2001 + 2001-11-15 + November 15, 2001 + Console + 243-340 + 68B653 + CDDF01 + 9ABF5E + 534F57 + 000000 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/xbox360.xml b/themes/linear-es-de/system/metadata/xbox360.xml new file mode 100644 index 000000000..7564fab76 --- /dev/null +++ b/themes/linear-es-de/system/metadata/xbox360.xml @@ -0,0 +1,19 @@ + + + Xbox 360 + The Xbox 360 is a home video game console developed by Microsoft. As the successor to the original Xbox, it is the second console in the Xbox series. It competed with Sony's PlayStation 3 and Nintendo's Wii as part of the seventh generation of video game consoles. It was officially unveiled on MTV on May 12, 2005, with detailed launch and game information announced later that month at the 2005 Electronic Entertainment Expo. + +The Xbox 360 features an online service, Xbox Live, which was expanded from its previous iteration on the original Xbox and received regular updates during the console's lifetime. Available in free and subscription-based varieties, Xbox Live allows users to: play games online; download games (through Xbox Live Arcade) and game demos; purchase and stream music, television programs, and films through the Xbox Music and Xbox Video portals; and access third-party content services through media streaming applications. In addition to online multimedia features, it allows users to stream media from local PCs. Several peripherals have been released, including wireless controllers, expanded hard drive storage, and the Kinect motion sensing camera. The release of these additional services and peripherals helped the Xbox brand grow from gaming-only to encompassing all multimedia, turning it into a hub for living-room computing entertainment. + Microsoft + 2005 + 2005-11-22 + November 22, 2005 + Console + 243-340 + 91B61C + 92C83E + CECECE + 2FA74D + 9D9FA2 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/zmachine.xml b/themes/linear-es-de/system/metadata/zmachine.xml new file mode 100644 index 000000000..7b59ce9b6 --- /dev/null +++ b/themes/linear-es-de/system/metadata/zmachine.xml @@ -0,0 +1,17 @@ + + + Z-machine + The Z-machine is a virtual machine that was developed by Joel Berez and Marc Blank in 1979 and used by Infocom for its text adventure games. Infocom compiled game code to files containing Z-machine instructions (called story files or Z-code files) and could therefore port its text adventures to a new platform simply by writing a Z-machine implementation for that platform. With the large number of incompatible home computer systems in use at the time, this was an important advantage over using native code or developing a compiler for each system. + Joel Berez & Marc Blank + 1979 + 1979 + 1979 + Engine + 1-1 + 000000 + 333333 + 48DBCE + C1C1BE + 586C6D + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/zx81.xml b/themes/linear-es-de/system/metadata/zx81.xml new file mode 100644 index 000000000..fcb4dc7df --- /dev/null +++ b/themes/linear-es-de/system/metadata/zx81.xml @@ -0,0 +1,21 @@ + + + ZX81 + The ZX81 is a home computer that was produced by Sinclair Research and manufactured in Dundee, Scotland, by Timex Corporation. It was launched in the United Kingdom in March 1981 as the successor to Sinclair's ZX80 and designed to be a low-cost introduction to home computing for the general public. It was hugely successful; more than 1.5 million units were sold. In the United States it was initially sold as the ZX-81 under licence by Timex. Timex later produced its own versions of the ZX81: the Timex Sinclair 1000 and Timex Sinclair 1500. Unauthorized ZX81 clones were produced in several countries. + +The ZX81 was designed to be small, simple, and above all, inexpensive, with as few components as possible. Video output is to a television set rather than a dedicated monitor. Programs and data are loaded and saved onto compact audio cassettes. It uses only four silicon chips and a mere 1 KB of memory. There is no power switch or any moving parts with the exception of a VHF TV channel selector switch present in some models. It has a pressure-sensitive membrane keyboard. The ZX81's limitations prompted a market in third-party peripherals to improve its capabilities. Its distinctive case and keyboard brought designer Rick Dickinson a Design Council award. + +The ZX81 could be bought by mail order preassembled or, for a lower price, in kit form. It was the first inexpensive mass-market home computer to be sold by high street stores, led by W. H. Smith and soon many other retailers. The ZX81 marked the point when computing in Britain became an activity for the general public rather than the preserve of businessmen and electronics hobbyists. It produced a huge community of enthusiasts, some of whom founded their own businesses producing software and hardware for the ZX81. Many went on to play major roles in the British computer industry. The ZX81's commercial success made Sinclair Research one of Britain's leading computer manufacturers and earned a fortune and an eventual knighthood for the company's founder Sir Clive Sinclair. + Sinclair Research + 1981 + 1981-03-05 + March 5, 1981 + Computer + 3-4 + B92E34 + EF5857 + 403E4B + D2CECD + 191222 + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/zxnext.xml b/themes/linear-es-de/system/metadata/zxnext.xml new file mode 100644 index 000000000..890fb787b --- /dev/null +++ b/themes/linear-es-de/system/metadata/zxnext.xml @@ -0,0 +1,17 @@ + + + ZX Spectrum Next + ZX Spectrum Next is an 8-bit home computer, initially released in 2017, which is compatible with software and hardware for the 1982 ZX Spectrum. It also has enhanced capabilities. It is intended to appeal to retrocomputing enthusiasts and to "encourage a new generation of bedroom coders", according to project member Jim Bagley. Despite the name, the machine is not directly affiliated with Sinclair Research Ltd., Sir Clive Sinclair or the current owner of the trademarks, Sky Group. + SpecNext Ltd. + 2017 + 2017 + 2017 + Computer + 3-4 + 32323D + CA2825 + EDBA01 + 009C37 + 02559C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/metadata/zxspectrum.xml b/themes/linear-es-de/system/metadata/zxspectrum.xml new file mode 100644 index 000000000..083ccd2c3 --- /dev/null +++ b/themes/linear-es-de/system/metadata/zxspectrum.xml @@ -0,0 +1,17 @@ + + + ZX Spectrum + The ZX Spectrum is an 8-bit personal home computer released in the United Kingdom in 1982 by Sinclair Research Ltd. It was the follow-up to the Sinclair ZX81. The Spectrum was ultimately released as eight different models (although the models after the Spectrum 128K were technically developed and manufactured by Amstrad), ranging from the entry level model with 16 kB RAM released in 1982 to the ZX Spectrum +3 with 128 kB RAM and built in floppy disk drive. The Spectrum was among the first mainstream audience home computers in the UK, similar in significance to the Commodore 64 in the USA. The Commodore 64, BBC Microcomputer and later the Amstrad CPC range were major rivals to the Spectrum in the UK market during the early 1980s. + Sinclair Research + 1982 + 1982-04-21 + April 21, 1982 + Computer + 3-4 + 8F1B12 + CA2825 + EDBA01 + 009C37 + 02559C + + \ No newline at end of file diff --git a/themes/linear-es-de/system/systemart/3do.webp b/themes/linear-es-de/system/systemart/3do.webp new file mode 100644 index 000000000..7da3a1330 Binary files /dev/null and b/themes/linear-es-de/system/systemart/3do.webp differ diff --git a/themes/linear-es-de/system/systemart/adam.webp b/themes/linear-es-de/system/systemart/adam.webp new file mode 100644 index 000000000..4e80ded6e Binary files /dev/null and b/themes/linear-es-de/system/systemart/adam.webp differ diff --git a/themes/linear-es-de/system/systemart/ags.webp b/themes/linear-es-de/system/systemart/ags.webp new file mode 100644 index 000000000..a70edb545 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ags.webp differ diff --git a/themes/linear-es-de/system/systemart/amiga.webp b/themes/linear-es-de/system/systemart/amiga.webp new file mode 100644 index 000000000..26f45dde3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/amiga.webp differ diff --git a/themes/linear-es-de/system/systemart/amiga1200.webp b/themes/linear-es-de/system/systemart/amiga1200.webp new file mode 100644 index 000000000..706fed641 Binary files /dev/null and b/themes/linear-es-de/system/systemart/amiga1200.webp differ diff --git a/themes/linear-es-de/system/systemart/amiga600.webp b/themes/linear-es-de/system/systemart/amiga600.webp new file mode 100644 index 000000000..1fadecbf8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/amiga600.webp differ diff --git a/themes/linear-es-de/system/systemart/amigacd32.webp b/themes/linear-es-de/system/systemart/amigacd32.webp new file mode 100644 index 000000000..898d275e7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/amigacd32.webp differ diff --git a/themes/linear-es-de/system/systemart/amstradcpc.webp b/themes/linear-es-de/system/systemart/amstradcpc.webp new file mode 100644 index 000000000..2074a294f Binary files /dev/null and b/themes/linear-es-de/system/systemart/amstradcpc.webp differ diff --git a/themes/linear-es-de/system/systemart/android.webp b/themes/linear-es-de/system/systemart/android.webp new file mode 100644 index 000000000..614f8ac04 Binary files /dev/null and b/themes/linear-es-de/system/systemart/android.webp differ diff --git a/themes/linear-es-de/system/systemart/apple2.webp b/themes/linear-es-de/system/systemart/apple2.webp new file mode 100644 index 000000000..c82639286 Binary files /dev/null and b/themes/linear-es-de/system/systemart/apple2.webp differ diff --git a/themes/linear-es-de/system/systemart/apple2gs.webp b/themes/linear-es-de/system/systemart/apple2gs.webp new file mode 100644 index 000000000..58c9193a3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/apple2gs.webp differ diff --git a/themes/linear-es-de/system/systemart/arcade.webp b/themes/linear-es-de/system/systemart/arcade.webp new file mode 100644 index 000000000..34fbb1d74 Binary files /dev/null and b/themes/linear-es-de/system/systemart/arcade.webp differ diff --git a/themes/linear-es-de/system/systemart/arcadia.webp b/themes/linear-es-de/system/systemart/arcadia.webp new file mode 100644 index 000000000..1d5bc789b Binary files /dev/null and b/themes/linear-es-de/system/systemart/arcadia.webp differ diff --git a/themes/linear-es-de/system/systemart/archimedes.webp b/themes/linear-es-de/system/systemart/archimedes.webp new file mode 100644 index 000000000..dc254722d Binary files /dev/null and b/themes/linear-es-de/system/systemart/archimedes.webp differ diff --git a/themes/linear-es-de/system/systemart/arduboy.webp b/themes/linear-es-de/system/systemart/arduboy.webp new file mode 100644 index 000000000..f49c0db84 Binary files /dev/null and b/themes/linear-es-de/system/systemart/arduboy.webp differ diff --git a/themes/linear-es-de/system/systemart/astrocade.webp b/themes/linear-es-de/system/systemart/astrocade.webp new file mode 100644 index 000000000..3a1678073 Binary files /dev/null and b/themes/linear-es-de/system/systemart/astrocade.webp differ diff --git a/themes/linear-es-de/system/systemart/atari2600.webp b/themes/linear-es-de/system/systemart/atari2600.webp new file mode 100644 index 000000000..2730d4d24 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atari2600.webp differ diff --git a/themes/linear-es-de/system/systemart/atari5200.webp b/themes/linear-es-de/system/systemart/atari5200.webp new file mode 100644 index 000000000..c783ea623 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atari5200.webp differ diff --git a/themes/linear-es-de/system/systemart/atari7800.webp b/themes/linear-es-de/system/systemart/atari7800.webp new file mode 100644 index 000000000..1c8d4069f Binary files /dev/null and b/themes/linear-es-de/system/systemart/atari7800.webp differ diff --git a/themes/linear-es-de/system/systemart/atari800.webp b/themes/linear-es-de/system/systemart/atari800.webp new file mode 100644 index 000000000..09e4d5312 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atari800.webp differ diff --git a/themes/linear-es-de/system/systemart/atarijaguar.webp b/themes/linear-es-de/system/systemart/atarijaguar.webp new file mode 100644 index 000000000..d87909c35 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atarijaguar.webp differ diff --git a/themes/linear-es-de/system/systemart/atarijaguarcd.webp b/themes/linear-es-de/system/systemart/atarijaguarcd.webp new file mode 100644 index 000000000..9094a6ad8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atarijaguarcd.webp differ diff --git a/themes/linear-es-de/system/systemart/atarilynx.webp b/themes/linear-es-de/system/systemart/atarilynx.webp new file mode 100644 index 000000000..9f54aaf12 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atarilynx.webp differ diff --git a/themes/linear-es-de/system/systemart/atarist.webp b/themes/linear-es-de/system/systemart/atarist.webp new file mode 100644 index 000000000..4dd191f64 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atarist.webp differ diff --git a/themes/linear-es-de/system/systemart/atarixe.webp b/themes/linear-es-de/system/systemart/atarixe.webp new file mode 100644 index 000000000..ad6618a28 Binary files /dev/null and b/themes/linear-es-de/system/systemart/atarixe.webp differ diff --git a/themes/linear-es-de/system/systemart/atomiswave.webp b/themes/linear-es-de/system/systemart/atomiswave.webp new file mode 100644 index 000000000..e5a78f0bb Binary files /dev/null and b/themes/linear-es-de/system/systemart/atomiswave.webp differ diff --git a/themes/linear-es-de/system/systemart/auto-allgames.webp b/themes/linear-es-de/system/systemart/auto-allgames.webp new file mode 100644 index 000000000..2065940af Binary files /dev/null and b/themes/linear-es-de/system/systemart/auto-allgames.webp differ diff --git a/themes/linear-es-de/system/systemart/auto-favorites.webp b/themes/linear-es-de/system/systemart/auto-favorites.webp new file mode 100644 index 000000000..d96f8320c Binary files /dev/null and b/themes/linear-es-de/system/systemart/auto-favorites.webp differ diff --git a/themes/linear-es-de/system/systemart/auto-lastplayed.webp b/themes/linear-es-de/system/systemart/auto-lastplayed.webp new file mode 100644 index 000000000..9b5951358 Binary files /dev/null and b/themes/linear-es-de/system/systemart/auto-lastplayed.webp differ diff --git a/themes/linear-es-de/system/systemart/bbcmicro.webp b/themes/linear-es-de/system/systemart/bbcmicro.webp new file mode 100644 index 000000000..cfb729238 Binary files /dev/null and b/themes/linear-es-de/system/systemart/bbcmicro.webp differ diff --git a/themes/linear-es-de/system/systemart/c64.webp b/themes/linear-es-de/system/systemart/c64.webp new file mode 100644 index 000000000..de03fccb0 Binary files /dev/null and b/themes/linear-es-de/system/systemart/c64.webp differ diff --git a/themes/linear-es-de/system/systemart/cavestory.webp b/themes/linear-es-de/system/systemart/cavestory.webp new file mode 100644 index 000000000..89f3ad8f8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/cavestory.webp differ diff --git a/themes/linear-es-de/system/systemart/cdimono1.webp b/themes/linear-es-de/system/systemart/cdimono1.webp new file mode 100644 index 000000000..065df2a9f Binary files /dev/null and b/themes/linear-es-de/system/systemart/cdimono1.webp differ diff --git a/themes/linear-es-de/system/systemart/cdtv.webp b/themes/linear-es-de/system/systemart/cdtv.webp new file mode 100644 index 000000000..a7ff22e66 Binary files /dev/null and b/themes/linear-es-de/system/systemart/cdtv.webp differ diff --git a/themes/linear-es-de/system/systemart/chailove.webp b/themes/linear-es-de/system/systemart/chailove.webp new file mode 100644 index 000000000..b0b411522 Binary files /dev/null and b/themes/linear-es-de/system/systemart/chailove.webp differ diff --git a/themes/linear-es-de/system/systemart/channelf.webp b/themes/linear-es-de/system/systemart/channelf.webp new file mode 100644 index 000000000..9ac4b06d7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/channelf.webp differ diff --git a/themes/linear-es-de/system/systemart/coco.webp b/themes/linear-es-de/system/systemart/coco.webp new file mode 100644 index 000000000..d3e9d3000 Binary files /dev/null and b/themes/linear-es-de/system/systemart/coco.webp differ diff --git a/themes/linear-es-de/system/systemart/colecovision.webp b/themes/linear-es-de/system/systemart/colecovision.webp new file mode 100644 index 000000000..0d3ef5d86 Binary files /dev/null and b/themes/linear-es-de/system/systemart/colecovision.webp differ diff --git a/themes/linear-es-de/system/systemart/consolearcade.webp b/themes/linear-es-de/system/systemart/consolearcade.webp new file mode 100644 index 000000000..663c434c1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/consolearcade.webp differ diff --git a/themes/linear-es-de/system/systemart/cps.webp b/themes/linear-es-de/system/systemart/cps.webp new file mode 100644 index 000000000..f2005e854 Binary files /dev/null and b/themes/linear-es-de/system/systemart/cps.webp differ diff --git a/themes/linear-es-de/system/systemart/cps1.webp b/themes/linear-es-de/system/systemart/cps1.webp new file mode 100644 index 000000000..9e00b8f44 Binary files /dev/null and b/themes/linear-es-de/system/systemart/cps1.webp differ diff --git a/themes/linear-es-de/system/systemart/cps2.webp b/themes/linear-es-de/system/systemart/cps2.webp new file mode 100644 index 000000000..005d842ef Binary files /dev/null and b/themes/linear-es-de/system/systemart/cps2.webp differ diff --git a/themes/linear-es-de/system/systemart/cps3.webp b/themes/linear-es-de/system/systemart/cps3.webp new file mode 100644 index 000000000..bb7b93e66 Binary files /dev/null and b/themes/linear-es-de/system/systemart/cps3.webp differ diff --git a/themes/linear-es-de/system/systemart/crvision.webp b/themes/linear-es-de/system/systemart/crvision.webp new file mode 100644 index 000000000..888470505 Binary files /dev/null and b/themes/linear-es-de/system/systemart/crvision.webp differ diff --git a/themes/linear-es-de/system/systemart/custom-collections.webp b/themes/linear-es-de/system/systemart/custom-collections.webp new file mode 100644 index 000000000..a7f182df1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/custom-collections.webp differ diff --git a/themes/linear-es-de/system/systemart/daphne.webp b/themes/linear-es-de/system/systemart/daphne.webp new file mode 100644 index 000000000..dbf68e19d Binary files /dev/null and b/themes/linear-es-de/system/systemart/daphne.webp differ diff --git a/themes/linear-es-de/system/systemart/desktop.webp b/themes/linear-es-de/system/systemart/desktop.webp new file mode 100644 index 000000000..9508102b7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/desktop.webp differ diff --git a/themes/linear-es-de/system/systemart/doom.webp b/themes/linear-es-de/system/systemart/doom.webp new file mode 100644 index 000000000..9408a312a Binary files /dev/null and b/themes/linear-es-de/system/systemart/doom.webp differ diff --git a/themes/linear-es-de/system/systemart/dos.webp b/themes/linear-es-de/system/systemart/dos.webp new file mode 100644 index 000000000..43783c9c0 Binary files /dev/null and b/themes/linear-es-de/system/systemart/dos.webp differ diff --git a/themes/linear-es-de/system/systemart/dragon32.webp b/themes/linear-es-de/system/systemart/dragon32.webp new file mode 100644 index 000000000..3a7837312 Binary files /dev/null and b/themes/linear-es-de/system/systemart/dragon32.webp differ diff --git a/themes/linear-es-de/system/systemart/dreamcast.webp b/themes/linear-es-de/system/systemart/dreamcast.webp new file mode 100644 index 000000000..97ce8e0c8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/dreamcast.webp differ diff --git a/themes/linear-es-de/system/systemart/easyrpg.webp b/themes/linear-es-de/system/systemart/easyrpg.webp new file mode 100644 index 000000000..14b075bef Binary files /dev/null and b/themes/linear-es-de/system/systemart/easyrpg.webp differ diff --git a/themes/linear-es-de/system/systemart/electron.webp b/themes/linear-es-de/system/systemart/electron.webp new file mode 100644 index 000000000..fbd4f5fca Binary files /dev/null and b/themes/linear-es-de/system/systemart/electron.webp differ diff --git a/themes/linear-es-de/system/systemart/emulators.webp b/themes/linear-es-de/system/systemart/emulators.webp new file mode 100644 index 000000000..2a2be402a Binary files /dev/null and b/themes/linear-es-de/system/systemart/emulators.webp differ diff --git a/themes/linear-es-de/system/systemart/epic.webp b/themes/linear-es-de/system/systemart/epic.webp new file mode 100644 index 000000000..3dbd287e6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/epic.webp differ diff --git a/themes/linear-es-de/system/systemart/famicom.webp b/themes/linear-es-de/system/systemart/famicom.webp new file mode 100644 index 000000000..476db3562 Binary files /dev/null and b/themes/linear-es-de/system/systemart/famicom.webp differ diff --git a/themes/linear-es-de/system/systemart/fba.webp b/themes/linear-es-de/system/systemart/fba.webp new file mode 100644 index 000000000..5ea05dc20 Binary files /dev/null and b/themes/linear-es-de/system/systemart/fba.webp differ diff --git a/themes/linear-es-de/system/systemart/fbneo.webp b/themes/linear-es-de/system/systemart/fbneo.webp new file mode 100644 index 000000000..8123d95f0 Binary files /dev/null and b/themes/linear-es-de/system/systemart/fbneo.webp differ diff --git a/themes/linear-es-de/system/systemart/fds.webp b/themes/linear-es-de/system/systemart/fds.webp new file mode 100644 index 000000000..313a84942 Binary files /dev/null and b/themes/linear-es-de/system/systemart/fds.webp differ diff --git a/themes/linear-es-de/system/systemart/flash.webp b/themes/linear-es-de/system/systemart/flash.webp new file mode 100644 index 000000000..defc12cc2 Binary files /dev/null and b/themes/linear-es-de/system/systemart/flash.webp differ diff --git a/themes/linear-es-de/system/systemart/fm7.webp b/themes/linear-es-de/system/systemart/fm7.webp new file mode 100644 index 000000000..a47b491d1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/fm7.webp differ diff --git a/themes/linear-es-de/system/systemart/fmtowns.webp b/themes/linear-es-de/system/systemart/fmtowns.webp new file mode 100644 index 000000000..95a14fb75 Binary files /dev/null and b/themes/linear-es-de/system/systemart/fmtowns.webp differ diff --git a/themes/linear-es-de/system/systemart/fpinball.webp b/themes/linear-es-de/system/systemart/fpinball.webp new file mode 100644 index 000000000..fc018fc4e Binary files /dev/null and b/themes/linear-es-de/system/systemart/fpinball.webp differ diff --git a/themes/linear-es-de/system/systemart/gamate.webp b/themes/linear-es-de/system/systemart/gamate.webp new file mode 100644 index 000000000..8933bcaf2 Binary files /dev/null and b/themes/linear-es-de/system/systemart/gamate.webp differ diff --git a/themes/linear-es-de/system/systemart/gameandwatch.webp b/themes/linear-es-de/system/systemart/gameandwatch.webp new file mode 100644 index 000000000..1ed2a048f Binary files /dev/null and b/themes/linear-es-de/system/systemart/gameandwatch.webp differ diff --git a/themes/linear-es-de/system/systemart/gamecom.webp b/themes/linear-es-de/system/systemart/gamecom.webp new file mode 100644 index 000000000..5bcfbf0ed Binary files /dev/null and b/themes/linear-es-de/system/systemart/gamecom.webp differ diff --git a/themes/linear-es-de/system/systemart/gamegear.webp b/themes/linear-es-de/system/systemart/gamegear.webp new file mode 100644 index 000000000..f9f48244b Binary files /dev/null and b/themes/linear-es-de/system/systemart/gamegear.webp differ diff --git a/themes/linear-es-de/system/systemart/gb.webp b/themes/linear-es-de/system/systemart/gb.webp new file mode 100644 index 000000000..dc5a414af Binary files /dev/null and b/themes/linear-es-de/system/systemart/gb.webp differ diff --git a/themes/linear-es-de/system/systemart/gba.webp b/themes/linear-es-de/system/systemart/gba.webp new file mode 100644 index 000000000..bff4b8bb8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/gba.webp differ diff --git a/themes/linear-es-de/system/systemart/gbc.webp b/themes/linear-es-de/system/systemart/gbc.webp new file mode 100644 index 000000000..2eace9e19 Binary files /dev/null and b/themes/linear-es-de/system/systemart/gbc.webp differ diff --git a/themes/linear-es-de/system/systemart/gc.webp b/themes/linear-es-de/system/systemart/gc.webp new file mode 100644 index 000000000..55fc524ac Binary files /dev/null and b/themes/linear-es-de/system/systemart/gc.webp differ diff --git a/themes/linear-es-de/system/systemart/genesis.webp b/themes/linear-es-de/system/systemart/genesis.webp new file mode 100644 index 000000000..5282fbfd2 Binary files /dev/null and b/themes/linear-es-de/system/systemart/genesis.webp differ diff --git a/themes/linear-es-de/system/systemart/gmaster.webp b/themes/linear-es-de/system/systemart/gmaster.webp new file mode 100644 index 000000000..98aba6770 Binary files /dev/null and b/themes/linear-es-de/system/systemart/gmaster.webp differ diff --git a/themes/linear-es-de/system/systemart/gx4000.webp b/themes/linear-es-de/system/systemart/gx4000.webp new file mode 100644 index 000000000..da1e7366e Binary files /dev/null and b/themes/linear-es-de/system/systemart/gx4000.webp differ diff --git a/themes/linear-es-de/system/systemart/intellivision.webp b/themes/linear-es-de/system/systemart/intellivision.webp new file mode 100644 index 000000000..358dc9656 Binary files /dev/null and b/themes/linear-es-de/system/systemart/intellivision.webp differ diff --git a/themes/linear-es-de/system/systemart/j2me.webp b/themes/linear-es-de/system/systemart/j2me.webp new file mode 100644 index 000000000..ae8312419 Binary files /dev/null and b/themes/linear-es-de/system/systemart/j2me.webp differ diff --git a/themes/linear-es-de/system/systemart/kodi.webp b/themes/linear-es-de/system/systemart/kodi.webp new file mode 100644 index 000000000..078a6d92d Binary files /dev/null and b/themes/linear-es-de/system/systemart/kodi.webp differ diff --git a/themes/linear-es-de/system/systemart/laserdisc.webp b/themes/linear-es-de/system/systemart/laserdisc.webp new file mode 100644 index 000000000..5395739a5 Binary files /dev/null and b/themes/linear-es-de/system/systemart/laserdisc.webp differ diff --git a/themes/linear-es-de/system/systemart/lcdgames.webp b/themes/linear-es-de/system/systemart/lcdgames.webp new file mode 100644 index 000000000..11f85db96 Binary files /dev/null and b/themes/linear-es-de/system/systemart/lcdgames.webp differ diff --git a/themes/linear-es-de/system/systemart/lowresnx.webp b/themes/linear-es-de/system/systemart/lowresnx.webp new file mode 100644 index 000000000..029994498 Binary files /dev/null and b/themes/linear-es-de/system/systemart/lowresnx.webp differ diff --git a/themes/linear-es-de/system/systemart/lutris.webp b/themes/linear-es-de/system/systemart/lutris.webp new file mode 100644 index 000000000..e297dfd06 Binary files /dev/null and b/themes/linear-es-de/system/systemart/lutris.webp differ diff --git a/themes/linear-es-de/system/systemart/lutro.webp b/themes/linear-es-de/system/systemart/lutro.webp new file mode 100644 index 000000000..5fcb9cd10 Binary files /dev/null and b/themes/linear-es-de/system/systemart/lutro.webp differ diff --git a/themes/linear-es-de/system/systemart/macintosh.webp b/themes/linear-es-de/system/systemart/macintosh.webp new file mode 100644 index 000000000..caaf02b05 Binary files /dev/null and b/themes/linear-es-de/system/systemart/macintosh.webp differ diff --git a/themes/linear-es-de/system/systemart/mame-advmame.webp b/themes/linear-es-de/system/systemart/mame-advmame.webp new file mode 100644 index 000000000..5b6e2b42f Binary files /dev/null and b/themes/linear-es-de/system/systemart/mame-advmame.webp differ diff --git a/themes/linear-es-de/system/systemart/mame.webp b/themes/linear-es-de/system/systemart/mame.webp new file mode 100644 index 000000000..854c9e2f8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/mame.webp differ diff --git a/themes/linear-es-de/system/systemart/mario.webp b/themes/linear-es-de/system/systemart/mario.webp new file mode 100644 index 000000000..1e4cb369f Binary files /dev/null and b/themes/linear-es-de/system/systemart/mario.webp differ diff --git a/themes/linear-es-de/system/systemart/mastersystem.webp b/themes/linear-es-de/system/systemart/mastersystem.webp new file mode 100644 index 000000000..330fa3aca Binary files /dev/null and b/themes/linear-es-de/system/systemart/mastersystem.webp differ diff --git a/themes/linear-es-de/system/systemart/megacd.webp b/themes/linear-es-de/system/systemart/megacd.webp new file mode 100644 index 000000000..967a9283f Binary files /dev/null and b/themes/linear-es-de/system/systemart/megacd.webp differ diff --git a/themes/linear-es-de/system/systemart/megacdjp.webp b/themes/linear-es-de/system/systemart/megacdjp.webp new file mode 100644 index 000000000..72d2cd097 Binary files /dev/null and b/themes/linear-es-de/system/systemart/megacdjp.webp differ diff --git a/themes/linear-es-de/system/systemart/megadrive.webp b/themes/linear-es-de/system/systemart/megadrive.webp new file mode 100644 index 000000000..e2bd9ac56 Binary files /dev/null and b/themes/linear-es-de/system/systemart/megadrive.webp differ diff --git a/themes/linear-es-de/system/systemart/megadrivejp.webp b/themes/linear-es-de/system/systemart/megadrivejp.webp new file mode 100644 index 000000000..4007cb112 Binary files /dev/null and b/themes/linear-es-de/system/systemart/megadrivejp.webp differ diff --git a/themes/linear-es-de/system/systemart/megaduck.webp b/themes/linear-es-de/system/systemart/megaduck.webp new file mode 100644 index 000000000..fd741bf06 Binary files /dev/null and b/themes/linear-es-de/system/systemart/megaduck.webp differ diff --git a/themes/linear-es-de/system/systemart/mess.webp b/themes/linear-es-de/system/systemart/mess.webp new file mode 100644 index 000000000..9fb0b951e Binary files /dev/null and b/themes/linear-es-de/system/systemart/mess.webp differ diff --git a/themes/linear-es-de/system/systemart/model2.webp b/themes/linear-es-de/system/systemart/model2.webp new file mode 100644 index 000000000..1c634ee4f Binary files /dev/null and b/themes/linear-es-de/system/systemart/model2.webp differ diff --git a/themes/linear-es-de/system/systemart/model3.webp b/themes/linear-es-de/system/systemart/model3.webp new file mode 100644 index 000000000..a56f47a75 Binary files /dev/null and b/themes/linear-es-de/system/systemart/model3.webp differ diff --git a/themes/linear-es-de/system/systemart/moto.webp b/themes/linear-es-de/system/systemart/moto.webp new file mode 100644 index 000000000..7c619a828 Binary files /dev/null and b/themes/linear-es-de/system/systemart/moto.webp differ diff --git a/themes/linear-es-de/system/systemart/msx.webp b/themes/linear-es-de/system/systemart/msx.webp new file mode 100644 index 000000000..98bbd185e Binary files /dev/null and b/themes/linear-es-de/system/systemart/msx.webp differ diff --git a/themes/linear-es-de/system/systemart/msx1.webp b/themes/linear-es-de/system/systemart/msx1.webp new file mode 100644 index 000000000..be31c800d Binary files /dev/null and b/themes/linear-es-de/system/systemart/msx1.webp differ diff --git a/themes/linear-es-de/system/systemart/msx2.webp b/themes/linear-es-de/system/systemart/msx2.webp new file mode 100644 index 000000000..2a7c252fe Binary files /dev/null and b/themes/linear-es-de/system/systemart/msx2.webp differ diff --git a/themes/linear-es-de/system/systemart/msxturbor.webp b/themes/linear-es-de/system/systemart/msxturbor.webp new file mode 100644 index 000000000..2ea549868 Binary files /dev/null and b/themes/linear-es-de/system/systemart/msxturbor.webp differ diff --git a/themes/linear-es-de/system/systemart/mugen.webp b/themes/linear-es-de/system/systemart/mugen.webp new file mode 100644 index 000000000..445a53706 Binary files /dev/null and b/themes/linear-es-de/system/systemart/mugen.webp differ diff --git a/themes/linear-es-de/system/systemart/multivision.webp b/themes/linear-es-de/system/systemart/multivision.webp new file mode 100644 index 000000000..7b67343b3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/multivision.webp differ diff --git a/themes/linear-es-de/system/systemart/n3ds.webp b/themes/linear-es-de/system/systemart/n3ds.webp new file mode 100644 index 000000000..8f1830785 Binary files /dev/null and b/themes/linear-es-de/system/systemart/n3ds.webp differ diff --git a/themes/linear-es-de/system/systemart/n64.webp b/themes/linear-es-de/system/systemart/n64.webp new file mode 100644 index 000000000..7912e1650 Binary files /dev/null and b/themes/linear-es-de/system/systemart/n64.webp differ diff --git a/themes/linear-es-de/system/systemart/n64dd.webp b/themes/linear-es-de/system/systemart/n64dd.webp new file mode 100644 index 000000000..a7f81dd28 Binary files /dev/null and b/themes/linear-es-de/system/systemart/n64dd.webp differ diff --git a/themes/linear-es-de/system/systemart/naomi.webp b/themes/linear-es-de/system/systemart/naomi.webp new file mode 100644 index 000000000..f62357bab Binary files /dev/null and b/themes/linear-es-de/system/systemart/naomi.webp differ diff --git a/themes/linear-es-de/system/systemart/naomi2.webp b/themes/linear-es-de/system/systemart/naomi2.webp new file mode 100644 index 000000000..a1107be49 Binary files /dev/null and b/themes/linear-es-de/system/systemart/naomi2.webp differ diff --git a/themes/linear-es-de/system/systemart/naomigd.webp b/themes/linear-es-de/system/systemart/naomigd.webp new file mode 100644 index 000000000..f22770b33 Binary files /dev/null and b/themes/linear-es-de/system/systemart/naomigd.webp differ diff --git a/themes/linear-es-de/system/systemart/nds.webp b/themes/linear-es-de/system/systemart/nds.webp new file mode 100644 index 000000000..cdb5cfa59 Binary files /dev/null and b/themes/linear-es-de/system/systemart/nds.webp differ diff --git a/themes/linear-es-de/system/systemart/neogeo.webp b/themes/linear-es-de/system/systemart/neogeo.webp new file mode 100644 index 000000000..76d92780e Binary files /dev/null and b/themes/linear-es-de/system/systemart/neogeo.webp differ diff --git a/themes/linear-es-de/system/systemart/neogeocd.webp b/themes/linear-es-de/system/systemart/neogeocd.webp new file mode 100644 index 000000000..3c1340208 Binary files /dev/null and b/themes/linear-es-de/system/systemart/neogeocd.webp differ diff --git a/themes/linear-es-de/system/systemart/neogeocdjp.webp b/themes/linear-es-de/system/systemart/neogeocdjp.webp new file mode 100644 index 000000000..3c1340208 Binary files /dev/null and b/themes/linear-es-de/system/systemart/neogeocdjp.webp differ diff --git a/themes/linear-es-de/system/systemart/nes.webp b/themes/linear-es-de/system/systemart/nes.webp new file mode 100644 index 000000000..7ab410f90 Binary files /dev/null and b/themes/linear-es-de/system/systemart/nes.webp differ diff --git a/themes/linear-es-de/system/systemart/ngage.webp b/themes/linear-es-de/system/systemart/ngage.webp new file mode 100644 index 000000000..f7b088de6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ngage.webp differ diff --git a/themes/linear-es-de/system/systemart/ngp.webp b/themes/linear-es-de/system/systemart/ngp.webp new file mode 100644 index 000000000..a202f596d Binary files /dev/null and b/themes/linear-es-de/system/systemart/ngp.webp differ diff --git a/themes/linear-es-de/system/systemart/ngpc.webp b/themes/linear-es-de/system/systemart/ngpc.webp new file mode 100644 index 000000000..76e258496 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ngpc.webp differ diff --git a/themes/linear-es-de/system/systemart/odyssey2.webp b/themes/linear-es-de/system/systemart/odyssey2.webp new file mode 100644 index 000000000..455a7ee3b Binary files /dev/null and b/themes/linear-es-de/system/systemart/odyssey2.webp differ diff --git a/themes/linear-es-de/system/systemart/openbor.webp b/themes/linear-es-de/system/systemart/openbor.webp new file mode 100644 index 000000000..b0a4eeba6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/openbor.webp differ diff --git a/themes/linear-es-de/system/systemart/oric.webp b/themes/linear-es-de/system/systemart/oric.webp new file mode 100644 index 000000000..6d6c25bc9 Binary files /dev/null and b/themes/linear-es-de/system/systemart/oric.webp differ diff --git a/themes/linear-es-de/system/systemart/palm.webp b/themes/linear-es-de/system/systemart/palm.webp new file mode 100644 index 000000000..c7a5a4451 Binary files /dev/null and b/themes/linear-es-de/system/systemart/palm.webp differ diff --git a/themes/linear-es-de/system/systemart/pc.webp b/themes/linear-es-de/system/systemart/pc.webp new file mode 100644 index 000000000..e8ba307f3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pc.webp differ diff --git a/themes/linear-es-de/system/systemart/pc88.webp b/themes/linear-es-de/system/systemart/pc88.webp new file mode 100644 index 000000000..83cbabbf8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pc88.webp differ diff --git a/themes/linear-es-de/system/systemart/pc98.webp b/themes/linear-es-de/system/systemart/pc98.webp new file mode 100644 index 000000000..743d60502 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pc98.webp differ diff --git a/themes/linear-es-de/system/systemart/pcarcade.webp b/themes/linear-es-de/system/systemart/pcarcade.webp new file mode 100644 index 000000000..2788d5b9d Binary files /dev/null and b/themes/linear-es-de/system/systemart/pcarcade.webp differ diff --git a/themes/linear-es-de/system/systemart/pcengine.webp b/themes/linear-es-de/system/systemart/pcengine.webp new file mode 100644 index 000000000..11cb818cc Binary files /dev/null and b/themes/linear-es-de/system/systemart/pcengine.webp differ diff --git a/themes/linear-es-de/system/systemart/pcenginecd.webp b/themes/linear-es-de/system/systemart/pcenginecd.webp new file mode 100644 index 000000000..308fbfc58 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pcenginecd.webp differ diff --git a/themes/linear-es-de/system/systemart/pcfx.webp b/themes/linear-es-de/system/systemart/pcfx.webp new file mode 100644 index 000000000..0fec27780 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pcfx.webp differ diff --git a/themes/linear-es-de/system/systemart/pico8.webp b/themes/linear-es-de/system/systemart/pico8.webp new file mode 100644 index 000000000..a43f189df Binary files /dev/null and b/themes/linear-es-de/system/systemart/pico8.webp differ diff --git a/themes/linear-es-de/system/systemart/plus4.webp b/themes/linear-es-de/system/systemart/plus4.webp new file mode 100644 index 000000000..011069082 Binary files /dev/null and b/themes/linear-es-de/system/systemart/plus4.webp differ diff --git a/themes/linear-es-de/system/systemart/pokemini.webp b/themes/linear-es-de/system/systemart/pokemini.webp new file mode 100644 index 000000000..d4bd34be6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/pokemini.webp differ diff --git a/themes/linear-es-de/system/systemart/ports.webp b/themes/linear-es-de/system/systemart/ports.webp new file mode 100644 index 000000000..e3f903127 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ports.webp differ diff --git a/themes/linear-es-de/system/systemart/ps2.webp b/themes/linear-es-de/system/systemart/ps2.webp new file mode 100644 index 000000000..d5d08b6e2 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ps2.webp differ diff --git a/themes/linear-es-de/system/systemart/ps3.webp b/themes/linear-es-de/system/systemart/ps3.webp new file mode 100644 index 000000000..4cf8fc5c1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ps3.webp differ diff --git a/themes/linear-es-de/system/systemart/ps4.webp b/themes/linear-es-de/system/systemart/ps4.webp new file mode 100644 index 000000000..75cd5e184 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ps4.webp differ diff --git a/themes/linear-es-de/system/systemart/psp.webp b/themes/linear-es-de/system/systemart/psp.webp new file mode 100644 index 000000000..f5ba33b46 Binary files /dev/null and b/themes/linear-es-de/system/systemart/psp.webp differ diff --git a/themes/linear-es-de/system/systemart/psvita.webp b/themes/linear-es-de/system/systemart/psvita.webp new file mode 100644 index 000000000..4edc9db6a Binary files /dev/null and b/themes/linear-es-de/system/systemart/psvita.webp differ diff --git a/themes/linear-es-de/system/systemart/psx.webp b/themes/linear-es-de/system/systemart/psx.webp new file mode 100644 index 000000000..313493c93 Binary files /dev/null and b/themes/linear-es-de/system/systemart/psx.webp differ diff --git a/themes/linear-es-de/system/systemart/pv1000.webp b/themes/linear-es-de/system/systemart/pv1000.webp new file mode 100644 index 000000000..e9406737e Binary files /dev/null and b/themes/linear-es-de/system/systemart/pv1000.webp differ diff --git a/themes/linear-es-de/system/systemart/quake.webp b/themes/linear-es-de/system/systemart/quake.webp new file mode 100644 index 000000000..0ece062f1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/quake.webp differ diff --git a/themes/linear-es-de/system/systemart/samcoupe.webp b/themes/linear-es-de/system/systemart/samcoupe.webp new file mode 100644 index 000000000..20ca24616 Binary files /dev/null and b/themes/linear-es-de/system/systemart/samcoupe.webp differ diff --git a/themes/linear-es-de/system/systemart/satellaview.webp b/themes/linear-es-de/system/systemart/satellaview.webp new file mode 100644 index 000000000..774de60c3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/satellaview.webp differ diff --git a/themes/linear-es-de/system/systemart/saturn.webp b/themes/linear-es-de/system/systemart/saturn.webp new file mode 100644 index 000000000..b937d16dc Binary files /dev/null and b/themes/linear-es-de/system/systemart/saturn.webp differ diff --git a/themes/linear-es-de/system/systemart/saturnjp.webp b/themes/linear-es-de/system/systemart/saturnjp.webp new file mode 100644 index 000000000..10dfb6107 Binary files /dev/null and b/themes/linear-es-de/system/systemart/saturnjp.webp differ diff --git a/themes/linear-es-de/system/systemart/scummvm.webp b/themes/linear-es-de/system/systemart/scummvm.webp new file mode 100644 index 000000000..867c0f751 Binary files /dev/null and b/themes/linear-es-de/system/systemart/scummvm.webp differ diff --git a/themes/linear-es-de/system/systemart/scv.webp b/themes/linear-es-de/system/systemart/scv.webp new file mode 100644 index 000000000..faa0a4d6e Binary files /dev/null and b/themes/linear-es-de/system/systemart/scv.webp differ diff --git a/themes/linear-es-de/system/systemart/sega32x.webp b/themes/linear-es-de/system/systemart/sega32x.webp new file mode 100644 index 000000000..90dfceff6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/sega32x.webp differ diff --git a/themes/linear-es-de/system/systemart/sega32xjp.webp b/themes/linear-es-de/system/systemart/sega32xjp.webp new file mode 100644 index 000000000..90dfceff6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/sega32xjp.webp differ diff --git a/themes/linear-es-de/system/systemart/sega32xna.webp b/themes/linear-es-de/system/systemart/sega32xna.webp new file mode 100644 index 000000000..90dfceff6 Binary files /dev/null and b/themes/linear-es-de/system/systemart/sega32xna.webp differ diff --git a/themes/linear-es-de/system/systemart/segacd.webp b/themes/linear-es-de/system/systemart/segacd.webp new file mode 100644 index 000000000..88674df13 Binary files /dev/null and b/themes/linear-es-de/system/systemart/segacd.webp differ diff --git a/themes/linear-es-de/system/systemart/sfc.webp b/themes/linear-es-de/system/systemart/sfc.webp new file mode 100644 index 000000000..3e51f52ce Binary files /dev/null and b/themes/linear-es-de/system/systemart/sfc.webp differ diff --git a/themes/linear-es-de/system/systemart/sg-1000.webp b/themes/linear-es-de/system/systemart/sg-1000.webp new file mode 100644 index 000000000..e03f77f75 Binary files /dev/null and b/themes/linear-es-de/system/systemart/sg-1000.webp differ diff --git a/themes/linear-es-de/system/systemart/sgb.webp b/themes/linear-es-de/system/systemart/sgb.webp new file mode 100644 index 000000000..98c370db1 Binary files /dev/null and b/themes/linear-es-de/system/systemart/sgb.webp differ diff --git a/themes/linear-es-de/system/systemart/snes.webp b/themes/linear-es-de/system/systemart/snes.webp new file mode 100644 index 000000000..1d430e2c7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/snes.webp differ diff --git a/themes/linear-es-de/system/systemart/snesna.webp b/themes/linear-es-de/system/systemart/snesna.webp new file mode 100644 index 000000000..caa15aa57 Binary files /dev/null and b/themes/linear-es-de/system/systemart/snesna.webp differ diff --git a/themes/linear-es-de/system/systemart/solarus.webp b/themes/linear-es-de/system/systemart/solarus.webp new file mode 100644 index 000000000..e5a750794 Binary files /dev/null and b/themes/linear-es-de/system/systemart/solarus.webp differ diff --git a/themes/linear-es-de/system/systemart/spectravideo.webp b/themes/linear-es-de/system/systemart/spectravideo.webp new file mode 100644 index 000000000..737c84c1c Binary files /dev/null and b/themes/linear-es-de/system/systemart/spectravideo.webp differ diff --git a/themes/linear-es-de/system/systemart/steam.webp b/themes/linear-es-de/system/systemart/steam.webp new file mode 100644 index 000000000..e443728b7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/steam.webp differ diff --git a/themes/linear-es-de/system/systemart/stv.webp b/themes/linear-es-de/system/systemart/stv.webp new file mode 100644 index 000000000..3d0d7869b Binary files /dev/null and b/themes/linear-es-de/system/systemart/stv.webp differ diff --git a/themes/linear-es-de/system/systemart/sufami.webp b/themes/linear-es-de/system/systemart/sufami.webp new file mode 100644 index 000000000..0c2f3f4bd Binary files /dev/null and b/themes/linear-es-de/system/systemart/sufami.webp differ diff --git a/themes/linear-es-de/system/systemart/supergrafx.webp b/themes/linear-es-de/system/systemart/supergrafx.webp new file mode 100644 index 000000000..b7e8060fb Binary files /dev/null and b/themes/linear-es-de/system/systemart/supergrafx.webp differ diff --git a/themes/linear-es-de/system/systemart/supervision.webp b/themes/linear-es-de/system/systemart/supervision.webp new file mode 100644 index 000000000..9ac72dac7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/supervision.webp differ diff --git a/themes/linear-es-de/system/systemart/supracan.webp b/themes/linear-es-de/system/systemart/supracan.webp new file mode 100644 index 000000000..4edbd3ed9 Binary files /dev/null and b/themes/linear-es-de/system/systemart/supracan.webp differ diff --git a/themes/linear-es-de/system/systemart/switch.webp b/themes/linear-es-de/system/systemart/switch.webp new file mode 100644 index 000000000..d83ec7199 Binary files /dev/null and b/themes/linear-es-de/system/systemart/switch.webp differ diff --git a/themes/linear-es-de/system/systemart/symbian.webp b/themes/linear-es-de/system/systemart/symbian.webp new file mode 100644 index 000000000..5f2cf0d76 Binary files /dev/null and b/themes/linear-es-de/system/systemart/symbian.webp differ diff --git a/themes/linear-es-de/system/systemart/tanodragon.webp b/themes/linear-es-de/system/systemart/tanodragon.webp new file mode 100644 index 000000000..8f3c42529 Binary files /dev/null and b/themes/linear-es-de/system/systemart/tanodragon.webp differ diff --git a/themes/linear-es-de/system/systemart/tg-cd.webp b/themes/linear-es-de/system/systemart/tg-cd.webp new file mode 100644 index 000000000..0606350ce Binary files /dev/null and b/themes/linear-es-de/system/systemart/tg-cd.webp differ diff --git a/themes/linear-es-de/system/systemart/tg16.webp b/themes/linear-es-de/system/systemart/tg16.webp new file mode 100644 index 000000000..e19edd21a Binary files /dev/null and b/themes/linear-es-de/system/systemart/tg16.webp differ diff --git a/themes/linear-es-de/system/systemart/ti99.webp b/themes/linear-es-de/system/systemart/ti99.webp new file mode 100644 index 000000000..25ca1c0d8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/ti99.webp differ diff --git a/themes/linear-es-de/system/systemart/tic80.webp b/themes/linear-es-de/system/systemart/tic80.webp new file mode 100644 index 000000000..da1ad36df Binary files /dev/null and b/themes/linear-es-de/system/systemart/tic80.webp differ diff --git a/themes/linear-es-de/system/systemart/to8.webp b/themes/linear-es-de/system/systemart/to8.webp new file mode 100644 index 000000000..49520bdac Binary files /dev/null and b/themes/linear-es-de/system/systemart/to8.webp differ diff --git a/themes/linear-es-de/system/systemart/tools.webp b/themes/linear-es-de/system/systemart/tools.webp new file mode 100644 index 000000000..7b0dd83d9 Binary files /dev/null and b/themes/linear-es-de/system/systemart/tools.webp differ diff --git a/themes/linear-es-de/system/systemart/triforce.webp b/themes/linear-es-de/system/systemart/triforce.webp new file mode 100644 index 000000000..e6b3864b2 Binary files /dev/null and b/themes/linear-es-de/system/systemart/triforce.webp differ diff --git a/themes/linear-es-de/system/systemart/trs-80.webp b/themes/linear-es-de/system/systemart/trs-80.webp new file mode 100644 index 000000000..27e7dc32d Binary files /dev/null and b/themes/linear-es-de/system/systemart/trs-80.webp differ diff --git a/themes/linear-es-de/system/systemart/type-x.webp b/themes/linear-es-de/system/systemart/type-x.webp new file mode 100644 index 000000000..5160eab89 Binary files /dev/null and b/themes/linear-es-de/system/systemart/type-x.webp differ diff --git a/themes/linear-es-de/system/systemart/uzebox.webp b/themes/linear-es-de/system/systemart/uzebox.webp new file mode 100644 index 000000000..b01957804 Binary files /dev/null and b/themes/linear-es-de/system/systemart/uzebox.webp differ diff --git a/themes/linear-es-de/system/systemart/vectrex.webp b/themes/linear-es-de/system/systemart/vectrex.webp new file mode 100644 index 000000000..91f1eda4b Binary files /dev/null and b/themes/linear-es-de/system/systemart/vectrex.webp differ diff --git a/themes/linear-es-de/system/systemart/vic20.webp b/themes/linear-es-de/system/systemart/vic20.webp new file mode 100644 index 000000000..280f05cb0 Binary files /dev/null and b/themes/linear-es-de/system/systemart/vic20.webp differ diff --git a/themes/linear-es-de/system/systemart/videopac.webp b/themes/linear-es-de/system/systemart/videopac.webp new file mode 100644 index 000000000..fbd50093d Binary files /dev/null and b/themes/linear-es-de/system/systemart/videopac.webp differ diff --git a/themes/linear-es-de/system/systemart/virtualboy.webp b/themes/linear-es-de/system/systemart/virtualboy.webp new file mode 100644 index 000000000..a7d0f797c Binary files /dev/null and b/themes/linear-es-de/system/systemart/virtualboy.webp differ diff --git a/themes/linear-es-de/system/systemart/vpinball.webp b/themes/linear-es-de/system/systemart/vpinball.webp new file mode 100644 index 000000000..010dfb905 Binary files /dev/null and b/themes/linear-es-de/system/systemart/vpinball.webp differ diff --git a/themes/linear-es-de/system/systemart/vsmile.webp b/themes/linear-es-de/system/systemart/vsmile.webp new file mode 100644 index 000000000..1d2db0156 Binary files /dev/null and b/themes/linear-es-de/system/systemart/vsmile.webp differ diff --git a/themes/linear-es-de/system/systemart/wasm4.webp b/themes/linear-es-de/system/systemart/wasm4.webp new file mode 100644 index 000000000..64fe54fb3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/wasm4.webp differ diff --git a/themes/linear-es-de/system/systemart/wii.webp b/themes/linear-es-de/system/systemart/wii.webp new file mode 100644 index 000000000..3d1b3c789 Binary files /dev/null and b/themes/linear-es-de/system/systemart/wii.webp differ diff --git a/themes/linear-es-de/system/systemart/wiiu.webp b/themes/linear-es-de/system/systemart/wiiu.webp new file mode 100644 index 000000000..beec3856c Binary files /dev/null and b/themes/linear-es-de/system/systemart/wiiu.webp differ diff --git a/themes/linear-es-de/system/systemart/windows.webp b/themes/linear-es-de/system/systemart/windows.webp new file mode 100644 index 000000000..fbb533ffb Binary files /dev/null and b/themes/linear-es-de/system/systemart/windows.webp differ diff --git a/themes/linear-es-de/system/systemart/windows3x.webp b/themes/linear-es-de/system/systemart/windows3x.webp new file mode 100644 index 000000000..7f91f07c8 Binary files /dev/null and b/themes/linear-es-de/system/systemart/windows3x.webp differ diff --git a/themes/linear-es-de/system/systemart/windows9x.webp b/themes/linear-es-de/system/systemart/windows9x.webp new file mode 100644 index 000000000..db99a7640 Binary files /dev/null and b/themes/linear-es-de/system/systemart/windows9x.webp differ diff --git a/themes/linear-es-de/system/systemart/wonderswan.webp b/themes/linear-es-de/system/systemart/wonderswan.webp new file mode 100644 index 000000000..313641bdc Binary files /dev/null and b/themes/linear-es-de/system/systemart/wonderswan.webp differ diff --git a/themes/linear-es-de/system/systemart/wonderswancolor.webp b/themes/linear-es-de/system/systemart/wonderswancolor.webp new file mode 100644 index 000000000..f0218de6f Binary files /dev/null and b/themes/linear-es-de/system/systemart/wonderswancolor.webp differ diff --git a/themes/linear-es-de/system/systemart/x1.webp b/themes/linear-es-de/system/systemart/x1.webp new file mode 100644 index 000000000..864c30152 Binary files /dev/null and b/themes/linear-es-de/system/systemart/x1.webp differ diff --git a/themes/linear-es-de/system/systemart/x68000.webp b/themes/linear-es-de/system/systemart/x68000.webp new file mode 100644 index 000000000..8cc8ad508 Binary files /dev/null and b/themes/linear-es-de/system/systemart/x68000.webp differ diff --git a/themes/linear-es-de/system/systemart/xbox.webp b/themes/linear-es-de/system/systemart/xbox.webp new file mode 100644 index 000000000..d4aca6b28 Binary files /dev/null and b/themes/linear-es-de/system/systemart/xbox.webp differ diff --git a/themes/linear-es-de/system/systemart/xbox360.webp b/themes/linear-es-de/system/systemart/xbox360.webp new file mode 100644 index 000000000..c9f2fa1b9 Binary files /dev/null and b/themes/linear-es-de/system/systemart/xbox360.webp differ diff --git a/themes/linear-es-de/system/systemart/zelda.webp b/themes/linear-es-de/system/systemart/zelda.webp new file mode 100644 index 000000000..ecdb24fc7 Binary files /dev/null and b/themes/linear-es-de/system/systemart/zelda.webp differ diff --git a/themes/linear-es-de/system/systemart/zmachine.webp b/themes/linear-es-de/system/systemart/zmachine.webp new file mode 100644 index 000000000..4644a1768 Binary files /dev/null and b/themes/linear-es-de/system/systemart/zmachine.webp differ diff --git a/themes/linear-es-de/system/systemart/zx81.webp b/themes/linear-es-de/system/systemart/zx81.webp new file mode 100644 index 000000000..3b42af9d3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/zx81.webp differ diff --git a/themes/linear-es-de/system/systemart/zxnext.webp b/themes/linear-es-de/system/systemart/zxnext.webp new file mode 100644 index 000000000..597ab55d3 Binary files /dev/null and b/themes/linear-es-de/system/systemart/zxnext.webp differ diff --git a/themes/linear-es-de/system/systemart/zxspectrum.webp b/themes/linear-es-de/system/systemart/zxspectrum.webp new file mode 100644 index 000000000..a66ae98dc Binary files /dev/null and b/themes/linear-es-de/system/systemart/zxspectrum.webp differ diff --git a/themes/linear-es-de/theme.xml b/themes/linear-es-de/theme.xml new file mode 100644 index 000000000..72370a692 --- /dev/null +++ b/themes/linear-es-de/theme.xml @@ -0,0 +1,915 @@ + + + + ./colors.xml + ./system/metadata/_default.xml + ./system/metadata/${system.theme}.xml + ./system/metadata-custom/_default.xml + ./system/metadata-custom/${system.theme}.xml + + + ./assets/fonts/Gilroy-Light.ttf + ./assets/fonts/Oxygen-Regular.ttf + ./assets/images/pixel.png + ./assets/images/gradient.svg + + + + + 0.032 + 0.03 0.05 + 0.05 + 0.035 + 0.035 + 0.032 + 0.03 + 0.032 + 0.03 + 0.05 + 0.03 + 0.018 0 + 0.115 0.031 + + + + + 0.038 + 0.03 0.045 + 0.06 + 0.038 + 0.041 + 0.038 + 0.036 + 0.038 + 0.034 + 0.06 + 0.036 + 0.02 0 + 0.118 0.034 + + + + + ./aspect-ratio-16-9.xml + + + ./aspect-ratio-16-10.xml + + + ./aspect-ratio-4-3.xml + + + ./aspect-ratio-21-9.xml + + + + + + 0 0 + 1 1 + 0 0 + ${pixelImage} + true + ${backgroundColor} + 0 + + + 0 1 + 0 1 + always + ${pixelImage} + true + ${helpsystemPanelColor} + 60 + + + 0.5 0.9855 + 0.5 1 + ${primaryColor} + ${primaryColor} + ${primaryFont} + capitalize + + + + + + 0.5 0.5 + 1 1 + 0.5 0.5 + ./system/systemart/${system.theme}.webp + 0.12 0.12 + 9.2 + 0.115 0.25 + 3 + center + 1 + 0.8 + true + 00000000 + 0.9 + ${primaryColor} + ${primaryFont} + 0.025 + none + 13 + + + 0.0 0.365 + 0.324 0.002 + 0 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.0 0.635 + 0.324 0.002 + 0 0 + ${pixelImage} + ${primaryColor} + 11 + + + 1 0.365 + 0.324 0.002 + 1 0 + ${pixelImage} + ${primaryColor} + 11 + + + 1 0.635 + 0.324 0.002 + 1 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.325 0.364 + 0.09 0.274 + 1 0 + ${gradientImage} + ${backgroundColor} + 12 + + + 0.676 0.364 + 0.09 0.274 + 0 0 + true + ${gradientImage} + ${backgroundColor} + 12 + + + 0.986 0.025 + 0.2 0.031 + 1 0 + gamecountGames + ${primaryFont} + ${gameCounterFontSize} + right + ${primaryColor} + capitalize + 12 + + + false + + + + + + 0.5 0.776 + 0.33 0.06 + 0.5 0.5 + center + all + 0.85 + ./assets/badges/badge-folder.svg + ./assets/badges/badge-broken.svg + ./assets/badges/badge-completed.svg + ./assets/badges/badge-favorite.svg + ./assets/badges/badge-kidgame.svg + ./assets/badges/badge-collection.svg + ./assets/badges/badge-controller.svg + ./assets/badges/badge-altemulator.svg + ./assets/badges/badge-manual.svg + 0.57 0.60 + 0.48 0.5 + ${primaryColor} + ${primaryColor} + 20 + + + + + + + + 0.02 0.174 + 0.37 0.735 + 0 0 + 0.003 + -0.001 + ${gamelistTextlistSelectorColor} + ${gamelistTextlistPrimaryColor} + ${gamelistTextlistSecondaryColor} + ${gamelistTextlistSelectorColor} + ${secondaryFont} + ${textlistFontSize} + left + 0.01 + none + 1.498 + + + 0.03 0.155 + 0.36 0.002 + 0 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.302 0.154 + 0.09 0.01 + 0 0.5 + ${gradientImage} + ${backgroundColor} + 12 + + + + + + + + 0.88 0.845 + 0.14 0.10 + 0.5 0.5 + ./system/logos/${system.theme}.svg + ${gamelistWatermarkLogoColor} + + + ${systemNamePos} + 0.7 0.029 + 0 0 + ${system.fullName} + ${primaryFont} + ${systemNameFontSize} + ${primaryColor} + + + 0.03 0.10 + 0.48 0.029 + 0 0 + ${primaryFont} + ${systemLabelFontSize} + ${secondaryColor} + + + 0.374 0.268 + description + true + 1 + 4.5 + 7 + ${primaryFont} + ${descriptionFontSize} + 1.2 + ${primaryColor} + + + 0.88 0.155 + 0.17 0.002 + 0.5 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.837 0.154 + 0.088 0.01 + 0.5 0 + true + ${gradientImage} + ${backgroundColor} + 12 + + + 0.5 0 + 0.9225 0.154 + 0.088 0.01 + ${gradientImage} + ${backgroundColor} + 12 + + + 0.88 0.174 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.180 + 0.165 0.03 + 0.5 0 + Rating + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.214 + 0.115 0.031 + 0.5 0 + true + ${primaryColor} + false + + + 0.88 0.257 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.262 + 0.165 0.03 + 0.5 0 + Released + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.3 + 0.165 0.03 + 0.5 0 + releasedate + :space: + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1 + + + 0.88 0.34 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.345 + 0.165 0.03 + 0.5 0 + Players + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.383 + 0.165 0.03 + 0.5 0 + players + :space: + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1 + + + 0.88 0.423 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.428 + 0.165 0.03 + 0.5 0 + Genre + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.466 + 0.165 0.03 + 0.5 0 + genre + :space: + true + horizontal + 0.7 + 2 + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1.2 + + + 0.88 0.5055 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.511 + 0.165 0.03 + 0.5 0 + Developer + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.549 + 0.165 0.03 + 0.5 0 + developer + :space: + true + horizontal + 0.7 + 2 + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1.2 + + + 0.88 0.5885 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.5935 + 0.165 0.03 + 0.5 0 + Publisher + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.631 + 0.165 0.03 + 0.5 0 + publisher + :space: + true + horizontal + 0.7 + 2 + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1.2 + + + 0.88 0.6715 + 0.17 0.08 + 0.5 0 + ${pixelImage} + ${gamelistMetadataPanelColor} + 14 + + + 0.88 0.6765 + 0.165 0.03 + 0.5 0 + Last Played + true + ${primaryFont} + ${metadataFontSize} + center + ${gamelistMetadataLabelColor} + 1 + + + 0.88 0.715 + 0.165 0.03 + 0.5 0 + lastplayed + :space: + ${primaryFont} + ${metadataFontSize} + center + ${primaryColor} + 1 + + + 0.974 0.164 + 0.035 0.54 + 1 0 + right + column + 1 + 9 + 0.005 0.005 + + + 0.96 0.105 + 0.163 0.031 + 1 0 + ${primaryFont} + ${gamelistInfoFontSize} + right + ${primaryColor} + + + + + + + + 0.02 0.174 + 0.37 0.735 + 0 0 + 0.003 + -0.001 + ${gamelistTextlistSelectorColor} + ${gamelistTextlistPrimaryColor} + ${gamelistTextlistSecondaryColor} + ${gamelistTextlistSelectorColor} + ${secondaryFont} + ${textlistFontSize} + left + 0.01 + none + 1.498 + + + 0.03 0.146 + 0.18 0.12 + 0 1 + ./system/logos/${system.theme}.svg + ${primaryColor} + + + 0.36 0.029 + 0 0 + ${primaryFont} + 0.035 + ${tertiaryColor} + + + false + + + false + + + 0.97 0.174 + 0.04 0.64 + 1 0 + right + column + 1 + 9 + 0.005 0.005 + + + 0.97 0.035 + 0.25 0.031 + 1 0 + ${primaryFont} + ${gamelistInfoFontSizeLarge} + right + ${primaryColor} + + + + + + + + + + + + + + 0.5 0.5 + image + true + + + + + + + + + + + + + + 0.5 0 + image + true + + + + + + + + 0.5 0.5 + 1 1 + 0.5 0.5 + cover + 9.2 + 0.12 0.12 + 0.105 0.18 + 3 + 0.003 + center + 1 + 0.8 + 0.8 + true + 00000000 + 0.9 + ${primaryColor} + ${primaryFont} + 0.025 + none + 13 + + + 0.0 0.365 + 0.324 0.002 + 0 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.0 0.635 + 0.324 0.002 + 0 0 + ${pixelImage} + ${primaryColor} + 11 + + + 1 0.365 + 0.324 0.002 + 1 0 + ${pixelImage} + ${primaryColor} + 11 + + + 1 0.635 + 0.324 0.002 + 1 0 + ${pixelImage} + ${primaryColor} + 11 + + + 0.325 0.364 + 0.09 0.274 + 1 0 + ${gradientImage} + ${backgroundColor} + 12 + + + 0.676 0.364 + 0.09 0.274 + 0 0 + true + ${gradientImage} + ${backgroundColor} + 12 + + + 0.5 0.13 + 0.25 0.1 + 0.5 0.5 + ./system/logos/${system.theme}.svg + ./system/custom/logo/${system.theme}.svg + ${primaryColor} + + + 0.5 0.87 + 0.97 0.08 + 0.5 0.5 + name + false + true + horizontal + 2.5 + ${primaryFont} + ${carouselGameNameFontSize} + center + ${primaryColor} + + + 0.5 0.2 + 0.45 0.029 + 0.5 0.5 + ${primaryFont} + 0.035 + center + ${primaryColor} + + + false + + + false + + + 0.986 0.025 + 0.25 0.031 + 1 0 + ${primaryFont} + ${gamelistInfoFontSizeLarge} + right + ${primaryColor} + + + 0.5 0.776 + 0.33 0.06 + 0.5 0.5 + center + row + 1 + 9 + 0.005 0.005 + + + + + + + + 0.12 0.7 + ${carouselRatingSize} + 0 0.5 + ${primaryColor} + false + + + 0.12 0.744 + ${carouselMetadataIconsSize} + 0 0.5 + ./assets/images/icon-players.svg + true + ${primaryColor} + + + 0.146 0.744 + 0.164 0.029 + 0 0.5 + players + :space: + ${primaryFont} + ${carouselMetadataFontSize} + left + ${primaryColor} + + + 0.12 0.788 + 0.19 0.03 + 0 0.5 + genre + :space: + true + horizontal + 0.7 + 2 + 0.9 + ${primaryFont} + ${carouselMetadataFontSize} + left + ${primaryColor} + 1.2 + + + 0.72 0.7 + ${carouselMetadataIconsSize} + 0 0.5 + ./assets/images/icon-release-date.svg + true + ${primaryColor} + + + 0.745 0.7 + 0.16 0.029 + 0 0.5 + releasedate + :space: + ${primaryFont} + ${carouselMetadataFontSize} + left + ${primaryColor} + 1 + + + 0.72 0.744 + 0.26 0.029 + 0 0.5 + developer + :space: + true + horizontal + 0.7 + 2 + 0.9 + ${primaryFont} + ${carouselMetadataFontSize} + left + ${primaryColor} + none + + + 0.72 0.788 + 0.26 0.029 + 0 0.5 + publisher + :space: + true + horizontal + 0.7 + 2 + 0.9 + ${primaryFont} + ${carouselMetadataFontSize} + left + ${primaryColor} + none + + + + \ No newline at end of file diff --git a/themes/modern-es-de/CREDITS.md b/themes/modern-es-de/CREDITS.md index d84701625..a6c6597aa 100644 --- a/themes/modern-es-de/CREDITS.md +++ b/themes/modern-es-de/CREDITS.md @@ -1,4 +1,4 @@ -# Modern for EmulationStation Desktop Edition - credits +# Modern for ES-DE - credits The Modern theme is based on [es-theme-switch](https://github.com/lilbud/es-theme-switch) by lilbud, and it was modified for ES-DE by Sophia Hadash. diff --git a/themes/modern-es-de/README.md b/themes/modern-es-de/README.md index e61e76237..53615d9c3 100644 --- a/themes/modern-es-de/README.md +++ b/themes/modern-es-de/README.md @@ -1,4 +1,4 @@ -# Modern for EmulationStation Desktop Edition (modern-es-de) +# Modern for ES-DE (modern-es-de) The following options are included: @@ -14,6 +14,11 @@ The following options are included: - Dark - Light +2 font sizes: + +- Medium +- Large + 4 aspect ratios: - 16:9 diff --git a/themes/modern-es-de/aspect-ratio-16-10.xml b/themes/modern-es-de/aspect-ratio-16-10.xml index ce3af94e2..268ceb2e5 100644 --- a/themes/modern-es-de/aspect-ratio-16-10.xml +++ b/themes/modern-es-de/aspect-ratio-16-10.xml @@ -25,6 +25,10 @@ + + 0.004 + 0.002 + 2 5 diff --git a/themes/modern-es-de/aspect-ratio-16-9.xml b/themes/modern-es-de/aspect-ratio-16-9.xml index 7bf7be82a..0d53b91c5 100644 --- a/themes/modern-es-de/aspect-ratio-16-9.xml +++ b/themes/modern-es-de/aspect-ratio-16-9.xml @@ -25,6 +25,10 @@ + + 0.0035 + 0.003 + 2 5 diff --git a/themes/modern-es-de/aspect-ratio-21-9.xml b/themes/modern-es-de/aspect-ratio-21-9.xml index 000c9586f..32b67b06e 100644 --- a/themes/modern-es-de/aspect-ratio-21-9.xml +++ b/themes/modern-es-de/aspect-ratio-21-9.xml @@ -25,6 +25,10 @@ + + 0.0022 + 0.004 + 2 5 diff --git a/themes/modern-es-de/aspect-ratio-4-3.xml b/themes/modern-es-de/aspect-ratio-4-3.xml index 26038031f..5143eaa1f 100644 --- a/themes/modern-es-de/aspect-ratio-4-3.xml +++ b/themes/modern-es-de/aspect-ratio-4-3.xml @@ -25,6 +25,10 @@ + + 0.005 + 0 + 2 5 diff --git a/themes/modern-es-de/assets/frame.png b/themes/modern-es-de/assets/frame.png new file mode 100644 index 000000000..731a7a13c Binary files /dev/null and b/themes/modern-es-de/assets/frame.png differ diff --git a/themes/modern-es-de/assets/selection_box.svg b/themes/modern-es-de/assets/selection_box.svg index 0afbf0c3d..9559d5522 100644 --- a/themes/modern-es-de/assets/selection_box.svg +++ b/themes/modern-es-de/assets/selection_box.svg @@ -5,37 +5,11 @@ version="1.1" viewBox="0 0 400 400" id="svg4" - sodipodi:docname="selection_box.svg" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" - inkscape:export-filename="/home/leon/Leon/Programmering/EmulationStation-DE/emulationstation-de/themes/modern-es-de/assets/selection_box.png" - inkscape:export-xdpi="72" - inkscape:export-ydpi="72" shape-rendering="crispEdges" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> - + ry="0" /> diff --git a/themes/modern-es-de/assets/selector.png b/themes/modern-es-de/assets/selector.png deleted file mode 100644 index 0e70f2479..000000000 Binary files a/themes/modern-es-de/assets/selector.png and /dev/null differ diff --git a/themes/modern-es-de/capabilities.xml b/themes/modern-es-de/capabilities.xml index 567309c43..9c6c01c2c 100644 --- a/themes/modern-es-de/capabilities.xml +++ b/themes/modern-es-de/capabilities.xml @@ -10,6 +10,9 @@ 4:3 21:9 + medium + large + diff --git a/themes/modern-es-de/theme.xml b/themes/modern-es-de/theme.xml index 0c6c61beb..d7bb6d106 100644 --- a/themes/modern-es-de/theme.xml +++ b/themes/modern-es-de/theme.xml @@ -1,5 +1,5 @@ + 0.032 + 0.04 + + 0.03 + 0.030 + 1.9 + 0.03 + 0.03 + 1.2 + 0.02 + 0.03 + 0.70 0.532 + 0.8453 0.532 + 0.70 0.608 + 0.8453 0.608 + 0.70 0.684 + 0.70 0.760 + 0.04 0.03 + 0.1267 0.185 + + + + + + 0.036 + 0.045 + + 0.04 + 0.0368 + 1.7 + 0.036 + 0.037 + 1.15 + 0.025 + 0.036 + 0.70 0.527 + 0.8453 0.527 + 0.70 0.602 + 0.8453 0.602 + 0.70 0.679 + 0.70 0.760 + 0 0.035 + 0.1267 0.205 + + + ./aspect-ratio-16-9.xml @@ -99,7 +148,7 @@ 0.5 0.5 gamecount ${mainFont} - 0.032 + ${gameCounterFontSize} center ${mainColor} capitalize @@ -117,7 +166,7 @@ 0.743 0.035 0 0.5 ${mainFont} - 0.04 + ${systemNameFontSize} left ${mainColor} @@ -148,19 +197,16 @@ 0.04 0.182 0.31 0.68 0 0 - 0.075 - -0.0015 ${mainColor} - ./assets/selector.png ${mainColor} ${secondaryColor} ${tertiaryColor} ${mainFont} - 0.030 + ${gamelistFontSize} left 0.01 none - 1.9 + ${gamelistLineSpacing} 0.5 0.13 @@ -174,7 +220,7 @@ 0.034 0.065 0.743 0.031 ${mainFont} - 0.03 + ${gamelistSystemNameFontSize} left ${secondaryColor} capitalize @@ -200,10 +246,10 @@ 0.966 0.065 - 0.2 0.031 + 0.25 0.031 1 0 ${mainFont} - 0.03 + ${gamelistInfoFontSize} right ${secondaryColor} @@ -244,85 +290,85 @@ 1 4.5 7 - 0.03 - 1.2 + ${descriptionFontSize} + ${descriptionLineSpacing} - 0.70 0.532 + ${publisherLabelPos} 0.13125 0.02 Publisher: true - 0.02 + ${metadataLabelFontSize} 0.70 0.552 0.13125 0.03 publisher Unknown - 0.03 + ${metadataValueFontSize} - 0.8453 0.532 + ${developerLabelPos} 0.13125 0.02 Developer: true - 0.02 + ${metadataLabelFontSize} 0.8453 0.552 0.13125 0.03 developer Unknown - 0.03 + ${metadataValueFontSize} - 0.70 0.608 + ${releaseDateLabelPos} 0.13125 0.02 Released: true - 0.02 + ${metadataLabelFontSize} 0.70 0.628 0.13125 0.03 releasedate Unknown - 0.03 + ${metadataValueFontSize} - 0.8453 0.608 + ${playersLabelPos} 0.13125 0.02 Players: true - 0.02 + ${metadataLabelFontSize} 0.8453 0.628 0.13125 0.03 players Unknown - 0.03 + ${metadataValueFontSize} - 0.70 0.684 + ${genreLabelPos} 0.13125 0.02 Genre: true - 0.02 + ${metadataLabelFontSize} 0.70 0.704 0.13125 0.03 genre Unknown - 0.03 + ${metadataValueFontSize} - 0.70 0.760 + ${ratingLabelPos} 0.13125 0.02 Rating: true - 0.02 + ${metadataLabelFontSize} @@ -336,13 +382,13 @@ 0.70 0.785 - 0.04 0.03 + ${ratingSize} ./assets/star-filled.svg ./assets/${colorSchemeName}/star-unfilled.svg 0.8423 0.685 - 0.1267 0.185 + ${badgesSize} 0 0 column collection, folder, favorite, completed, kidgame, broken, controller, altemulator, manual diff --git a/themes/slate-es-de/CREDITS.md b/themes/slate-es-de/CREDITS.md index 8797c42d6..8ce2d57ef 100644 --- a/themes/slate-es-de/CREDITS.md +++ b/themes/slate-es-de/CREDITS.md @@ -1,4 +1,4 @@ -# Slate for EmulationStation Desktop Edition - credits +# Slate for ES-DE - credits The Slate theme is based on [recalbox-multi](https://gitlab.com/recalbox/recalbox-themes) by the Recalbox community, prior to their license change in 2018. diff --git a/themes/slate-es-de/MISSING.md b/themes/slate-es-de/MISSING.md index 92fd301b8..1ca14750d 100644 --- a/themes/slate-es-de/MISSING.md +++ b/themes/slate-es-de/MISSING.md @@ -1,4 +1,4 @@ -# EmulationStation Desktop Edition (ES-DE) - Missing slate-es-de theme assets +# ES-DE - Missing slate-es-de theme assets * ags: Adventure Game Studio Game Engine - consolegame.svg, controller.svg * amigacd32: Amiga CD32 - consolegame.svg, controller.svg diff --git a/themes/slate-es-de/README.md b/themes/slate-es-de/README.md index 8f6d1e19b..bbaa8e32e 100644 --- a/themes/slate-es-de/README.md +++ b/themes/slate-es-de/README.md @@ -1,4 +1,4 @@ -# Slate for EmulationStation Desktop Edition (slate-es-de) +# Slate for ES-DE (slate-es-de) The following options are included: @@ -12,6 +12,11 @@ The following options are included: - Dark - Light +2 font sizes: + +- Medium +- Large + 4 aspect ratios: - 16:9 diff --git a/themes/slate-es-de/android/images/logo.svg b/themes/slate-es-de/android/images/logo.svg index b409a241f..095870b56 100644 --- a/themes/slate-es-de/android/images/logo.svg +++ b/themes/slate-es-de/android/images/logo.svg @@ -1,19 +1,15 @@ + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> @@ -22,96 +18,43 @@ image/svg+xml - - + + + 0.025 + 0.70 0.03 + 0.023 + 0.05 0.675 + 0.05 0.690 + 0.05 0.705 + 0.05 0.720 + 0.05 0.750 + 0.05 0.765 + 0.05 0.780 + 0.05 0.795 + 0.05 0.810 + 0.05 0.825 + 0.0264 + 0.026 + 0.026 + 0.026 + 0 0.02 + 0.11 0.235 + + + + + 0.027 + 0.70 0.03 + 0.027 + 0.05 0.675 + 0.05 0.692 + 0.05 0.709 + 0.05 0.726 + 0.05 0.756 + 0.05 0.773 + 0.05 0.790 + 0.05 0.807 + 0.05 0.824 + 0.05 0.841 + 0.0326 + 0.03 + 0.0315 + 0.028 + 0 0.02 + 0.11 0.235 + + + 0.012 0.98 - 0.025 + ${helpsystemFontSize} @@ -17,7 +64,7 @@ - 0.0264 + ${gamelistFontSize} 0.35 0.12 @@ -47,38 +94,38 @@ 0.12 0.14 - 0.70 0.03 - 0.023 + ${systemInfoSize} + ${systemInfoFontSize} - 0.05 0.675 + ${systemInfoPos1} - 0.05 0.690 + ${systemInfoPos2} - 0.05 0.705 + ${systemInfoPos3} - 0.05 0.720 + ${systemInfoPos4} - 0.05 0.750 + ${systemInfoPos5} - 0.05 0.765 + ${systemInfoPos6} - 0.05 0.780 + ${systemInfoPos7} - 0.05 0.795 + ${systemInfoPos8} - 0.05 0.810 + ${systemInfoPos9} - 0.05 0.825 + ${systemInfoPos10} @@ -98,7 +145,7 @@ 0.155 0.02 - 0.026 + ${metadataFontSize} 0.454 0.535 @@ -106,7 +153,7 @@ 0.454 0.558 0.155 0.02 - 0.026 + ${metadataFontSize} 0.62 0.535 @@ -138,24 +185,24 @@ 0.79 0.613 0.155 0.02 - 0.026 + ${metadataFontSize} 0.454 0.655 0.384 0.262 - 0.026 + ${descriptionFontSize} - 0 0.02 + ${ratingSize} 0.723 0.192 0.24 0.042 - 0.026 + ${gamelistInfoFontSize} 0.96 0.655 - 0.11 0.235 + ${badgesSize} 1 0 5 2 diff --git a/themes/slate-es-de/aspect-ratio-16-9.xml b/themes/slate-es-de/aspect-ratio-16-9.xml index 31ad0a623..aa49d30a3 100644 --- a/themes/slate-es-de/aspect-ratio-16-9.xml +++ b/themes/slate-es-de/aspect-ratio-16-9.xml @@ -1,9 +1,56 @@ + + + 0.035 + 0.40 0.03 + 0.021 + 0.38 0.695 + 0.38 0.716 + 0.38 0.737 + 0.38 0.758 + 0.38 0.800 + 0.38 0.821 + 0.38 0.842 + 0.38 0.863 + 0.38 0.884 + 0.38 0.905 + 0.025 + 0.025 + 0.0195 + 0.0195 + 0 0.03 + 0.13 0.235 + + + + + 0.035 + 0.416 0.03 + 0.024 + 0.38 0.680 + 0.38 0.705 + 0.38 0.730 + 0.38 0.755 + 0.38 0.795 + 0.38 0.820 + 0.38 0.845 + 0.38 0.870 + 0.38 0.895 + 0.38 0.920 + 0.0296 + 0.028 + 0.025 + 0.0235 + 0 0.03 + 0.13 0.235 + + + 0.012 0.955 - 0.035 + ${helpsystemFontSize} @@ -17,7 +64,7 @@ - 0.025 + ${gamelistFontSize} 0.4 0.15 @@ -47,38 +94,38 @@ 0.12 0.28 - 0.40 0.03 - 0.021 + ${systemInfoSize} + ${systemInfoFontSize} - 0.38 0.695 + ${systemInfoPos1} - 0.38 0.716 + ${systemInfoPos2} - 0.38 0.737 + ${systemInfoPos3} - 0.38 0.758 + ${systemInfoPos4} - 0.38 0.800 + ${systemInfoPos5} - 0.38 0.821 + ${systemInfoPos6} - 0.38 0.842 + ${systemInfoPos7} - 0.38 0.863 + ${systemInfoPos8} - 0.38 0.884 + ${systemInfoPos9} - 0.38 0.905 + ${systemInfoPos10} @@ -98,7 +145,7 @@ 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.815 0.2755 @@ -106,7 +153,7 @@ 0.83 0.3005 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.815 0.3355 @@ -138,24 +185,24 @@ 0.83 0.6005 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.454 0.675 0.346 0.242 - 0.0195 + ${descriptionFontSize} - 0 0.03 + ${ratingSize} 0.773 0.192 0.2 0.042 - 0.025 + ${gamelistInfoFontSize} 0.815 0.675 - 0.13 0.235 + ${badgesSize} 0 0 3 3 diff --git a/themes/slate-es-de/aspect-ratio-4-3-vertical.xml b/themes/slate-es-de/aspect-ratio-4-3-vertical.xml index 36adc3390..5e3d4f3eb 100644 --- a/themes/slate-es-de/aspect-ratio-4-3-vertical.xml +++ b/themes/slate-es-de/aspect-ratio-4-3-vertical.xml @@ -1,9 +1,56 @@ + + + 0.025 + 0.70 0.03 + 0.023 + 0.05 0.675 + 0.05 0.694 + 0.05 0.713 + 0.05 0.732 + 0.05 0.770 + 0.05 0.789 + 0.05 0.808 + 0.05 0.827 + 0.05 0.846 + 0.05 0.865 + 0.0264 + 0.026 + 0.026 + 0.026 + 0 0.02 + 0.11 0.245 + + + + + 0.027 + 0.70 0.03 + 0.027 + 0.05 0.675 + 0.05 0.696 + 0.05 0.717 + 0.05 0.738 + 0.05 0.778 + 0.05 0.799 + 0.05 0.820 + 0.05 0.841 + 0.05 0.862 + 0.05 0.883 + 0.0335 + 0.030 + 0.0318 + 0.0285 + 0 0.022 + 0.11 0.245 + + + 0.012 0.975 - 0.025 + ${helpsystemFontSize} @@ -17,7 +64,7 @@ - 0.0264 + ${gamelistFontSize} 0.35 0.12 @@ -47,38 +94,38 @@ 0.12 0.17 - 0.70 0.03 - 0.023 + ${systemInfoSize} + ${systemInfoFontSize} - 0.05 0.675 + ${systemInfoPos1} - 0.05 0.694 + ${systemInfoPos2} - 0.05 0.713 + ${systemInfoPos3} - 0.05 0.732 + ${systemInfoPos4} - 0.05 0.770 + ${systemInfoPos5} - 0.05 0.789 + ${systemInfoPos6} - 0.05 0.808 + ${systemInfoPos7} - 0.05 0.827 + ${systemInfoPos8} - 0.05 0.846 + ${systemInfoPos9} - 0.05 0.865 + ${systemInfoPos10} @@ -98,7 +145,7 @@ 0.155 0.02 - 0.026 + ${metadataFontSize} 0.454 0.535 @@ -106,7 +153,7 @@ 0.454 0.558 0.155 0.02 - 0.026 + ${metadataFontSize} 0.62 0.535 @@ -138,24 +185,24 @@ 0.79 0.613 0.155 0.02 - 0.026 + ${metadataFontSize} 0.454 0.655 0.384 0.262 - 0.026 + ${descriptionFontSize} - 0 0.02 + ${ratingSize} 0.723 0.192 0.24 0.042 - 0.026 + ${gamelistInfoFontSize} 0.96 0.655 - 0.11 0.245 + ${badgesSize} 1 0 5 2 diff --git a/themes/slate-es-de/aspect-ratio-4-3.xml b/themes/slate-es-de/aspect-ratio-4-3.xml index f23b1c6da..2ebf458ae 100644 --- a/themes/slate-es-de/aspect-ratio-4-3.xml +++ b/themes/slate-es-de/aspect-ratio-4-3.xml @@ -1,9 +1,56 @@ + + + 0.034 + 0.44 0.03 + 0.021 + 0.34 0.695 + 0.34 0.716 + 0.34 0.737 + 0.34 0.758 + 0.34 0.799 + 0.34 0.820 + 0.34 0.841 + 0.34 0.862 + 0.34 0.883 + 0.34 0.904 + 0.025 + 0.025 + 0.0195 + 0.0195 + 0 0.03 + 0.13 0.235 + + + + + 0.034 + 0.46 0.03 + 0.0238 + 0.34 0.680 + 0.34 0.705 + 0.34 0.730 + 0.34 0.755 + 0.34 0.795 + 0.34 0.820 + 0.34 0.845 + 0.34 0.870 + 0.34 0.895 + 0.34 0.920 + 0.03165 + 0.029 + 0.025 + 0.0235 + 0 0.03 + 0.14 0.235 + + + 0.012 0.955 - 0.034 + ${helpsystemFontSize} @@ -17,7 +64,7 @@ - 0.025 + ${gamelistFontSize} 0.4 0.15 @@ -47,38 +94,38 @@ 0.12 0.28 - 0.44 0.03 - 0.021 + ${systemInfoSize} + ${systemInfoFontSize} - 0.34 0.695 + ${systemInfoPos1} - 0.34 0.716 + ${systemInfoPos2} - 0.34 0.737 + ${systemInfoPos3} - 0.34 0.758 + ${systemInfoPos4} - 0.34 0.799 + ${systemInfoPos5} - 0.34 0.820 + ${systemInfoPos6} - 0.34 0.841 + ${systemInfoPos7} - 0.34 0.862 + ${systemInfoPos8} - 0.34 0.883 + ${systemInfoPos9} - 0.34 0.904 + ${systemInfoPos10} @@ -98,7 +145,7 @@ 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.815 0.2755 @@ -106,7 +153,7 @@ 0.83 0.3005 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.815 0.3355 @@ -138,24 +185,24 @@ 0.83 0.6005 0.14 0.02 - 0.0195 + ${metadataFontSize} 0.454 0.675 0.346 0.242 - 0.0195 + ${descriptionFontSize} - 0 0.03 + ${ratingSize} 0.773 0.192 0.2 0.042 - 0.025 + ${gamelistInfoFontSize} 0.815 0.675 - 0.13 0.235 + ${badgesSize} 0 0 3 3 diff --git a/themes/slate-es-de/auto-favorites/images/logo.svg b/themes/slate-es-de/auto-favorites/images/logo.svg index 63b9aabe0..2735bfcdd 100644 --- a/themes/slate-es-de/auto-favorites/images/logo.svg +++ b/themes/slate-es-de/auto-favorites/images/logo.svg @@ -2,14 +2,6 @@ image/svg+xml \ No newline at end of file + id="path4952" /> diff --git a/themes/slate-es-de/capabilities.xml b/themes/slate-es-de/capabilities.xml index 26ce9b218..8c5b70b8f 100644 --- a/themes/slate-es-de/capabilities.xml +++ b/themes/slate-es-de/capabilities.xml @@ -10,6 +10,9 @@ 4:3 4:3_vertical + medium + large + diff --git a/themes/slate-es-de/cps/images/logo.svg b/themes/slate-es-de/cps/images/logo.svg index 279706252..ae54ebb14 100644 --- a/themes/slate-es-de/cps/images/logo.svg +++ b/themes/slate-es-de/cps/images/logo.svg @@ -3,38 +3,12 @@ viewBox="0 0 1758.6 493.19999" version="1.1" id="svg45" - sodipodi:docname="logo.svg" - inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)" width="1758.6" height="493.20001" - inkscape:export-filename="/home/leon/Leon/Programmering/EmulationStation-DE/emulationstation-de/themes/slate-DE/cps/images/logo.png" - inkscape:export-xdpi="32.700729" - inkscape:export-ydpi="32.700729" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> - + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> - @@ -108,13 +73,10 @@ image/svg+xml - + transform="matrix(0.26458333,0,0,0.26458333,15.635294,241.12131)" /> + d="m 16.763386,275.86523 -0.996309,0.99631 v 5.97955 l 0.996309,0.9963 h 5.979547 v -1.99318 h -4.983239 v -3.9858 h 3.986365 l 0.996874,-1.99318 z m 7.863157,0 -0.996309,0.99631 v 5.97955 l 0.996309,0.9963 h 4.982674 l 0.996874,-0.9963 v -5.97955 l -0.996874,-0.99631 z m 6.86685,0 v 7.97216 h 5.979549 l 0.996307,-1.99318 h -4.982674 v -5.97898 z m 7.863159,0 v 7.97216 h 5.979546 l 0.996311,-1.99318 h -4.982674 v -5.97898 z m 7.863723,0 v 7.97216 h 5.978983 v -1.99318 h -3.985799 v -0.9963 h 3.985799 v -1.99318 h -3.985799 v -0.99632 h 3.985799 v -1.99318 z m 7.863157,0 -0.996309,0.99631 v 5.97955 l 0.996309,0.9963 h 5.978984 v -1.99318 h -4.982674 v -3.9858 h 3.986364 l 0.99631,-1.99318 z m 6.866851,0 v 1.99318 h 2.491335 v 5.97898 h 1.993183 v -5.97898 h 2.491339 v -1.99318 z m 7.863156,0 v 7.97216 h 1.993183 v -7.97216 z m 3.877361,0 -0.996875,0.99631 v 5.97955 l 0.996875,0.9963 h 4.982674 l 0.996308,-0.9963 v -5.97955 l -0.996308,-0.99631 z m 6.866849,0 v 7.97216 h 1.992619 v -4.98266 l 2.491335,4.98266 h 2.491339 v -7.97216 h -1.992619 v 4.98268 l -2.491336,-4.98268 z m 8.859461,0 -0.996302,0.99631 v 2.99006 l 0.996302,0.99631 h 3.986373 v 0.9963 h -4.982675 v 1.99318 h 4.982675 l 1.993181,-1.99318 v -2.98948 h -4.982679 v -0.99632 h 3.986948 l 0.995731,-1.99318 z m -63.793692,1.99318 h 2.98949 v 3.9858 h -2.98949 z m 49.06369,0 h 2.989491 v 3.9858 h -2.989491 z" /> + id="path4538" /> diff --git a/themes/slate-es-de/dreamcast/images/jp/consolegame.svg b/themes/slate-es-de/dreamcast/images/jp/consolegame.svg index 93a1e1ae5..781f18738 100644 --- a/themes/slate-es-de/dreamcast/images/jp/consolegame.svg +++ b/themes/slate-es-de/dreamcast/images/jp/consolegame.svg @@ -2,146 +2,94 @@ image/svg+xml \ No newline at end of file + style="fill:#8c8c8c" /> diff --git a/themes/slate-es-de/dreamcast/images/us/consolegame.svg b/themes/slate-es-de/dreamcast/images/us/consolegame.svg index 1c328f350..457e4f65d 100644 --- a/themes/slate-es-de/dreamcast/images/us/consolegame.svg +++ b/themes/slate-es-de/dreamcast/images/us/consolegame.svg @@ -2,320 +2,244 @@ image/svg+xml \ No newline at end of file + style="fill:#2f3338" /> diff --git a/themes/slate-es-de/theme.xml b/themes/slate-es-de/theme.xml index 12ec97351..7532a77a7 100644 --- a/themes/slate-es-de/theme.xml +++ b/themes/slate-es-de/theme.xml @@ -1,5 +1,5 @@