New automatic Crowdin sync procedure (#210)

This commit is contained in:
Michael Burgardt 2021-11-12 22:54:17 +01:00 committed by GitHub
parent b0c79f0833
commit 0096b3e8b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 465 additions and 1360 deletions

View File

@ -1,41 +1,34 @@
# Prepare source for Crowdin sync
# Prepare source texts & upload them to Crowdin
name: Crowdin Upload Preparation
name: Crowdin Source Texts Upload
# on change to the English texts
on:
push:
branches:
- master
paths:
- 'libgambatte/libretro/libretro_core_options.h'
- "libgambatte/libretro/libretro_core_options.h"
jobs:
prepare_source_file:
upload_source_file:
runs-on: ubuntu-latest
steps:
- name: Setup Java JDK
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Setup Python
uses: actions/setup-python@v2
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal access token.
fetch-depth: 0 # otherwise, there would be errors pushing refs to the destination repository.
- name: Crowdin Prep
- name: Upload Source
shell: bash
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: |
python3 intl/crowdin_prep.py 'libgambatte/libretro'
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add intl/*
git commit -m "Recreate translation source text files" -a
- name: GitHub Push
uses: ad-m/github-push-action@v0.6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
python3 intl/crowdin_prep.py "libgambatte/libretro"
python3 intl/crowdin_source_upload.py "$CROWDIN_API_KEY" "gambatte-libretro"

View File

@ -1,21 +1,23 @@
# Recreate libretro_core_options_intl.h using translations form Crowdin
# Download translations form Crowdin & Recreate libretro_core_options_intl.h
name: Crowdin Translation Integration
on:
push:
branches:
- master
paths:
- 'intl/*/*'
schedule:
- cron: '0 0 * * *' # every day at midnight
jobs:
create_intl_file:
runs-on: ubuntu-latest
steps:
- name: Setup Java JDK
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Setup Python
uses: actions/setup-python@v2
- name: Checkout
uses: actions/checkout@v2
with:
@ -24,15 +26,17 @@ jobs:
- name: Create intl file
shell: bash
env:
CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }}
run: |
python3 intl/crowdin_intl.py 'libgambatte/libretro'
python3 intl/translation_workflow.py "$CROWDIN_API_KEY" "gambatte-libretro" "libgambatte/libretro"
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.email "github-actions@github.com"
git config --local user.name "github-actions[bot]"
git add libgambatte/libretro/libretro_core_options_intl.h
git commit -m "Recreate libretro_core_options_intl.h" -a
git add intl/translation_workflow.py "libgambatte/libretro/libretro_core_options_intl.h"
git commit -m "Fetch translations & Recreate libretro_core_options_intl.h"
- name: GitHub Push
uses: ad-m/github-push-action@v0.6.0

2
intl/.gitignore vendored
View File

@ -1 +1,3 @@
__pycache__
crowdin-cli.jar
_*/*

View File

@ -1,359 +0,0 @@
CATEGORY_GB_LINK_LABEL "Game Boy Link"
CATEGORY_GB_LINK_INFO_0 "Configure networked 'Game Boy Link' (multiplayer) options."
GAMBATTE_GB_COLORIZATION_LABEL "GB Colorization"
GAMBATTE_GB_COLORIZATION_INFO_0 "Enables colorization of Game Boy games. 'Auto' selects the 'best' (most colorful/appropriate) palette. 'GBC' selects game-specific Game Boy Color palette if defined, otherwise 'GBC - Dark Green'. 'SGB' selects game-specific Super Game Boy palette if defined, otherwise 'SGB - 1A', 'Internal' uses 'Internal Palette' core option. 'Custom' loads user-created palette from system directory."
OPTION_VAL_AUTO "Auto"
OPTION_VAL_GBC "GBC"
OPTION_VAL_SGB "SGB"
OPTION_VAL_INTERNAL "Internal"
OPTION_VAL_CUSTOM "Custom"
GAMBATTE_GB_INTERNAL_PALETTE_LABEL "Internal Palette"
GAMBATTE_GB_INTERNAL_PALETTE_INFO_0 "Selects palette used for colorizing Game Boy games when 'GB Colorization' is set to 'Internal', or when 'GB Colorization' is set to 'Auto' and game has no pre-defined SGB/GBC palette. 'GB' palettes mimic the display of original Game Boy hardware. 'GBC' palettes are identical to the built-in presets of the Game Boy Color. 'SGB' palettes are identical to the built-in presets of the Super Game Boy."
OPTION_VAL_GB_DMG "GB - DMG"
OPTION_VAL_GB_POCKET "GB - Pocket"
OPTION_VAL_GB_LIGHT "GB - Light"
OPTION_VAL_GBC_BLUE "GBC - Blue"
OPTION_VAL_GBC_BROWN "GBC - Brown"
OPTION_VAL_GBC_DARK_BLUE "GBC - Dark Blue"
OPTION_VAL_GBC_DARK_BROWN "GBC - Dark Brown"
OPTION_VAL_GBC_DARK_GREEN "GBC - Dark Green"
OPTION_VAL_GBC_GRAYSCALE "GBC - Grayscale"
OPTION_VAL_GBC_GREEN "GBC - Green"
OPTION_VAL_GBC_INVERTED "GBC - Inverted"
OPTION_VAL_GBC_ORANGE "GBC - Orange"
OPTION_VAL_GBC_PASTEL_MIX "GBC - Pastel Mix"
OPTION_VAL_GBC_RED "GBC - Red"
OPTION_VAL_GBC_YELLOW "GBC - Yellow"
OPTION_VAL_SGB_1A "SGB - 1A"
OPTION_VAL_SGB_1B "SGB - 1B"
OPTION_VAL_SGB_1C "SGB - 1C"
OPTION_VAL_SGB_1D "SGB - 1D"
OPTION_VAL_SGB_1E "SGB - 1E"
OPTION_VAL_SGB_1F "SGB - 1F"
OPTION_VAL_SGB_1G "SGB - 1G"
OPTION_VAL_SGB_1H "SGB - 1H"
OPTION_VAL_SGB_2A "SGB - 2A"
OPTION_VAL_SGB_2B "SGB - 2B"
OPTION_VAL_SGB_2C "SGB - 2C"
OPTION_VAL_SGB_2D "SGB - 2D"
OPTION_VAL_SGB_2E "SGB - 2E"
OPTION_VAL_SGB_2F "SGB - 2F"
OPTION_VAL_SGB_2G "SGB - 2G"
OPTION_VAL_SGB_2H "SGB - 2H"
OPTION_VAL_SGB_3A "SGB - 3A"
OPTION_VAL_SGB_3B "SGB - 3B"
OPTION_VAL_SGB_3C "SGB - 3C"
OPTION_VAL_SGB_3D "SGB - 3D"
OPTION_VAL_SGB_3E "SGB - 3E"
OPTION_VAL_SGB_3F "SGB - 3F"
OPTION_VAL_SGB_3G "SGB - 3G"
OPTION_VAL_SGB_3H "SGB - 3H"
OPTION_VAL_SGB_4A "SGB - 4A"
OPTION_VAL_SGB_4B "SGB - 4B"
OPTION_VAL_SGB_4C "SGB - 4C"
OPTION_VAL_SGB_4D "SGB - 4D"
OPTION_VAL_SGB_4E "SGB - 4E"
OPTION_VAL_SGB_4F "SGB - 4F"
OPTION_VAL_SGB_4G "SGB - 4G"
OPTION_VAL_SGB_4H "SGB - 4H"
OPTION_VAL_SPECIAL_1 "Special 1"
OPTION_VAL_SPECIAL_2 "Special 2"
OPTION_VAL_SPECIAL_3 "Special 3"
OPTION_VAL_SPECIAL_4_TI_83_LEGACY "Special 4 (TI-83 Legacy)"
OPTION_VAL_TWB64_PACK_1 "TWB64 - Pack 1"
OPTION_VAL_TWB64_PACK_2 "TWB64 - Pack 2"
GAMBATTE_GB_PALETTE_TWB64_1_LABEL "> TWB64 - Pack 1 Palette"
GAMBATTE_GB_PALETTE_TWB64_1_INFO_0 "Selects internal colorization palette when 'Internal Palette' is set to 'TWB64 - Pack 1'."
OPTION_VAL_TWB64_001_AQOURS_BLUE "TWB64 001 - Aqours Blue"
OPTION_VAL_TWB64_002_ANIME_EXPO_VER "TWB64 002 - Anime Expo Ver."
OPTION_VAL_TWB64_003_SPONGEBOB_YELLOW "TWB64 003 - SpongeBob Yellow"
OPTION_VAL_TWB64_004_PATRICK_STAR_PINK "TWB64 004 - Patrick Star Pink"
OPTION_VAL_TWB64_005_NEON_RED "TWB64 005 - Neon Red"
OPTION_VAL_TWB64_006_NEON_BLUE "TWB64 006 - Neon Blue"
OPTION_VAL_TWB64_007_NEON_YELLOW "TWB64 007 - Neon Yellow"
OPTION_VAL_TWB64_008_NEON_GREEN "TWB64 008 - Neon Green"
OPTION_VAL_TWB64_009_NEON_PINK "TWB64 009 - Neon Pink"
OPTION_VAL_TWB64_010_MARIO_RED "TWB64 010 - Mario Red"
OPTION_VAL_TWB64_011_NICK_ORANGE "TWB64 011 - Nick Orange"
OPTION_VAL_TWB64_012_VIRTUAL_BOY_VER "TWB64 012 - Virtual Boy Ver."
OPTION_VAL_TWB64_013_GOLDEN_WILD "TWB64 013 - Golden Wild"
OPTION_VAL_TWB64_014_BUILDER_YELLOW "TWB64 014 - Builder Yellow"
OPTION_VAL_TWB64_015_CLASSIC_BLURPLE "TWB64 015 - Classic Blurple"
OPTION_VAL_TWB64_016_765_PRODUCTION_VER "TWB64 016 - 765 Production Ver."
OPTION_VAL_TWB64_017_SUPERBALL_IVORY "TWB64 017 - Superball Ivory"
OPTION_VAL_TWB64_018_CRUNCHYROLL_ORANGE "TWB64 018 - Crunchyroll Orange"
OPTION_VAL_TWB64_019_MUSE_PINK "TWB64 019 - Muse Pink"
OPTION_VAL_TWB64_020_NIJIGASAKI_YELLOW "TWB64 020 - Nijigasaki Yellow"
OPTION_VAL_TWB64_021_GAMATE_VER "TWB64 021 - Gamate Ver."
OPTION_VAL_TWB64_022_GREENSCALE_VER "TWB64 022 - Greenscale Ver."
OPTION_VAL_TWB64_023_ODYSSEY_GOLD "TWB64 023 - Odyssey Gold"
OPTION_VAL_TWB64_024_SUPER_SAIYAN_GOD "TWB64 024 - Super Saiyan God"
OPTION_VAL_TWB64_025_SUPER_SAIYAN_BLUE "TWB64 025 - Super Saiyan Blue"
OPTION_VAL_TWB64_026_BIZARRE_PINK "TWB64 026 - Bizarre Pink"
OPTION_VAL_TWB64_027_NINTENDO_SWITCH_LITE_VER "TWB64 027 - Nintendo Switch Lite Ver."
OPTION_VAL_TWB64_028_GAME_COM_VER "TWB64 028 - Game.com Ver."
OPTION_VAL_TWB64_029_SANRIO_PINK "TWB64 029 - Sanrio Pink"
OPTION_VAL_TWB64_030_BANDAI_NAMCO_VER "TWB64 030 - BANDAI NAMCO Ver."
OPTION_VAL_TWB64_031_COSMO_GREEN "TWB64 031 - Cosmo Green"
OPTION_VAL_TWB64_032_WANDA_PINK "TWB64 032 - Wanda Pink"
OPTION_VAL_TWB64_033_LINK_S_AWAKENING_DX_VER "TWB64 033 - Link's Awakening DX Ver."
OPTION_VAL_TWB64_034_TRAVEL_WOOD "TWB64 034 - Travel Wood"
OPTION_VAL_TWB64_035_POKEMON_VER "TWB64 035 - Pokemon Ver."
OPTION_VAL_TWB64_036_GAME_GRUMP_ORANGE "TWB64 036 - Game Grump Orange"
OPTION_VAL_TWB64_037_SCOOBY_DOO_MYSTERY_VER "TWB64 037 - Scooby-Doo Mystery Ver."
OPTION_VAL_TWB64_038_POKEMON_MINI_VER "TWB64 038 - Pokemon mini Ver."
OPTION_VAL_TWB64_039_SUPERVISION_VER "TWB64 039 - Supervision Ver."
OPTION_VAL_TWB64_040_DMG_VER "TWB64 040 - DMG Ver."
OPTION_VAL_TWB64_041_POCKET_VER "TWB64 041 - Pocket Ver."
OPTION_VAL_TWB64_042_LIGHT_VER "TWB64 042 - Light Ver."
OPTION_VAL_TWB64_043_MIRAITOWA_BLUE "TWB64 043 - Miraitowa Blue"
OPTION_VAL_TWB64_044_SOMEITY_PINK "TWB64 044 - Someity Pink"
OPTION_VAL_TWB64_045_PIKACHU_YELLOW "TWB64 045 - Pikachu Yellow"
OPTION_VAL_TWB64_046_EEVEE_BROWN "TWB64 046 - Eevee Brown"
OPTION_VAL_TWB64_047_MICROVISION_VER "TWB64 047 - Microvision Ver."
OPTION_VAL_TWB64_048_TI_83_VER "TWB64 048 - TI-83 Ver."
OPTION_VAL_TWB64_049_AEGIS_CHERRY "TWB64 049 - Aegis Cherry"
OPTION_VAL_TWB64_050_LABO_FAWN "TWB64 050 - Labo Fawn"
OPTION_VAL_TWB64_051_MILLION_LIVE_GOLD "TWB64 051 - MILLION LIVE GOLD!"
OPTION_VAL_TWB64_052_TOKYO_MIDTOWN_VER "TWB64 052 - Tokyo Midtown Ver."
OPTION_VAL_TWB64_053_VMU_VER "TWB64 053 - VMU Ver."
OPTION_VAL_TWB64_054_GAME_MASTER_VER "TWB64 054 - Game Master Ver."
OPTION_VAL_TWB64_055_ANDROID_GREEN "TWB64 055 - Android Green"
OPTION_VAL_TWB64_056_TICKETMASTER_AZURE "TWB64 056 - Ticketmaster Azure"
OPTION_VAL_TWB64_057_GOOGLE_RED "TWB64 057 - Google Red"
OPTION_VAL_TWB64_058_GOOGLE_BLUE "TWB64 058 - Google Blue"
OPTION_VAL_TWB64_059_GOOGLE_YELLOW "TWB64 059 - Google Yellow"
OPTION_VAL_TWB64_060_GOOGLE_GREEN "TWB64 060 - Google Green"
OPTION_VAL_TWB64_061_WONDERSWAN_VER "TWB64 061 - WonderSwan Ver."
OPTION_VAL_TWB64_062_NEO_GEO_POCKET_VER "TWB64 062 - Neo Geo Pocket Ver."
OPTION_VAL_TWB64_063_DEW_GREEN "TWB64 063 - Dew Green"
OPTION_VAL_TWB64_064_COCA_COLA_RED "TWB64 064 - Coca-Cola Red"
OPTION_VAL_TWB64_065_GAMEKING_VER "TWB64 065 - GameKing Ver."
OPTION_VAL_TWB64_066_DO_THE_DEW_VER "TWB64 066 - Do The Dew Ver."
OPTION_VAL_TWB64_067_DIGIVICE_VER "TWB64 067 - Digivice Ver."
OPTION_VAL_TWB64_068_BIKINI_BOTTOM_VER "TWB64 068 - Bikini Bottom Ver."
OPTION_VAL_TWB64_069_BLOSSOM_PINK "TWB64 069 - Blossom Pink"
OPTION_VAL_TWB64_070_BUBBLES_BLUE "TWB64 070 - Bubbles Blue"
OPTION_VAL_TWB64_071_BUTTERCUP_GREEN "TWB64 071 - Buttercup Green"
OPTION_VAL_TWB64_072_NASCAR_VER "TWB64 072 - NASCAR Ver."
OPTION_VAL_TWB64_073_LEMON_LIME_GREEN "TWB64 073 - Lemon-Lime Green"
OPTION_VAL_TWB64_074_MEGA_MAN_V_VER "TWB64 074 - Mega Man V Ver."
OPTION_VAL_TWB64_075_TAMAGOTCHI_VER "TWB64 075 - Tamagotchi Ver."
OPTION_VAL_TWB64_076_PHANTOM_RED "TWB64 076 - Phantom Red"
OPTION_VAL_TWB64_077_HALLOWEEN_VER "TWB64 077 - Halloween Ver."
OPTION_VAL_TWB64_078_CHRISTMAS_VER "TWB64 078 - Christmas Ver."
OPTION_VAL_TWB64_079_CARDCAPTOR_PINK "TWB64 079 - Cardcaptor Pink"
OPTION_VAL_TWB64_080_PRETTY_GUARDIAN_GOLD "TWB64 080 - Pretty Guardian Gold"
OPTION_VAL_TWB64_081_CAMOFLAUGE_VER "TWB64 081 - Camoflauge Ver."
OPTION_VAL_TWB64_082_LEGENDARY_SUPER_SAIYAN "TWB64 082 - Legendary Super Saiyan"
OPTION_VAL_TWB64_083_SUPER_SAIYAN_ROSE "TWB64 083 - Super Saiyan Rose"
OPTION_VAL_TWB64_084_SUPER_SAIYAN "TWB64 084 - Super Saiyan"
OPTION_VAL_TWB64_085_MASTERED_ULTRA_INSTINCT "TWB64 085 - Mastered Ultra Instinct"
OPTION_VAL_TWB64_086_SAINT_SNOW_RED "TWB64 086 - Saint Snow Red"
OPTION_VAL_TWB64_087_YELLOW_BANANA "TWB64 087 - Yellow Banana"
OPTION_VAL_TWB64_088_GREEN_BANANA "TWB64 088 - Green Banana"
OPTION_VAL_TWB64_089_SUPER_SAIYAN_3 "TWB64 089 - Super Saiyan 3"
OPTION_VAL_TWB64_090_SUPER_SAIYAN_BLUE_EVOLVED "TWB64 090 - Super Saiyan Blue Evolved"
OPTION_VAL_TWB64_091_POCKET_TALES_VER "TWB64 091 - Pocket Tales Ver."
OPTION_VAL_TWB64_092_INVESTIGATION_YELLOW "TWB64 092 - Investigation Yellow"
OPTION_VAL_TWB64_093_S_E_E_S_BLUE "TWB64 093 - S.E.E.S. Blue"
OPTION_VAL_TWB64_094_GAME_AWARDS_CYAN "TWB64 094 - Game Awards Cyan"
OPTION_VAL_TWB64_095_HOKAGE_ORANGE "TWB64 095 - Hokage Orange"
OPTION_VAL_TWB64_096_STRAW_HAT_RED "TWB64 096 - Straw Hat Red"
OPTION_VAL_TWB64_097_SWORD_ART_CYAN "TWB64 097 - Sword Art Cyan"
OPTION_VAL_TWB64_098_DEKU_ALPHA_EMERALD "TWB64 098 - Deku Alpha Emerald"
OPTION_VAL_TWB64_099_BLUE_STRIPES_VER "TWB64 099 - Blue Stripes Ver."
OPTION_VAL_TWB64_100_STONE_ORANGE "TWB64 100 - Stone Orange"
GAMBATTE_GB_PALETTE_TWB64_2_LABEL "> TWB64 - Pack 2 Palette"
GAMBATTE_GB_PALETTE_TWB64_2_INFO_0 "Selects internal colorization palette when 'Internal Palette' is set to 'TWB64 - Pack 2'."
OPTION_VAL_TWB64_101_765PRO_PINK "TWB64 101 - 765PRO Pink"
OPTION_VAL_TWB64_102_CINDERELLA_BLUE "TWB64 102 - CINDERELLA Blue"
OPTION_VAL_TWB64_103_MILLION_YELLOW "TWB64 103 - MILLION Yellow!"
OPTION_VAL_TWB64_104_SIDEM_GREEN "TWB64 104 - SideM Green"
OPTION_VAL_TWB64_105_SHINY_SKY_BLUE "TWB64 105 - SHINY Sky Blue"
OPTION_VAL_TWB64_106_ANGRY_VOLCANO_VER "TWB64 106 - Angry Volcano Ver."
OPTION_VAL_TWB64_107_YO_KAI_PINK "TWB64 107 - Yo-kai Pink"
OPTION_VAL_TWB64_108_YO_KAI_GREEN "TWB64 108 - Yo-kai Green"
OPTION_VAL_TWB64_109_YO_KAI_BLUE "TWB64 109 - Yo-kai Blue"
OPTION_VAL_TWB64_110_YO_KAI_PURPLE "TWB64 110 - Yo-kai Purple"
OPTION_VAL_TWB64_111_AQUATIC_IRO "TWB64 111 - Aquatic Iro"
OPTION_VAL_TWB64_112_TEA_MIDORI "TWB64 112 - Tea Midori"
OPTION_VAL_TWB64_113_SAKURA_PINK "TWB64 113 - Sakura Pink"
OPTION_VAL_TWB64_114_WISTERIA_MURASAKI "TWB64 114 - Wisteria Murasaki"
OPTION_VAL_TWB64_115_ONI_AKA "TWB64 115 - Oni Aka"
OPTION_VAL_TWB64_116_GOLDEN_KIIRO "TWB64 116 - Golden Kiiro"
OPTION_VAL_TWB64_117_SILVER_SHIRO "TWB64 117 - Silver Shiro"
OPTION_VAL_TWB64_118_FRUITY_ORANGE "TWB64 118 - Fruity Orange"
OPTION_VAL_TWB64_119_AKB48_PINK "TWB64 119 - AKB48 Pink"
OPTION_VAL_TWB64_120_MIKU_BLUE "TWB64 120 - Miku Blue"
OPTION_VAL_TWB64_121_FAIRY_TAIL_RED "TWB64 121 - Fairy Tail Red"
OPTION_VAL_TWB64_122_SURVEY_CORPS_BROWN "TWB64 122 - Survey Corps Brown"
OPTION_VAL_TWB64_123_ISLAND_GREEN "TWB64 123 - Island Green"
OPTION_VAL_TWB64_124_MANIA_PLUS_GREEN "TWB64 124 - Mania Plus Green"
OPTION_VAL_TWB64_125_NINJA_TURTLE_GREEN "TWB64 125 - Ninja Turtle Green"
OPTION_VAL_TWB64_126_SLIME_BLUE "TWB64 126 - Slime Blue"
OPTION_VAL_TWB64_127_LIME_MIDORI "TWB64 127 - Lime Midori"
OPTION_VAL_TWB64_128_GHOSTLY_AOI "TWB64 128 - Ghostly Aoi"
OPTION_VAL_TWB64_129_RETRO_BOGEDA "TWB64 129 - Retro Bogeda"
OPTION_VAL_TWB64_130_ROYAL_BLUE "TWB64 130 - Royal Blue"
OPTION_VAL_TWB64_131_NEON_PURPLE "TWB64 131 - Neon Purple"
OPTION_VAL_TWB64_132_NEON_ORANGE "TWB64 132 - Neon Orange"
OPTION_VAL_TWB64_133_MOONLIGHT_VISION "TWB64 133 - Moonlight Vision"
OPTION_VAL_TWB64_134_TOKYO_RED "TWB64 134 - Tokyo Red"
OPTION_VAL_TWB64_135_PARIS_GOLD "TWB64 135 - Paris Gold"
OPTION_VAL_TWB64_136_BEIJING_BLUE "TWB64 136 - Beijing Blue"
OPTION_VAL_TWB64_137_PAC_MAN_YELLOW "TWB64 137 - Pac-Man Yellow"
OPTION_VAL_TWB64_138_IRISH_GREEN "TWB64 138 - Irish Green"
OPTION_VAL_TWB64_139_KAKAROT_ORANGE "TWB64 139 - Kakarot Orange"
OPTION_VAL_TWB64_140_DRAGON_BALL_ORANGE "TWB64 140 - Dragon Ball Orange"
OPTION_VAL_TWB64_141_CHRISTMAS_GOLD "TWB64 141 - Christmas Gold"
OPTION_VAL_TWB64_142_PEPSI_BLUE "TWB64 142 - Pepsi Blue"
OPTION_VAL_TWB64_143_BUBBLUN_GREEN "TWB64 143 - Bubblun Green"
OPTION_VAL_TWB64_144_BOBBLUN_BLUE "TWB64 144 - Bobblun Blue"
OPTION_VAL_TWB64_145_BAJA_BLAST_STORM "TWB64 145 - Baja Blast Storm"
OPTION_VAL_TWB64_146_OLYMPIC_GOLD "TWB64 146 - Olympic Gold"
OPTION_VAL_TWB64_147_VALUE_ORANGE "TWB64 147 - Value Orange"
OPTION_VAL_TWB64_148_LIELLA_PURPLE "TWB64 148 - Liella Purple!"
OPTION_VAL_TWB64_149_OLYMPIC_SILVER "TWB64 149 - Olympic Silver"
OPTION_VAL_TWB64_150_OLYMPIC_BRONZE "TWB64 150 - Olympic Bronze"
OPTION_VAL_TWB64_151_ANA_SKY_BLUE "TWB64 151 - ANA Sky Blue"
OPTION_VAL_TWB64_152_NIJIGASAKI_ORANGE "TWB64 152 - Nijigasaki Orange"
OPTION_VAL_TWB64_153_HOLOBLUE "TWB64 153 - HoloBlue"
OPTION_VAL_TWB64_154_WRESTLING_RED "TWB64 154 - Wrestling Red"
OPTION_VAL_TWB64_155_YOSHI_EGG_GREEN "TWB64 155 - Yoshi Egg Green"
OPTION_VAL_TWB64_156_POKEDEX_RED "TWB64 156 - Pokedex Red"
OPTION_VAL_TWB64_157_DISNEY_DREAM_BLUE "TWB64 157 - Disney Dream Blue"
OPTION_VAL_TWB64_158_XBOX_GREEN "TWB64 158 - Xbox Green"
OPTION_VAL_TWB64_159_SONIC_MEGA_BLUE "TWB64 159 - Sonic Mega Blue"
OPTION_VAL_TWB64_160_G4_ORANGE "TWB64 160 - G4 Orange"
OPTION_VAL_TWB64_161_SCARLETT_GREEN "TWB64 161 - Scarlett Green"
OPTION_VAL_TWB64_162_GLITCHY_BLUE "TWB64 162 - Glitchy Blue"
OPTION_VAL_TWB64_163_CLASSIC_LCD "TWB64 163 - Classic LCD"
OPTION_VAL_TWB64_164_3DS_VIRTUAL_CONSOLE_VER "TWB64 164 - 3DS Virtual Console Ver."
OPTION_VAL_TWB64_165_POCKETSTATION_VER "TWB64 165 - PocketStation Ver."
OPTION_VAL_TWB64_166_GAME_AND_GOLD "TWB64 166 - Game and Gold"
OPTION_VAL_TWB64_167_SMURFY_BLUE "TWB64 167 - Smurfy Blue"
OPTION_VAL_TWB64_168_SWAMPY_OGRE_GREEN "TWB64 168 - Swampy Ogre Green"
OPTION_VAL_TWB64_169_SAILOR_SPINACH_GREEN "TWB64 169 - Sailor Spinach Green"
OPTION_VAL_TWB64_170_SHENRON_GREEN "TWB64 170 - Shenron Green"
OPTION_VAL_TWB64_171_BERSERK_BLOOD "TWB64 171 - Berserk Blood"
OPTION_VAL_TWB64_172_SUPER_STAR_PINK "TWB64 172 - Super Star Pink"
OPTION_VAL_TWB64_173_GAMEBUINO_CLASSIC_VER "TWB64 173 - Gamebuino Classic Ver."
OPTION_VAL_TWB64_174_BARBIE_PINK "TWB64 174 - Barbie Pink"
OPTION_VAL_TWB64_175_STAR_COMMAND_GREEN "TWB64 175 - Star Command Green"
OPTION_VAL_TWB64_176_NOKIA_3310_VER "TWB64 176 - Nokia 3310 Ver."
OPTION_VAL_TWB64_177_CLOVER_GREEN "TWB64 177 - Clover Green"
OPTION_VAL_TWB64_178_CRASH_ORANGE "TWB64 178 - Crash Orange"
OPTION_VAL_TWB64_179_FAMICOM_DISK_YELLOW "TWB64 179 - Famicom Disk Yellow"
OPTION_VAL_TWB64_180_TEAM_ROCKET_RED "TWB64 180 - Team Rocket Red"
OPTION_VAL_TWB64_181_SEIKO_TIMER_YELLOW "TWB64 181 - SEIKO Timer Yellow"
OPTION_VAL_TWB64_182_PINK109 "TWB64 182 - PINK109"
OPTION_VAL_TWB64_183_DORAEMON_BLUE "TWB64 183 - Doraemon Blue"
OPTION_VAL_TWB64_184_FURY_BLUE "TWB64 184 - Fury Blue"
OPTION_VAL_TWB64_185_ROCKSTAR_ORANGE "TWB64 185 - Rockstar Orange"
OPTION_VAL_TWB64_186_PUYO_PUYO_GREEN "TWB64 186 - Puyo Puyo Green"
OPTION_VAL_TWB64_187_SUSAN_G_PINK "TWB64 187 - Susan G. Pink"
OPTION_VAL_TWB64_188_PIZZA_HUT_RED "TWB64 188 - Pizza Hut Red"
OPTION_VAL_TWB64_189_PLUMBOB_GREEN "TWB64 189 - Plumbob Green"
OPTION_VAL_TWB64_190_GRAND_IVORY "TWB64 190 - Grand Ivory"
OPTION_VAL_TWB64_191_DEMON_S_GOLD "TWB64 191 - Demon's Gold"
OPTION_VAL_TWB64_192_SEGA_TOKYO_BLUE "TWB64 192 - SEGA Tokyo Blue"
OPTION_VAL_TWB64_193_CHAMPION_BLUE "TWB64 193 - Champion Blue"
OPTION_VAL_TWB64_194_DK_BARREL_BROWN "TWB64 194 - DK Barrel Brown"
OPTION_VAL_TWB64_195_EVANGELION_GREEN "TWB64 195 - Evangelion Green"
OPTION_VAL_TWB64_196_EQUESTRIAN_PURPLE "TWB64 196 - Equestrian Purple"
OPTION_VAL_TWB64_197_AUTOBOT_RED "TWB64 197 - Autobot Red"
OPTION_VAL_TWB64_198_NICONICO_SEA_GREEN "TWB64 198 - Niconico Sea Green"
OPTION_VAL_TWB64_199_DURACELL_COPPER "TWB64 199 - Duracell Copper"
OPTION_VAL_TWB64_200_TOKYO_SKYTREE_CLOUDY_BLUE "TWB64 200 - TOKYO SKYTREE CLOUDY BLUE"
GAMBATTE_GBC_COLOR_CORRECTION_LABEL "Color Correction"
GAMBATTE_GBC_COLOR_CORRECTION_INFO_0 "Adjusts output colors to match the display of real Game Boy Color hardware. 'GBC Only' ensures that correction will only be applied when playing Game Boy Color games, or when using a Game Boy Color palette to colorize a Game Boy game. 'Always' applies color correction to all content, and will produce unexpected/suboptimal results when using 'GB' or 'SGB' internal color palettes."
OPTION_VAL_GBC_ONLY "GBC Only"
OPTION_VAL_ALWAYS "Always"
GAMBATTE_GBC_COLOR_CORRECTION_MODE_LABEL "Color Correction Mode"
GAMBATTE_GBC_COLOR_CORRECTION_MODE_INFO_0 "Specifies method used when performing color correction. 'Accurate' produces output almost indistinguishable from a real Game Boy Color LCD panel. 'Fast' merely darkens colors and reduces saturation, and may be used on low-end hardware if the 'Accurate' method is too slow."
OPTION_VAL_ACCURATE "Accurate"
OPTION_VAL_FAST "Fast"
GAMBATTE_GBC_FRONTLIGHT_POSITION_LABEL "Color Correction - Frontlight Position"
GAMBATTE_GBC_FRONTLIGHT_POSITION_INFO_0 "Simulates the physical response of the Game Boy Color LCD panel when illuminated from different angles. 'Central' represents standard color reproduction. 'Above Screen' increases brightness. 'Below Screen' reduces brightness. This setting only applies when 'Color Correction Mode' is set to 'Accurate'."
OPTION_VAL_CENTRAL "Central"
OPTION_VAL_ABOVE_SCREEN "Above Screen"
OPTION_VAL_BELOW_SCREEN "Below Screen"
GAMBATTE_DARK_FILTER_LEVEL_LABEL "Dark Filter Level (percent)"
GAMBATTE_DARK_FILTER_LEVEL_INFO_0 "Enable luminosity-based brightness reduction. May be used to avoid glare/eye strain when playing games with white backgrounds, which are intended for display on a non-backlit Game Boy Color and can therefore appear uncomfortably bright when viewed on a modern backlit screen."
GAMBATTE_GB_HWMODE_LABEL "Emulated Hardware (restart)"
GAMBATTE_GB_HWMODE_INFO_0 "Specify which type of hardware to emulate. 'Auto' is recommended. Selecting 'GBA' unlocks extra features in certain 'GBA enhanced' Game Boy Color games (Shantae, Wendy - Every Witch Way, Legend of Zelda: Oracle of Seasons/Ages...)."
OPTION_VAL_GB "GB"
OPTION_VAL_GBA "GBA"
GAMBATTE_GB_BOOTLOADER_LABEL "Use Official Bootloader (restart)"
GAMBATTE_GB_BOOTLOADER_INFO_0 "Enable support for official Game Boy and Game Boy Color bootloaders, with corresponding start-up logo animations."
GAMBATTE_MIX_FRAMES_LABEL "Interframe Blending"
GAMBATTE_MIX_FRAMES_INFO_0 "Simulates LCD ghosting effects. 'Simple' performs a 50:50 mix of the current and previous frames. 'LCD Ghosting' mimics natural LCD response times by combining multiple buffered frames. 'Simple' blending is required when playing games that rely on LCD ghosting for transparency effects (Wave Race, Ballistic, Chikyuu Kaihou Gun ZAS...)."
OPTION_VAL_MIX "Simple"
OPTION_VAL_LCD_GHOSTING "LCD Ghosting (Accurate)"
OPTION_VAL_LCD_GHOSTING_FAST "LCD Ghosting (Fast)"
GAMBATTE_UP_DOWN_ALLOWED_LABEL "Allow Opposing Directions"
GAMBATTE_UP_DOWN_ALLOWED_INFO_0 "Enabling this will allow pressing / quickly alternating / holding both left and right (or up and down) directions at the same time. This may cause movement-based glitches."
GAMBATTE_TURBO_PERIOD_LABEL "Turbo Button Period"
GAMBATTE_TURBO_PERIOD_INFO_0 "Specify the repeat interval (in frames) when holding down the Turbo A/B buttons."
GAMBATTE_RUMBLE_LEVEL_LABEL "Gamepad Rumble Strength"
GAMBATTE_RUMBLE_LEVEL_INFO_0 "Enables haptic feedback effects for supported games (Pokemon Pinball, Perfect Dark...)."
GAMBATTE_SHOW_GB_LINK_SETTINGS_LABEL "Show Game Boy Link Settings"
GAMBATTE_SHOW_GB_LINK_SETTINGS_INFO_0 "Enable configuration of networked 'Game Boy Link' (multiplayer) options. NOTE: Quick Menu may need to be toggled for this setting to take effect."
GAMBATTE_GB_LINK_MODE_LABEL "Game Boy Link Mode"
GAMBATTE_GB_LINK_MODE_LABEL_CAT "Link Mode"
GAMBATTE_GB_LINK_MODE_INFO_0 "When enabling networked 'Game Boy Link' functionality, specify whether current instance should run as a server or client."
OPTION_VAL_NOT_CONNECTED "Not Connected"
OPTION_VAL_NETWORK_SERVER "Network Server"
OPTION_VAL_NETWORK_CLIENT "Network Client"
GAMBATTE_GB_LINK_NETWORK_PORT_LABEL "Network Link Port"
GAMBATTE_GB_LINK_NETWORK_PORT_LABEL_CAT "Port"
GAMBATTE_GB_LINK_NETWORK_PORT_INFO_0 "Specify port used for 'Game Boy Link' network communication."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_LABEL "Network Link Server Address Pt. 01: x__.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_LABEL_CAT "Server Address Pt. 01: x__.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_INFO_0 "1st digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_INFO_1 "1st digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_LABEL "Network Link Server Address Pt. 02: _x_.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_LABEL_CAT "Server Address Pt. 02: _x_.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_INFO_0 "2nd digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_INFO_1 "2nd digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_LABEL "Network Link Server Address Pt. 03: __x.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_LABEL_CAT "Server Address Pt. 03: __x.___.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_INFO_0 "3rd digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_INFO_1 "3rd digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_LABEL "Network Link Server Address Pt. 04: ___.x__.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_LABEL_CAT "Server Address Pt. 04: ___.x__.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_INFO_0 "4th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_INFO_1 "4th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_LABEL "Network Link Server Address Pt. 05: ___._x_.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_LABEL_CAT "Server Address Pt. 05: ___._x_.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_INFO_0 "5th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_INFO_1 "5th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_LABEL "Network Link Server Address Pt. 06: ___.__x.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_LABEL_CAT "Server Address Pt. 06: ___.__x.___.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_INFO_0 "6th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_INFO_1 "6th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_LABEL "Network Link Server Address Pt. 07: ___.___.x__.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_LABEL_CAT "Server Address Pt. 07: ___.___.x__.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_INFO_0 "7th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_INFO_1 "7th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_LABEL "Network Link Server Address Pt. 08: ___.___._x_.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_LABEL_CAT "Server Address Pt. 08: ___.___._x_.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_INFO_0 "8th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_INFO_1 "8th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_LABEL "Network Link Server Address Pt. 09: ___.___.__x.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_LABEL_CAT "Server Address Pt. 09: ___.___.__x.___"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_INFO_0 "9th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_INFO_1 "9th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_LABEL "Network Link Server Address Pt. 10: ___.___.___.x__"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_LABEL_CAT "Server Address Pt. 10: ___.___.___.x__"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_INFO_0 "10th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_INFO_1 "10th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_LABEL "Network Link Server Address Pt. 11: ___.___.___._x_"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_LABEL_CAT "Server Address Pt. 11: ___.___.___._x_"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_INFO_0 "11th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_INFO_1 "11th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_LABEL "Network Link Server Address Pt. 12: ___.___.___.__x"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_LABEL_CAT "Server Address Pt. 12: ___.___.___.__x"
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_INFO_0 "12th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'."
GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_INFO_1 "12th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."

View File

@ -1,361 +0,0 @@
{
"CATEGORY_GB_LINK_LABEL": "Game Boy Link",
"CATEGORY_GB_LINK_INFO_0": "Configure networked 'Game Boy Link' (multiplayer) options.",
"GAMBATTE_GB_COLORIZATION_LABEL": "GB Colorization",
"GAMBATTE_GB_COLORIZATION_INFO_0": "Enables colorization of Game Boy games. 'Auto' selects the 'best' (most colorful/appropriate) palette. 'GBC' selects game-specific Game Boy Color palette if defined, otherwise 'GBC - Dark Green'. 'SGB' selects game-specific Super Game Boy palette if defined, otherwise 'SGB - 1A', 'Internal' uses 'Internal Palette' core option. 'Custom' loads user-created palette from system directory.",
"OPTION_VAL_AUTO": "Auto",
"OPTION_VAL_GBC": "GBC",
"OPTION_VAL_SGB": "SGB",
"OPTION_VAL_INTERNAL": "Internal",
"OPTION_VAL_CUSTOM": "Custom",
"GAMBATTE_GB_INTERNAL_PALETTE_LABEL": "Internal Palette",
"GAMBATTE_GB_INTERNAL_PALETTE_INFO_0": "Selects palette used for colorizing Game Boy games when 'GB Colorization' is set to 'Internal', or when 'GB Colorization' is set to 'Auto' and game has no pre-defined SGB/GBC palette. 'GB' palettes mimic the display of original Game Boy hardware. 'GBC' palettes are identical to the built-in presets of the Game Boy Color. 'SGB' palettes are identical to the built-in presets of the Super Game Boy.",
"OPTION_VAL_GB_DMG": "GB - DMG",
"OPTION_VAL_GB_POCKET": "GB - Pocket",
"OPTION_VAL_GB_LIGHT": "GB - Light",
"OPTION_VAL_GBC_BLUE": "GBC - Blue",
"OPTION_VAL_GBC_BROWN": "GBC - Brown",
"OPTION_VAL_GBC_DARK_BLUE": "GBC - Dark Blue",
"OPTION_VAL_GBC_DARK_BROWN": "GBC - Dark Brown",
"OPTION_VAL_GBC_DARK_GREEN": "GBC - Dark Green",
"OPTION_VAL_GBC_GRAYSCALE": "GBC - Grayscale",
"OPTION_VAL_GBC_GREEN": "GBC - Green",
"OPTION_VAL_GBC_INVERTED": "GBC - Inverted",
"OPTION_VAL_GBC_ORANGE": "GBC - Orange",
"OPTION_VAL_GBC_PASTEL_MIX": "GBC - Pastel Mix",
"OPTION_VAL_GBC_RED": "GBC - Red",
"OPTION_VAL_GBC_YELLOW": "GBC - Yellow",
"OPTION_VAL_SGB_1A": "SGB - 1A",
"OPTION_VAL_SGB_1B": "SGB - 1B",
"OPTION_VAL_SGB_1C": "SGB - 1C",
"OPTION_VAL_SGB_1D": "SGB - 1D",
"OPTION_VAL_SGB_1E": "SGB - 1E",
"OPTION_VAL_SGB_1F": "SGB - 1F",
"OPTION_VAL_SGB_1G": "SGB - 1G",
"OPTION_VAL_SGB_1H": "SGB - 1H",
"OPTION_VAL_SGB_2A": "SGB - 2A",
"OPTION_VAL_SGB_2B": "SGB - 2B",
"OPTION_VAL_SGB_2C": "SGB - 2C",
"OPTION_VAL_SGB_2D": "SGB - 2D",
"OPTION_VAL_SGB_2E": "SGB - 2E",
"OPTION_VAL_SGB_2F": "SGB - 2F",
"OPTION_VAL_SGB_2G": "SGB - 2G",
"OPTION_VAL_SGB_2H": "SGB - 2H",
"OPTION_VAL_SGB_3A": "SGB - 3A",
"OPTION_VAL_SGB_3B": "SGB - 3B",
"OPTION_VAL_SGB_3C": "SGB - 3C",
"OPTION_VAL_SGB_3D": "SGB - 3D",
"OPTION_VAL_SGB_3E": "SGB - 3E",
"OPTION_VAL_SGB_3F": "SGB - 3F",
"OPTION_VAL_SGB_3G": "SGB - 3G",
"OPTION_VAL_SGB_3H": "SGB - 3H",
"OPTION_VAL_SGB_4A": "SGB - 4A",
"OPTION_VAL_SGB_4B": "SGB - 4B",
"OPTION_VAL_SGB_4C": "SGB - 4C",
"OPTION_VAL_SGB_4D": "SGB - 4D",
"OPTION_VAL_SGB_4E": "SGB - 4E",
"OPTION_VAL_SGB_4F": "SGB - 4F",
"OPTION_VAL_SGB_4G": "SGB - 4G",
"OPTION_VAL_SGB_4H": "SGB - 4H",
"OPTION_VAL_SPECIAL_1": "Special 1",
"OPTION_VAL_SPECIAL_2": "Special 2",
"OPTION_VAL_SPECIAL_3": "Special 3",
"OPTION_VAL_SPECIAL_4_TI_83_LEGACY": "Special 4 (TI-83 Legacy)",
"OPTION_VAL_TWB64_PACK_1": "TWB64 - Pack 1",
"OPTION_VAL_TWB64_PACK_2": "TWB64 - Pack 2",
"GAMBATTE_GB_PALETTE_TWB64_1_LABEL": "> TWB64 - Pack 1 Palette",
"GAMBATTE_GB_PALETTE_TWB64_1_INFO_0": "Selects internal colorization palette when 'Internal Palette' is set to 'TWB64 - Pack 1'.",
"OPTION_VAL_TWB64_001_AQOURS_BLUE": "TWB64 001 - Aqours Blue",
"OPTION_VAL_TWB64_002_ANIME_EXPO_VER": "TWB64 002 - Anime Expo Ver.",
"OPTION_VAL_TWB64_003_SPONGEBOB_YELLOW": "TWB64 003 - SpongeBob Yellow",
"OPTION_VAL_TWB64_004_PATRICK_STAR_PINK": "TWB64 004 - Patrick Star Pink",
"OPTION_VAL_TWB64_005_NEON_RED": "TWB64 005 - Neon Red",
"OPTION_VAL_TWB64_006_NEON_BLUE": "TWB64 006 - Neon Blue",
"OPTION_VAL_TWB64_007_NEON_YELLOW": "TWB64 007 - Neon Yellow",
"OPTION_VAL_TWB64_008_NEON_GREEN": "TWB64 008 - Neon Green",
"OPTION_VAL_TWB64_009_NEON_PINK": "TWB64 009 - Neon Pink",
"OPTION_VAL_TWB64_010_MARIO_RED": "TWB64 010 - Mario Red",
"OPTION_VAL_TWB64_011_NICK_ORANGE": "TWB64 011 - Nick Orange",
"OPTION_VAL_TWB64_012_VIRTUAL_BOY_VER": "TWB64 012 - Virtual Boy Ver.",
"OPTION_VAL_TWB64_013_GOLDEN_WILD": "TWB64 013 - Golden Wild",
"OPTION_VAL_TWB64_014_BUILDER_YELLOW": "TWB64 014 - Builder Yellow",
"OPTION_VAL_TWB64_015_CLASSIC_BLURPLE": "TWB64 015 - Classic Blurple",
"OPTION_VAL_TWB64_016_765_PRODUCTION_VER": "TWB64 016 - 765 Production Ver.",
"OPTION_VAL_TWB64_017_SUPERBALL_IVORY": "TWB64 017 - Superball Ivory",
"OPTION_VAL_TWB64_018_CRUNCHYROLL_ORANGE": "TWB64 018 - Crunchyroll Orange",
"OPTION_VAL_TWB64_019_MUSE_PINK": "TWB64 019 - Muse Pink",
"OPTION_VAL_TWB64_020_NIJIGASAKI_YELLOW": "TWB64 020 - Nijigasaki Yellow",
"OPTION_VAL_TWB64_021_GAMATE_VER": "TWB64 021 - Gamate Ver.",
"OPTION_VAL_TWB64_022_GREENSCALE_VER": "TWB64 022 - Greenscale Ver.",
"OPTION_VAL_TWB64_023_ODYSSEY_GOLD": "TWB64 023 - Odyssey Gold",
"OPTION_VAL_TWB64_024_SUPER_SAIYAN_GOD": "TWB64 024 - Super Saiyan God",
"OPTION_VAL_TWB64_025_SUPER_SAIYAN_BLUE": "TWB64 025 - Super Saiyan Blue",
"OPTION_VAL_TWB64_026_BIZARRE_PINK": "TWB64 026 - Bizarre Pink",
"OPTION_VAL_TWB64_027_NINTENDO_SWITCH_LITE_VER": "TWB64 027 - Nintendo Switch Lite Ver.",
"OPTION_VAL_TWB64_028_GAME_COM_VER": "TWB64 028 - Game.com Ver.",
"OPTION_VAL_TWB64_029_SANRIO_PINK": "TWB64 029 - Sanrio Pink",
"OPTION_VAL_TWB64_030_BANDAI_NAMCO_VER": "TWB64 030 - BANDAI NAMCO Ver.",
"OPTION_VAL_TWB64_031_COSMO_GREEN": "TWB64 031 - Cosmo Green",
"OPTION_VAL_TWB64_032_WANDA_PINK": "TWB64 032 - Wanda Pink",
"OPTION_VAL_TWB64_033_LINK_S_AWAKENING_DX_VER": "TWB64 033 - Link's Awakening DX Ver.",
"OPTION_VAL_TWB64_034_TRAVEL_WOOD": "TWB64 034 - Travel Wood",
"OPTION_VAL_TWB64_035_POKEMON_VER": "TWB64 035 - Pokemon Ver.",
"OPTION_VAL_TWB64_036_GAME_GRUMP_ORANGE": "TWB64 036 - Game Grump Orange",
"OPTION_VAL_TWB64_037_SCOOBY_DOO_MYSTERY_VER": "TWB64 037 - Scooby-Doo Mystery Ver.",
"OPTION_VAL_TWB64_038_POKEMON_MINI_VER": "TWB64 038 - Pokemon mini Ver.",
"OPTION_VAL_TWB64_039_SUPERVISION_VER": "TWB64 039 - Supervision Ver.",
"OPTION_VAL_TWB64_040_DMG_VER": "TWB64 040 - DMG Ver.",
"OPTION_VAL_TWB64_041_POCKET_VER": "TWB64 041 - Pocket Ver.",
"OPTION_VAL_TWB64_042_LIGHT_VER": "TWB64 042 - Light Ver.",
"OPTION_VAL_TWB64_043_MIRAITOWA_BLUE": "TWB64 043 - Miraitowa Blue",
"OPTION_VAL_TWB64_044_SOMEITY_PINK": "TWB64 044 - Someity Pink",
"OPTION_VAL_TWB64_045_PIKACHU_YELLOW": "TWB64 045 - Pikachu Yellow",
"OPTION_VAL_TWB64_046_EEVEE_BROWN": "TWB64 046 - Eevee Brown",
"OPTION_VAL_TWB64_047_MICROVISION_VER": "TWB64 047 - Microvision Ver.",
"OPTION_VAL_TWB64_048_TI_83_VER": "TWB64 048 - TI-83 Ver.",
"OPTION_VAL_TWB64_049_AEGIS_CHERRY": "TWB64 049 - Aegis Cherry",
"OPTION_VAL_TWB64_050_LABO_FAWN": "TWB64 050 - Labo Fawn",
"OPTION_VAL_TWB64_051_MILLION_LIVE_GOLD": "TWB64 051 - MILLION LIVE GOLD!",
"OPTION_VAL_TWB64_052_TOKYO_MIDTOWN_VER": "TWB64 052 - Tokyo Midtown Ver.",
"OPTION_VAL_TWB64_053_VMU_VER": "TWB64 053 - VMU Ver.",
"OPTION_VAL_TWB64_054_GAME_MASTER_VER": "TWB64 054 - Game Master Ver.",
"OPTION_VAL_TWB64_055_ANDROID_GREEN": "TWB64 055 - Android Green",
"OPTION_VAL_TWB64_056_TICKETMASTER_AZURE": "TWB64 056 - Ticketmaster Azure",
"OPTION_VAL_TWB64_057_GOOGLE_RED": "TWB64 057 - Google Red",
"OPTION_VAL_TWB64_058_GOOGLE_BLUE": "TWB64 058 - Google Blue",
"OPTION_VAL_TWB64_059_GOOGLE_YELLOW": "TWB64 059 - Google Yellow",
"OPTION_VAL_TWB64_060_GOOGLE_GREEN": "TWB64 060 - Google Green",
"OPTION_VAL_TWB64_061_WONDERSWAN_VER": "TWB64 061 - WonderSwan Ver.",
"OPTION_VAL_TWB64_062_NEO_GEO_POCKET_VER": "TWB64 062 - Neo Geo Pocket Ver.",
"OPTION_VAL_TWB64_063_DEW_GREEN": "TWB64 063 - Dew Green",
"OPTION_VAL_TWB64_064_COCA_COLA_RED": "TWB64 064 - Coca-Cola Red",
"OPTION_VAL_TWB64_065_GAMEKING_VER": "TWB64 065 - GameKing Ver.",
"OPTION_VAL_TWB64_066_DO_THE_DEW_VER": "TWB64 066 - Do The Dew Ver.",
"OPTION_VAL_TWB64_067_DIGIVICE_VER": "TWB64 067 - Digivice Ver.",
"OPTION_VAL_TWB64_068_BIKINI_BOTTOM_VER": "TWB64 068 - Bikini Bottom Ver.",
"OPTION_VAL_TWB64_069_BLOSSOM_PINK": "TWB64 069 - Blossom Pink",
"OPTION_VAL_TWB64_070_BUBBLES_BLUE": "TWB64 070 - Bubbles Blue",
"OPTION_VAL_TWB64_071_BUTTERCUP_GREEN": "TWB64 071 - Buttercup Green",
"OPTION_VAL_TWB64_072_NASCAR_VER": "TWB64 072 - NASCAR Ver.",
"OPTION_VAL_TWB64_073_LEMON_LIME_GREEN": "TWB64 073 - Lemon-Lime Green",
"OPTION_VAL_TWB64_074_MEGA_MAN_V_VER": "TWB64 074 - Mega Man V Ver.",
"OPTION_VAL_TWB64_075_TAMAGOTCHI_VER": "TWB64 075 - Tamagotchi Ver.",
"OPTION_VAL_TWB64_076_PHANTOM_RED": "TWB64 076 - Phantom Red",
"OPTION_VAL_TWB64_077_HALLOWEEN_VER": "TWB64 077 - Halloween Ver.",
"OPTION_VAL_TWB64_078_CHRISTMAS_VER": "TWB64 078 - Christmas Ver.",
"OPTION_VAL_TWB64_079_CARDCAPTOR_PINK": "TWB64 079 - Cardcaptor Pink",
"OPTION_VAL_TWB64_080_PRETTY_GUARDIAN_GOLD": "TWB64 080 - Pretty Guardian Gold",
"OPTION_VAL_TWB64_081_CAMOFLAUGE_VER": "TWB64 081 - Camoflauge Ver.",
"OPTION_VAL_TWB64_082_LEGENDARY_SUPER_SAIYAN": "TWB64 082 - Legendary Super Saiyan",
"OPTION_VAL_TWB64_083_SUPER_SAIYAN_ROSE": "TWB64 083 - Super Saiyan Rose",
"OPTION_VAL_TWB64_084_SUPER_SAIYAN": "TWB64 084 - Super Saiyan",
"OPTION_VAL_TWB64_085_MASTERED_ULTRA_INSTINCT": "TWB64 085 - Mastered Ultra Instinct",
"OPTION_VAL_TWB64_086_SAINT_SNOW_RED": "TWB64 086 - Saint Snow Red",
"OPTION_VAL_TWB64_087_YELLOW_BANANA": "TWB64 087 - Yellow Banana",
"OPTION_VAL_TWB64_088_GREEN_BANANA": "TWB64 088 - Green Banana",
"OPTION_VAL_TWB64_089_SUPER_SAIYAN_3": "TWB64 089 - Super Saiyan 3",
"OPTION_VAL_TWB64_090_SUPER_SAIYAN_BLUE_EVOLVED": "TWB64 090 - Super Saiyan Blue Evolved",
"OPTION_VAL_TWB64_091_POCKET_TALES_VER": "TWB64 091 - Pocket Tales Ver.",
"OPTION_VAL_TWB64_092_INVESTIGATION_YELLOW": "TWB64 092 - Investigation Yellow",
"OPTION_VAL_TWB64_093_S_E_E_S_BLUE": "TWB64 093 - S.E.E.S. Blue",
"OPTION_VAL_TWB64_094_GAME_AWARDS_CYAN": "TWB64 094 - Game Awards Cyan",
"OPTION_VAL_TWB64_095_HOKAGE_ORANGE": "TWB64 095 - Hokage Orange",
"OPTION_VAL_TWB64_096_STRAW_HAT_RED": "TWB64 096 - Straw Hat Red",
"OPTION_VAL_TWB64_097_SWORD_ART_CYAN": "TWB64 097 - Sword Art Cyan",
"OPTION_VAL_TWB64_098_DEKU_ALPHA_EMERALD": "TWB64 098 - Deku Alpha Emerald",
"OPTION_VAL_TWB64_099_BLUE_STRIPES_VER": "TWB64 099 - Blue Stripes Ver.",
"OPTION_VAL_TWB64_100_STONE_ORANGE": "TWB64 100 - Stone Orange",
"GAMBATTE_GB_PALETTE_TWB64_2_LABEL": "> TWB64 - Pack 2 Palette",
"GAMBATTE_GB_PALETTE_TWB64_2_INFO_0": "Selects internal colorization palette when 'Internal Palette' is set to 'TWB64 - Pack 2'.",
"OPTION_VAL_TWB64_101_765PRO_PINK": "TWB64 101 - 765PRO Pink",
"OPTION_VAL_TWB64_102_CINDERELLA_BLUE": "TWB64 102 - CINDERELLA Blue",
"OPTION_VAL_TWB64_103_MILLION_YELLOW": "TWB64 103 - MILLION Yellow!",
"OPTION_VAL_TWB64_104_SIDEM_GREEN": "TWB64 104 - SideM Green",
"OPTION_VAL_TWB64_105_SHINY_SKY_BLUE": "TWB64 105 - SHINY Sky Blue",
"OPTION_VAL_TWB64_106_ANGRY_VOLCANO_VER": "TWB64 106 - Angry Volcano Ver.",
"OPTION_VAL_TWB64_107_YO_KAI_PINK": "TWB64 107 - Yo-kai Pink",
"OPTION_VAL_TWB64_108_YO_KAI_GREEN": "TWB64 108 - Yo-kai Green",
"OPTION_VAL_TWB64_109_YO_KAI_BLUE": "TWB64 109 - Yo-kai Blue",
"OPTION_VAL_TWB64_110_YO_KAI_PURPLE": "TWB64 110 - Yo-kai Purple",
"OPTION_VAL_TWB64_111_AQUATIC_IRO": "TWB64 111 - Aquatic Iro",
"OPTION_VAL_TWB64_112_TEA_MIDORI": "TWB64 112 - Tea Midori",
"OPTION_VAL_TWB64_113_SAKURA_PINK": "TWB64 113 - Sakura Pink",
"OPTION_VAL_TWB64_114_WISTERIA_MURASAKI": "TWB64 114 - Wisteria Murasaki",
"OPTION_VAL_TWB64_115_ONI_AKA": "TWB64 115 - Oni Aka",
"OPTION_VAL_TWB64_116_GOLDEN_KIIRO": "TWB64 116 - Golden Kiiro",
"OPTION_VAL_TWB64_117_SILVER_SHIRO": "TWB64 117 - Silver Shiro",
"OPTION_VAL_TWB64_118_FRUITY_ORANGE": "TWB64 118 - Fruity Orange",
"OPTION_VAL_TWB64_119_AKB48_PINK": "TWB64 119 - AKB48 Pink",
"OPTION_VAL_TWB64_120_MIKU_BLUE": "TWB64 120 - Miku Blue",
"OPTION_VAL_TWB64_121_FAIRY_TAIL_RED": "TWB64 121 - Fairy Tail Red",
"OPTION_VAL_TWB64_122_SURVEY_CORPS_BROWN": "TWB64 122 - Survey Corps Brown",
"OPTION_VAL_TWB64_123_ISLAND_GREEN": "TWB64 123 - Island Green",
"OPTION_VAL_TWB64_124_MANIA_PLUS_GREEN": "TWB64 124 - Mania Plus Green",
"OPTION_VAL_TWB64_125_NINJA_TURTLE_GREEN": "TWB64 125 - Ninja Turtle Green",
"OPTION_VAL_TWB64_126_SLIME_BLUE": "TWB64 126 - Slime Blue",
"OPTION_VAL_TWB64_127_LIME_MIDORI": "TWB64 127 - Lime Midori",
"OPTION_VAL_TWB64_128_GHOSTLY_AOI": "TWB64 128 - Ghostly Aoi",
"OPTION_VAL_TWB64_129_RETRO_BOGEDA": "TWB64 129 - Retro Bogeda",
"OPTION_VAL_TWB64_130_ROYAL_BLUE": "TWB64 130 - Royal Blue",
"OPTION_VAL_TWB64_131_NEON_PURPLE": "TWB64 131 - Neon Purple",
"OPTION_VAL_TWB64_132_NEON_ORANGE": "TWB64 132 - Neon Orange",
"OPTION_VAL_TWB64_133_MOONLIGHT_VISION": "TWB64 133 - Moonlight Vision",
"OPTION_VAL_TWB64_134_TOKYO_RED": "TWB64 134 - Tokyo Red",
"OPTION_VAL_TWB64_135_PARIS_GOLD": "TWB64 135 - Paris Gold",
"OPTION_VAL_TWB64_136_BEIJING_BLUE": "TWB64 136 - Beijing Blue",
"OPTION_VAL_TWB64_137_PAC_MAN_YELLOW": "TWB64 137 - Pac-Man Yellow",
"OPTION_VAL_TWB64_138_IRISH_GREEN": "TWB64 138 - Irish Green",
"OPTION_VAL_TWB64_139_KAKAROT_ORANGE": "TWB64 139 - Kakarot Orange",
"OPTION_VAL_TWB64_140_DRAGON_BALL_ORANGE": "TWB64 140 - Dragon Ball Orange",
"OPTION_VAL_TWB64_141_CHRISTMAS_GOLD": "TWB64 141 - Christmas Gold",
"OPTION_VAL_TWB64_142_PEPSI_BLUE": "TWB64 142 - Pepsi Blue",
"OPTION_VAL_TWB64_143_BUBBLUN_GREEN": "TWB64 143 - Bubblun Green",
"OPTION_VAL_TWB64_144_BOBBLUN_BLUE": "TWB64 144 - Bobblun Blue",
"OPTION_VAL_TWB64_145_BAJA_BLAST_STORM": "TWB64 145 - Baja Blast Storm",
"OPTION_VAL_TWB64_146_OLYMPIC_GOLD": "TWB64 146 - Olympic Gold",
"OPTION_VAL_TWB64_147_VALUE_ORANGE": "TWB64 147 - Value Orange",
"OPTION_VAL_TWB64_148_LIELLA_PURPLE": "TWB64 148 - Liella Purple!",
"OPTION_VAL_TWB64_149_OLYMPIC_SILVER": "TWB64 149 - Olympic Silver",
"OPTION_VAL_TWB64_150_OLYMPIC_BRONZE": "TWB64 150 - Olympic Bronze",
"OPTION_VAL_TWB64_151_ANA_SKY_BLUE": "TWB64 151 - ANA Sky Blue",
"OPTION_VAL_TWB64_152_NIJIGASAKI_ORANGE": "TWB64 152 - Nijigasaki Orange",
"OPTION_VAL_TWB64_153_HOLOBLUE": "TWB64 153 - HoloBlue",
"OPTION_VAL_TWB64_154_WRESTLING_RED": "TWB64 154 - Wrestling Red",
"OPTION_VAL_TWB64_155_YOSHI_EGG_GREEN": "TWB64 155 - Yoshi Egg Green",
"OPTION_VAL_TWB64_156_POKEDEX_RED": "TWB64 156 - Pokedex Red",
"OPTION_VAL_TWB64_157_DISNEY_DREAM_BLUE": "TWB64 157 - Disney Dream Blue",
"OPTION_VAL_TWB64_158_XBOX_GREEN": "TWB64 158 - Xbox Green",
"OPTION_VAL_TWB64_159_SONIC_MEGA_BLUE": "TWB64 159 - Sonic Mega Blue",
"OPTION_VAL_TWB64_160_G4_ORANGE": "TWB64 160 - G4 Orange",
"OPTION_VAL_TWB64_161_SCARLETT_GREEN": "TWB64 161 - Scarlett Green",
"OPTION_VAL_TWB64_162_GLITCHY_BLUE": "TWB64 162 - Glitchy Blue",
"OPTION_VAL_TWB64_163_CLASSIC_LCD": "TWB64 163 - Classic LCD",
"OPTION_VAL_TWB64_164_3DS_VIRTUAL_CONSOLE_VER": "TWB64 164 - 3DS Virtual Console Ver.",
"OPTION_VAL_TWB64_165_POCKETSTATION_VER": "TWB64 165 - PocketStation Ver.",
"OPTION_VAL_TWB64_166_GAME_AND_GOLD": "TWB64 166 - Game and Gold",
"OPTION_VAL_TWB64_167_SMURFY_BLUE": "TWB64 167 - Smurfy Blue",
"OPTION_VAL_TWB64_168_SWAMPY_OGRE_GREEN": "TWB64 168 - Swampy Ogre Green",
"OPTION_VAL_TWB64_169_SAILOR_SPINACH_GREEN": "TWB64 169 - Sailor Spinach Green",
"OPTION_VAL_TWB64_170_SHENRON_GREEN": "TWB64 170 - Shenron Green",
"OPTION_VAL_TWB64_171_BERSERK_BLOOD": "TWB64 171 - Berserk Blood",
"OPTION_VAL_TWB64_172_SUPER_STAR_PINK": "TWB64 172 - Super Star Pink",
"OPTION_VAL_TWB64_173_GAMEBUINO_CLASSIC_VER": "TWB64 173 - Gamebuino Classic Ver.",
"OPTION_VAL_TWB64_174_BARBIE_PINK": "TWB64 174 - Barbie Pink",
"OPTION_VAL_TWB64_175_STAR_COMMAND_GREEN": "TWB64 175 - Star Command Green",
"OPTION_VAL_TWB64_176_NOKIA_3310_VER": "TWB64 176 - Nokia 3310 Ver.",
"OPTION_VAL_TWB64_177_CLOVER_GREEN": "TWB64 177 - Clover Green",
"OPTION_VAL_TWB64_178_CRASH_ORANGE": "TWB64 178 - Crash Orange",
"OPTION_VAL_TWB64_179_FAMICOM_DISK_YELLOW": "TWB64 179 - Famicom Disk Yellow",
"OPTION_VAL_TWB64_180_TEAM_ROCKET_RED": "TWB64 180 - Team Rocket Red",
"OPTION_VAL_TWB64_181_SEIKO_TIMER_YELLOW": "TWB64 181 - SEIKO Timer Yellow",
"OPTION_VAL_TWB64_182_PINK109": "TWB64 182 - PINK109",
"OPTION_VAL_TWB64_183_DORAEMON_BLUE": "TWB64 183 - Doraemon Blue",
"OPTION_VAL_TWB64_184_FURY_BLUE": "TWB64 184 - Fury Blue",
"OPTION_VAL_TWB64_185_ROCKSTAR_ORANGE": "TWB64 185 - Rockstar Orange",
"OPTION_VAL_TWB64_186_PUYO_PUYO_GREEN": "TWB64 186 - Puyo Puyo Green",
"OPTION_VAL_TWB64_187_SUSAN_G_PINK": "TWB64 187 - Susan G. Pink",
"OPTION_VAL_TWB64_188_PIZZA_HUT_RED": "TWB64 188 - Pizza Hut Red",
"OPTION_VAL_TWB64_189_PLUMBOB_GREEN": "TWB64 189 - Plumbob Green",
"OPTION_VAL_TWB64_190_GRAND_IVORY": "TWB64 190 - Grand Ivory",
"OPTION_VAL_TWB64_191_DEMON_S_GOLD": "TWB64 191 - Demon's Gold",
"OPTION_VAL_TWB64_192_SEGA_TOKYO_BLUE": "TWB64 192 - SEGA Tokyo Blue",
"OPTION_VAL_TWB64_193_CHAMPION_BLUE": "TWB64 193 - Champion Blue",
"OPTION_VAL_TWB64_194_DK_BARREL_BROWN": "TWB64 194 - DK Barrel Brown",
"OPTION_VAL_TWB64_195_EVANGELION_GREEN": "TWB64 195 - Evangelion Green",
"OPTION_VAL_TWB64_196_EQUESTRIAN_PURPLE": "TWB64 196 - Equestrian Purple",
"OPTION_VAL_TWB64_197_AUTOBOT_RED": "TWB64 197 - Autobot Red",
"OPTION_VAL_TWB64_198_NICONICO_SEA_GREEN": "TWB64 198 - Niconico Sea Green",
"OPTION_VAL_TWB64_199_DURACELL_COPPER": "TWB64 199 - Duracell Copper",
"OPTION_VAL_TWB64_200_TOKYO_SKYTREE_CLOUDY_BLUE": "TWB64 200 - TOKYO SKYTREE CLOUDY BLUE",
"GAMBATTE_GBC_COLOR_CORRECTION_LABEL": "Color Correction",
"GAMBATTE_GBC_COLOR_CORRECTION_INFO_0": "Adjusts output colors to match the display of real Game Boy Color hardware. 'GBC Only' ensures that correction will only be applied when playing Game Boy Color games, or when using a Game Boy Color palette to colorize a Game Boy game. 'Always' applies color correction to all content, and will produce unexpected/suboptimal results when using 'GB' or 'SGB' internal color palettes.",
"OPTION_VAL_GBC_ONLY": "GBC Only",
"OPTION_VAL_ALWAYS": "Always",
"GAMBATTE_GBC_COLOR_CORRECTION_MODE_LABEL": "Color Correction Mode",
"GAMBATTE_GBC_COLOR_CORRECTION_MODE_INFO_0": "Specifies method used when performing color correction. 'Accurate' produces output almost indistinguishable from a real Game Boy Color LCD panel. 'Fast' merely darkens colors and reduces saturation, and may be used on low-end hardware if the 'Accurate' method is too slow.",
"OPTION_VAL_ACCURATE": "Accurate",
"OPTION_VAL_FAST": "Fast",
"GAMBATTE_GBC_FRONTLIGHT_POSITION_LABEL": "Color Correction - Frontlight Position",
"GAMBATTE_GBC_FRONTLIGHT_POSITION_INFO_0": "Simulates the physical response of the Game Boy Color LCD panel when illuminated from different angles. 'Central' represents standard color reproduction. 'Above Screen' increases brightness. 'Below Screen' reduces brightness. This setting only applies when 'Color Correction Mode' is set to 'Accurate'.",
"OPTION_VAL_CENTRAL": "Central",
"OPTION_VAL_ABOVE_SCREEN": "Above Screen",
"OPTION_VAL_BELOW_SCREEN": "Below Screen",
"GAMBATTE_DARK_FILTER_LEVEL_LABEL": "Dark Filter Level (percent)",
"GAMBATTE_DARK_FILTER_LEVEL_INFO_0": "Enable luminosity-based brightness reduction. May be used to avoid glare/eye strain when playing games with white backgrounds, which are intended for display on a non-backlit Game Boy Color and can therefore appear uncomfortably bright when viewed on a modern backlit screen.",
"GAMBATTE_GB_HWMODE_LABEL": "Emulated Hardware (restart)",
"GAMBATTE_GB_HWMODE_INFO_0": "Specify which type of hardware to emulate. 'Auto' is recommended. Selecting 'GBA' unlocks extra features in certain 'GBA enhanced' Game Boy Color games (Shantae, Wendy - Every Witch Way, Legend of Zelda: Oracle of Seasons/Ages...).",
"OPTION_VAL_GB": "GB",
"OPTION_VAL_GBA": "GBA",
"GAMBATTE_GB_BOOTLOADER_LABEL": "Use Official Bootloader (restart)",
"GAMBATTE_GB_BOOTLOADER_INFO_0": "Enable support for official Game Boy and Game Boy Color bootloaders, with corresponding start-up logo animations.",
"GAMBATTE_MIX_FRAMES_LABEL": "Interframe Blending",
"GAMBATTE_MIX_FRAMES_INFO_0": "Simulates LCD ghosting effects. 'Simple' performs a 50:50 mix of the current and previous frames. 'LCD Ghosting' mimics natural LCD response times by combining multiple buffered frames. 'Simple' blending is required when playing games that rely on LCD ghosting for transparency effects (Wave Race, Ballistic, Chikyuu Kaihou Gun ZAS...).",
"OPTION_VAL_MIX": "Simple",
"OPTION_VAL_LCD_GHOSTING": "LCD Ghosting (Accurate)",
"OPTION_VAL_LCD_GHOSTING_FAST": "LCD Ghosting (Fast)",
"GAMBATTE_UP_DOWN_ALLOWED_LABEL": "Allow Opposing Directions",
"GAMBATTE_UP_DOWN_ALLOWED_INFO_0": "Enabling this will allow pressing / quickly alternating / holding both left and right (or up and down) directions at the same time. This may cause movement-based glitches.",
"GAMBATTE_TURBO_PERIOD_LABEL": "Turbo Button Period",
"GAMBATTE_TURBO_PERIOD_INFO_0": "Specify the repeat interval (in frames) when holding down the Turbo A/B buttons.",
"GAMBATTE_RUMBLE_LEVEL_LABEL": "Gamepad Rumble Strength",
"GAMBATTE_RUMBLE_LEVEL_INFO_0": "Enables haptic feedback effects for supported games (Pokemon Pinball, Perfect Dark...).",
"GAMBATTE_SHOW_GB_LINK_SETTINGS_LABEL": "Show Game Boy Link Settings",
"GAMBATTE_SHOW_GB_LINK_SETTINGS_INFO_0": "Enable configuration of networked 'Game Boy Link' (multiplayer) options. NOTE: Quick Menu may need to be toggled for this setting to take effect.",
"GAMBATTE_GB_LINK_MODE_LABEL": "Game Boy Link Mode",
"GAMBATTE_GB_LINK_MODE_LABEL_CAT": "Link Mode",
"GAMBATTE_GB_LINK_MODE_INFO_0": "When enabling networked 'Game Boy Link' functionality, specify whether current instance should run as a server or client.",
"OPTION_VAL_NOT_CONNECTED": "Not Connected",
"OPTION_VAL_NETWORK_SERVER": "Network Server",
"OPTION_VAL_NETWORK_CLIENT": "Network Client",
"GAMBATTE_GB_LINK_NETWORK_PORT_LABEL": "Network Link Port",
"GAMBATTE_GB_LINK_NETWORK_PORT_LABEL_CAT": "Port",
"GAMBATTE_GB_LINK_NETWORK_PORT_INFO_0": "Specify port used for 'Game Boy Link' network communication.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_LABEL": "Network Link Server Address Pt. 01: x__.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_LABEL_CAT": "Server Address Pt. 01: x__.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_INFO_0": "1st digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_1_INFO_1": "1st digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_LABEL": "Network Link Server Address Pt. 02: _x_.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_LABEL_CAT": "Server Address Pt. 02: _x_.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_INFO_0": "2nd digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_2_INFO_1": "2nd digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_LABEL": "Network Link Server Address Pt. 03: __x.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_LABEL_CAT": "Server Address Pt. 03: __x.___.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_INFO_0": "3rd digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_3_INFO_1": "3rd digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_LABEL": "Network Link Server Address Pt. 04: ___.x__.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_LABEL_CAT": "Server Address Pt. 04: ___.x__.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_INFO_0": "4th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_4_INFO_1": "4th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_LABEL": "Network Link Server Address Pt. 05: ___._x_.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_LABEL_CAT": "Server Address Pt. 05: ___._x_.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_INFO_0": "5th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_5_INFO_1": "5th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_LABEL": "Network Link Server Address Pt. 06: ___.__x.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_LABEL_CAT": "Server Address Pt. 06: ___.__x.___.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_INFO_0": "6th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_6_INFO_1": "6th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_LABEL": "Network Link Server Address Pt. 07: ___.___.x__.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_LABEL_CAT": "Server Address Pt. 07: ___.___.x__.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_INFO_0": "7th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_7_INFO_1": "7th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_LABEL": "Network Link Server Address Pt. 08: ___.___._x_.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_LABEL_CAT": "Server Address Pt. 08: ___.___._x_.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_INFO_0": "8th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_8_INFO_1": "8th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_LABEL": "Network Link Server Address Pt. 09: ___.___.__x.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_LABEL_CAT": "Server Address Pt. 09: ___.___.__x.___",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_INFO_0": "9th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_9_INFO_1": "9th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_LABEL": "Network Link Server Address Pt. 10: ___.___.___.x__",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_LABEL_CAT": "Server Address Pt. 10: ___.___.___.x__",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_INFO_0": "10th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_10_INFO_1": "10th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_LABEL": "Network Link Server Address Pt. 11: ___.___.___._x_",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_LABEL_CAT": "Server Address Pt. 11: ___.___.___._x_",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_INFO_0": "11th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_11_INFO_1": "11th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_LABEL": "Network Link Server Address Pt. 12: ___.___.___.__x",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_LABEL_CAT": "Server Address Pt. 12: ___.___.___.__x",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_INFO_0": "12th digit of remote 'Game Boy Link' network server IP address. Only used when 'Game Boy Link Mode' is set to 'Network Client'.",
"GAMBATTE_GB_LINK_NETWORK_SERVER_IP_12_INFO_1": "12th digit of remote 'Game Boy Link' network server IP address. Only used when 'Link Mode' is set to 'Network Client'."
}

View File

@ -9,7 +9,7 @@ Both v1 and v2 structs are supported. It is, however, recommended to convert v1
'v1_to_v2_converter.py'.
Usage:
python3 path/to/core_opt_translation.py "path/to/where/libretro_core_options.h & libretro_core_options_intl.h/are"
python3 path/to/core_option_translation.py "path/to/where/libretro_core_options.h & libretro_core_options_intl.h/are"
This script will:
1.) create key words for & extract the texts from libretro_core_options.h & save them into intl/_us/core_options.h
@ -23,88 +23,62 @@ import json
import urllib.request as req
import shutil
# for uploading translations to Crowdin, the Crowdin 'language id' is required
LANG_CODE_TO_ID = {'_ar': 'ar',
'_ast': 'ast',
'_chs': 'zh-CN',
'_cht': 'zh-TW',
'_cs': 'cs',
'_cy': 'cy',
'_da': 'da',
'_de': 'de',
'_el': 'el',
'_eo': 'eo',
'_es': 'es-ES',
'_fa': 'fa',
'_fi': 'fi',
'_fr': 'fr',
'_gl': 'gl',
'_he': 'he',
'_hu': 'hu',
'_id': 'id',
'_it': 'it',
'_ja': 'ja',
'_ko': 'ko',
'_nl': 'nl',
'_pl': 'pl',
'_pt_br': 'pt-BR',
'_pt_pt': 'pt-PT',
'_ru': 'ru',
'_sk': 'sk',
'_sv': 'sv-SE',
'_tr': 'tr',
'_uk': 'uk',
'_vn': 'vi'}
LANG_CODE_TO_R_LANG = {'_ar': 'RETRO_LANGUAGE_ARABIC',
'_ast': 'RETRO_LANGUAGE_ASTURIAN',
'_chs': 'RETRO_LANGUAGE_CHINESE_SIMPLIFIED',
'_cht': 'RETRO_LANGUAGE_CHINESE_TRADITIONAL',
'_cs': 'RETRO_LANGUAGE_CZECH',
'_cy': 'RETRO_LANGUAGE_WELSH',
'_da': 'RETRO_LANGUAGE_DANISH',
'_de': 'RETRO_LANGUAGE_GERMAN',
'_el': 'RETRO_LANGUAGE_GREEK',
'_eo': 'RETRO_LANGUAGE_ESPERANTO',
'_es': 'RETRO_LANGUAGE_SPANISH',
'_fa': 'RETRO_LANGUAGE_PERSIAN',
'_fi': 'RETRO_LANGUAGE_FINNISH',
'_fr': 'RETRO_LANGUAGE_FRENCH',
'_gl': 'RETRO_LANGUAGE_GALICIAN',
'_he': 'RETRO_LANGUAGE_HEBREW',
'_hu': 'RETRO_LANGUAGE_HUNGARIAN',
'_id': 'RETRO_LANGUAGE_INDONESIAN',
'_it': 'RETRO_LANGUAGE_ITALIAN',
'_ja': 'RETRO_LANGUAGE_JAPANESE',
'_ko': 'RETRO_LANGUAGE_KOREAN',
'_nl': 'RETRO_LANGUAGE_DUTCH',
'_pl': 'RETRO_LANGUAGE_POLISH',
'_pt_br': 'RETRO_LANGUAGE_PORTUGUESE_BRAZIL',
'_pt_pt': 'RETRO_LANGUAGE_PORTUGUESE_PORTUGAL',
'_ru': 'RETRO_LANGUAGE_RUSSIAN',
'_sk': 'RETRO_LANGUAGE_SLOVAK',
'_sv': 'RETRO_LANGUAGE_SWEDISH',
'_tr': 'RETRO_LANGUAGE_TURKISH',
'_uk': 'RETRO_LANGUAGE_UKRAINIAN',
'_us': 'RETRO_LANGUAGE_ENGLISH',
'_vn': 'RETRO_LANGUAGE_VIETNAMESE'}
# LANG_CODE_TO_R_LANG = {'_ar': 'RETRO_LANGUAGE_ARABIC',
# '_ast': 'RETRO_LANGUAGE_ASTURIAN',
# '_chs': 'RETRO_LANGUAGE_CHINESE_SIMPLIFIED',
# '_cht': 'RETRO_LANGUAGE_CHINESE_TRADITIONAL',
# '_cs': 'RETRO_LANGUAGE_CZECH',
# '_cy': 'RETRO_LANGUAGE_WELSH',
# '_da': 'RETRO_LANGUAGE_DANISH',
# '_de': 'RETRO_LANGUAGE_GERMAN',
# '_el': 'RETRO_LANGUAGE_GREEK',
# '_eo': 'RETRO_LANGUAGE_ESPERANTO',
# '_es': 'RETRO_LANGUAGE_SPANISH',
# '_fa': 'RETRO_LANGUAGE_PERSIAN',
# '_fi': 'RETRO_LANGUAGE_FINNISH',
# '_fr': 'RETRO_LANGUAGE_FRENCH',
# '_gl': 'RETRO_LANGUAGE_GALICIAN',
# '_he': 'RETRO_LANGUAGE_HEBREW',
# '_hu': 'RETRO_LANGUAGE_HUNGARIAN',
# '_id': 'RETRO_LANGUAGE_INDONESIAN',
# '_it': 'RETRO_LANGUAGE_ITALIAN',
# '_ja': 'RETRO_LANGUAGE_JAPANESE',
# '_ko': 'RETRO_LANGUAGE_KOREAN',
# '_nl': 'RETRO_LANGUAGE_DUTCH',
# '_oc': 'RETRO_LANGUAGE_OCCITAN',
# '_pl': 'RETRO_LANGUAGE_POLISH',
# '_pt_br': 'RETRO_LANGUAGE_PORTUGUESE_BRAZIL',
# '_pt_pt': 'RETRO_LANGUAGE_PORTUGUESE_PORTUGAL',
# '_ru': 'RETRO_LANGUAGE_RUSSIAN',
# '_sk': 'RETRO_LANGUAGE_SLOVAK',
# '_sv': 'RETRO_LANGUAGE_SWEDISH',
# '_tr': 'RETRO_LANGUAGE_TURKISH',
# '_uk': 'RETRO_LANGUAGE_UKRAINIAN',
# '_us': 'RETRO_LANGUAGE_ENGLISH',
# '_vn': 'RETRO_LANGUAGE_VIETNAMESE'}
# these are handled by RetroArch directly - no need to include them in core translations
ON_OFFS = {'"enabled"', '"disabled"', '"true"', '"false"', '"on"', '"off"'}
def remove_special_chars(text: str, char_set=0) -> str:
def remove_special_chars(text: str, char_set=0, allow_non_ascii=False) -> str:
"""Removes special characters from a text.
:param text: String to be cleaned.
:param char_set: 0 -> remove all ASCII special chars except for '_' & 'space';
:param char_set: 0 -> remove all ASCII special chars except for '_' & 'space' (default)
1 -> remove invalid chars from file names
:param allow_non_ascii: False -> all non-ascii characters will be removed (default)
True -> non-ascii characters will be passed through
:return: Clean text.
"""
command_chars = [chr(unicode) for unicode in tuple(range(0, 32)) + (127,)]
special_chars = ([chr(unicode) for unicode in tuple(range(33, 48)) + tuple(range(58, 65)) + tuple(range(91, 95))
+ (96,) + tuple(range(123, 127))],
('\\', '/', ':', '*', '?', '"', '<', '>', '|'))
res = text
('\\', '/', ':', '*', '?', '"', '<', '>', '|', '#', '%',
'&', '{', '}', '$', '!', '¸', "'", '@', '+', '='))
res = text if allow_non_ascii \
else text.encode('ascii', errors='ignore').decode('unicode-escape')
for cm in command_chars:
res = res.replace(cm, '_')
for sp in special_chars[char_set]:
@ -284,7 +258,7 @@ def get_texts(text: str) -> dict:
set_value = set_key
# re.fullmatch(r'(?:[+-][0-9]+)+', value[1:-1])
if set_value not in just_string[lang] and not re.sub(r'[+-]', '', set_value[1:-1]).isdigit():
clean_key = set_key.encode('ascii', errors='ignore').decode('unicode-escape')[1:-1]
clean_key = set_key[1:-1]
clean_key = remove_special_chars(clean_key).upper().replace(' ', '_')
m_h = create_non_dupe(re.sub(r'__+', '_', f"OPTION_VAL_{clean_key}"), opt, hash_n_string[lang])
hash_n_string[lang][m_h] = set_value
@ -418,14 +392,14 @@ def get_crowdin_client(dir_path: str) -> str:
return jar_path
def create_intl_file(intl_file_path: str, intl_dir_path: str, text: str, core_name: str, file_path: str) -> None:
def create_intl_file(localisation_file_path: str, intl_dir_path: str, text: str, core_name: str, file_path: str) -> None:
"""Creates 'libretro_core_options_intl.h' from Crowdin translations.
:param intl_file_path: Path to 'libretro_core_options_intl.h'
:param localisation_file_path: Path to 'libretro_core_options_intl.h'
:param intl_dir_path: Path to the intl directory.
:param text: Content of the 'libretro_core_options.h' being translated.
:param core_name: Name of the core. Needed to identify the files to pull the translations from.
:param file_path: Path to the '<core name>_us.h' file, containing the original English texts.
:param file_path: Path to the '<core name>.h' file, containing the original English texts.
:return: None
"""
msg_dict = {}
@ -503,30 +477,44 @@ def create_intl_file(intl_file_path: str, intl_dir_path: str, text: str, core_na
for msg in masked_msgs:
msg_dict[msg.group(2)] = msg.group(1)
with open(intl_file_path, 'r', encoding='utf-8') as intl: # libretro_core_options_intl.h
in_text = intl.read()
intl_start = re.search(re.escape('/*\n'
' ********************************\n'
' * Core Option Definitions\n'
' ********************************\n'
'*/\n'), in_text)
if intl_start:
out_txt = in_text[:intl_start.end(0)]
else:
intl_start = re.search(re.escape('#ifdef __cplusplus\n'
'extern "C" {\n'
'#endif\n'), in_text)
out_txt = in_text[:intl_start.end(0)]
out_txt = "#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__\n" \
"#define LIBRETRO_CORE_OPTIONS_INTL_H__\n\n" \
"#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900)\n" \
"/* https://support.microsoft.com/en-us/kb/980263 */\n" \
'#pragma execution_character_set("utf-8")\n' \
"#pragma warning(disable:4566)\n" \
"#endif\n\n" \
"#include <libretro.h>\n\n"
for folder in os.listdir(intl_dir_path): # intl/_*
if os.path.isdir(os.path.join(intl_dir_path, folder)) and folder.startswith('_')\
and folder != '_us' and folder != '__pycache__':
translation_path = os.path.join(intl_dir_path, folder, core_name + '.h') # <core_name>_<lang>.h
if os.path.isfile(localisation_file_path):
with open(localisation_file_path, 'r', encoding='utf-8') as intl: # libretro_core_options_intl.h
in_text = intl.read()
intl_start = re.search(re.escape('/*\n'
' ********************************\n'
' * Core Option Definitions\n'
' ********************************\n'
'*/\n'), in_text)
if intl_start:
out_txt = in_text[:intl_start.end(0)]
else:
intl_start = re.search(re.escape('#ifdef __cplusplus\n'
'extern "C" {\n'
'#endif\n'), in_text)
if intl_start:
out_txt = in_text[:intl_start.end(0)]
for folder in os.scandir(intl_dir_path): # intl/_*
if folder.is_dir() and folder.name.startswith('_')\
and folder.name != '_us' and folder.name != '__pycache__':
translation_path = os.path.join(folder.path, core_name + '.h') # <core_name>_<lang>.h
if not os.path.isfile(translation_path):
continue
# all structs: group(0) full struct, group(1) beginning, group(2) content
struct_groups = cor.p_struct.finditer(text)
lang_up = folder.upper()
lang_low = folder.lower()
out_txt = out_txt + f'/* {LANG_CODE_TO_R_LANG[lang_low]} */\n\n' # /* RETRO_LANGUAGE_NAME */
lang_up = folder.name.upper()
lang_low = folder.name.lower()
out_txt = out_txt + f'/* RETRO_LANGUAGE{lang_up} */\n\n' # /* RETRO_LANGUAGE_NM */
with open(translation_path, 'r+', encoding='utf-8') as f_in: # <core name>.h
out_txt = out_txt + f_in.read() + '\n'
for construct in struct_groups:
@ -561,7 +549,7 @@ def create_intl_file(intl_file_path: str, intl_dir_path: str, text: str, core_na
'};\n\n'
# shutil.rmtree(JOINER.join((intl_dir_path, folder)))
with open(intl_file_path, 'w', encoding='utf-8') as intl:
with open(localisation_file_path, 'w', encoding='utf-8') as intl:
intl.write(out_txt + '\n#ifdef __cplusplus\n'
'}\n#endif\n'
'\n#endif')
@ -571,7 +559,6 @@ def create_intl_file(intl_file_path: str, intl_dir_path: str, text: str, core_na
# -------------------- MAIN -------------------- #
if __name__ == '__main__':
#
try:
if os.path.isfile(sys.argv[1]):
_temp = os.path.dirname(sys.argv[1])
@ -584,26 +571,24 @@ if __name__ == '__main__':
TARGET_DIR_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
print("No path provided, assuming parent directory:\n" + TARGET_DIR_PATH)
NAME = 'core_options'
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
H_FILE_PATH = os.path.join(TARGET_DIR_PATH, 'libretro_core_options.h')
INTL_FILE_PATH = os.path.join(TARGET_DIR_PATH, 'libretro_core_options_intl.h')
_core_name = 'core_options'
try:
print('Getting texts from libretro_core_options.h')
with open(H_FILE_PATH, 'r+', encoding='utf-8') as _h_file:
_main_text = _h_file.read()
_hash_n_str = get_texts(_main_text)
_files = create_msg_hash(DIR_PATH, _core_name, _hash_n_str)
_source_jsons = h2json(_files)
except Exception as e:
print(e)
print('Getting texts from libretro_core_options.h')
with open(H_FILE_PATH, 'r+', encoding='utf-8') as _h_file:
_main_text = _h_file.read()
_hash_n_str = get_texts(_main_text)
_files = create_msg_hash(DIR_PATH, NAME, _hash_n_str)
_source_jsons = h2json(_files)
print('Getting texts from libretro_core_options_intl.h')
with open(INTL_FILE_PATH, 'r+', encoding='utf-8') as _intl_file:
_intl_text = _intl_file.read()
_hash_n_str_intl = get_texts(_intl_text)
_intl_files = create_msg_hash(DIR_PATH, _core_name, _hash_n_str_intl)
_intl_jsons = h2json(_intl_files)
if os.path.isfile(INTL_FILE_PATH):
with open(INTL_FILE_PATH, 'r+', encoding='utf-8') as _intl_file:
_intl_text = _intl_file.read()
_hash_n_str_intl = get_texts(_intl_text)
_intl_files = create_msg_hash(DIR_PATH, NAME, _hash_n_str_intl)
_intl_jsons = h2json(_intl_files)
print('\nAll done!')

13
intl/crowdin.yaml Normal file
View File

@ -0,0 +1,13 @@
"project_id": "380544"
"api_token": "_secret_"
"base_url": "https://api.crowdin.com"
"preserve_hierarchy": true
"files":
[
{
"source": "/intl/_us/*.json",
"dest": "/_core_name_/%original_file_name%",
"translation": "/intl/_%two_letters_code%/%original_file_name%",
},
]

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python3
import core_opt_translation as t
import core_option_translation as t
if __name__ == '__main__':
_core_name = 'core_options'
NAME = 'core_options'
try:
if t.os.path.isfile(t.sys.argv[1]):
@ -21,13 +21,11 @@ if __name__ == '__main__':
DIR_PATH = t.os.path.dirname(t.os.path.realpath(__file__))
H_FILE_PATH = t.os.path.join(TARGET_DIR_PATH, 'libretro_core_options.h')
_core_name = t.clean_file_name(_core_name)
print('Getting texts from libretro_core_options.h')
with open(H_FILE_PATH, 'r+', encoding='utf-8') as _h_file:
_main_text = _h_file.read()
_hash_n_str = t.get_texts(_main_text)
_files = t.create_msg_hash(DIR_PATH, _core_name, _hash_n_str)
_files = t.create_msg_hash(DIR_PATH, NAME, _hash_n_str)
_source_jsons = t.h2json(_files)

View File

@ -0,0 +1,84 @@
#!/usr/bin/env python3
import re
import os
import shutil
import subprocess
import sys
import urllib.request
import zipfile
import core_option_translation as t
# Check Crowdin API Token and core name
try:
api_key = sys.argv[1]
core_name = t.clean_file_name(sys.argv[2])
except IndexError as e:
print('Please provide Crowdin API Token and core name!')
raise e
DIR_PATH = t.os.path.dirname(t.os.path.realpath(__file__))
YAML_PATH = t.os.path.join(DIR_PATH, 'crowdin.yaml')
# Apply Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": "_secret_"',
f'"api_token": "{api_key}"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/_core_name_/%original_file_name%",',
f'"dest": "/{core_name}/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
try:
# Download Crowdin CLI
jar_name = 'crowdin-cli.jar'
jar_path = t.os.path.join(DIR_PATH, jar_name)
crowdin_cli_file = 'crowdin-cli.zip'
crowdin_cli_url = 'https://downloads.crowdin.com/cli/v3/' + crowdin_cli_file
crowdin_cli_path = t.os.path.join(DIR_PATH, crowdin_cli_file)
if not os.path.isfile(t.os.path.join(DIR_PATH, jar_name)):
print('download crowdin-cli.jar')
urllib.request.urlretrieve(crowdin_cli_url, crowdin_cli_path)
with zipfile.ZipFile(crowdin_cli_path, 'r') as zip_ref:
jar_dir = t.os.path.join(DIR_PATH, zip_ref.namelist()[0])
for file in zip_ref.namelist():
if file.endswith(jar_name):
jar_file = file
break
zip_ref.extract(jar_file, path=DIR_PATH)
os.rename(t.os.path.join(DIR_PATH, jar_file), jar_path)
os.remove(crowdin_cli_path)
shutil.rmtree(jar_dir)
print('upload source *.json')
subprocess.run(['java', '-jar', jar_path, 'upload', 'sources', '--config', YAML_PATH])
# Reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"',
'"api_token": "_secret_"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
except Exception as e:
# Try really hard to reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"',
'"api_token": "_secret_"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
raise e

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
import core_opt_translation as t
import core_option_translation as t
if __name__ == '__main__':
@ -16,28 +16,25 @@ if __name__ == '__main__':
TARGET_DIR_PATH = t.os.path.dirname(t.os.path.dirname(t.os.path.realpath(__file__)))
print("No path provided, assuming parent directory:\n" + TARGET_DIR_PATH)
NAME = 'core_options'
DIR_PATH = t.os.path.dirname(t.os.path.realpath(__file__))
US_FILE_PATH = t.os.path.join(DIR_PATH, '_us', f'{NAME}.h')
H_FILE_PATH = t.os.path.join(TARGET_DIR_PATH, 'libretro_core_options.h')
INTL_FILE_PATH = t.os.path.join(TARGET_DIR_PATH, 'libretro_core_options_intl.h')
_core_name = 'core_options'
_core_name = t.clean_file_name(_core_name)
print('Getting texts from libretro_core_options.h')
with open(H_FILE_PATH, 'r+', encoding='utf-8') as _h_file:
_main_text = _h_file.read()
_hash_n_str = t.get_texts(_main_text)
_files = t.create_msg_hash(DIR_PATH, _core_name, _hash_n_str)
_files = t.create_msg_hash(DIR_PATH, NAME, _hash_n_str)
print('Converting translations *.json to *.h:')
for _folder in t.os.listdir(DIR_PATH):
if t.os.path.isdir(t.os.path.join(DIR_PATH, _folder))\
and _folder.startswith('_')\
and _folder != '__pycache__':
print(_folder)
t.json2h(DIR_PATH, t.os.path.join(DIR_PATH, _folder), _core_name)
for _folder in t.os.scandir(DIR_PATH):
if _folder.is_dir() and _folder.name.startswith('_') and _folder.name != '__pycache__':
print(_folder.name)
t.json2h(DIR_PATH, _folder.path, NAME)
print('Constructing libretro_core_options_intl.h')
t.create_intl_file(INTL_FILE_PATH, DIR_PATH, _main_text, _core_name, _files['_us'])
t.create_intl_file(INTL_FILE_PATH, DIR_PATH, _main_text, NAME, _files["_us"])
print('\nAll done!')

View File

@ -0,0 +1,84 @@
#!/usr/bin/env python3
import re
import os
import shutil
import subprocess
import sys
import urllib.request
import zipfile
import core_option_translation as t
# Check Crowdin API Token and core name
try:
api_key = sys.argv[1]
core_name = t.clean_file_name(sys.argv[2])
except IndexError as e:
print('Please provide Crowdin API Token and core name!')
raise e
DIR_PATH = t.os.path.dirname(t.os.path.realpath(__file__))
YAML_PATH = t.os.path.join(DIR_PATH, 'crowdin.yaml')
# Apply Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": "_secret_"',
f'"api_token": "{api_key}"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/_core_name_/%original_file_name%",',
f'"dest": "/{core_name}/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
try:
# Download Crowdin CLI
jar_name = 'crowdin-cli.jar'
jar_path = t.os.path.join(DIR_PATH, jar_name)
crowdin_cli_file = 'crowdin-cli.zip'
crowdin_cli_url = 'https://downloads.crowdin.com/cli/v3/' + crowdin_cli_file
crowdin_cli_path = t.os.path.join(DIR_PATH, crowdin_cli_file)
if not os.path.isfile(t.os.path.join(DIR_PATH, jar_name)):
print('download crowdin-cli.jar')
urllib.request.urlretrieve(crowdin_cli_url, crowdin_cli_path)
with zipfile.ZipFile(crowdin_cli_path, 'r') as zip_ref:
jar_dir = t.os.path.join(DIR_PATH, zip_ref.namelist()[0])
for file in zip_ref.namelist():
if file.endswith(jar_name):
jar_file = file
break
zip_ref.extract(jar_file, path=DIR_PATH)
os.rename(t.os.path.join(DIR_PATH, jar_file), jar_path)
os.remove(crowdin_cli_path)
shutil.rmtree(jar_dir)
print('download translation *.json')
subprocess.run(['java', '-jar', jar_path, 'download', '--config', YAML_PATH])
# Reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"',
'"api_token": "_secret_"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
except Exception as e:
# Try really hard to reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"',
'"api_token": "_secret_"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
raise e

103
intl/initial_sync.py Normal file
View File

@ -0,0 +1,103 @@
#!/usr/bin/env python3
import re
import os
import shutil
import subprocess
import sys
import time
import urllib.request
import zipfile
import core_option_translation as t
# Check Crowdin API Token and core name
try:
api_key = sys.argv[1]
core_name = t.clean_file_name(sys.argv[2])
except IndexError as e:
print('Please provide Crowdin API Token and core name!')
raise e
DIR_PATH = t.os.path.dirname(t.os.path.realpath(__file__))
YAML_PATH = t.os.path.join(DIR_PATH, 'crowdin.yaml')
# Apply Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": "_secret_"',
f'"api_token": "{api_key}"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/_core_name_/%original_file_name%",',
f'"dest": "/{core_name}/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
try:
# Download Crowdin CLI
jar_name = 'crowdin-cli.jar'
jar_path = t.os.path.join(DIR_PATH, jar_name)
crowdin_cli_file = 'crowdin-cli.zip'
crowdin_cli_url = 'https://downloads.crowdin.com/cli/v3/' + crowdin_cli_file
crowdin_cli_path = t.os.path.join(DIR_PATH, crowdin_cli_file)
if not os.path.isfile(t.os.path.join(DIR_PATH, jar_name)):
print('download crowdin-cli.jar')
urllib.request.urlretrieve(crowdin_cli_url, crowdin_cli_path)
with zipfile.ZipFile(crowdin_cli_path, 'r') as zip_ref:
jar_dir = t.os.path.join(DIR_PATH, zip_ref.namelist()[0])
for file in zip_ref.namelist():
if file.endswith(jar_name):
jar_file = file
break
zip_ref.extract(jar_file, path=DIR_PATH)
os.rename(t.os.path.join(DIR_PATH, jar_file), jar_path)
os.remove(crowdin_cli_path)
shutil.rmtree(jar_dir)
print('upload source & translations *.json')
subprocess.run(['java', '-jar', jar_path, 'upload', 'sources', '--config', YAML_PATH])
subprocess.run(['java', '-jar', jar_path, 'upload', 'translations', '--config', YAML_PATH])
print('wait for crowdin server to process data')
time.sleep(10)
print('download translation *.json')
subprocess.run(['java', '-jar', jar_path, 'download', '--config', YAML_PATH])
# Reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"', '"api_token": "_secret_"', crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
with open('intl/translation_workflow.py', 'r') as workflow:
workflow_config = workflow.read()
workflow_config = workflow_config.replace(
"subprocess.run(['python3', 'intl/core_option_translation.py', dir_path])",
"subprocess.run(['python3', 'intl/crowdin_translation_download.py', api_key, core_name])"
)
workflow_config = workflow_config.replace(
"subprocess.run(['python3', 'intl/initial_sync.py', api_key, core_name])\n",
""
)
with open('intl/translation_workflow.py', 'w') as workflow:
workflow.write(workflow_config)
except Exception as e:
# Try really hard to reset Crowdin API Key
with open(YAML_PATH, 'r') as crowdin_config_file:
crowdin_config = crowdin_config_file.read()
crowdin_config = re.sub(r'"api_token": ".*?"',
'"api_token": "_secret_"',
crowdin_config, 1)
crowdin_config = re.sub(r'"dest": "/.*?/%original_file_name%",',
'"dest": "/_core_name_/%original_file_name%",'
, crowdin_config, 1)
with open(YAML_PATH, 'w') as crowdin_config_file:
crowdin_config_file.write(crowdin_config)
raise e

View File

@ -0,0 +1,16 @@
#!/usr/bin/env python3
import sys
import subprocess
try:
api_key = sys.argv[1]
core_name = sys.argv[2]
dir_path = sys.argv[3]
except IndexError as e:
print('Please provide path to libretro_core_options.h, Crowdin API Token and core name!')
raise e
subprocess.run(['python3', 'intl/core_option_translation.py', dir_path])
subprocess.run(['python3', 'intl/initial_sync.py', api_key, core_name])
subprocess.run(['python3', 'intl/crowdin_translate.py', dir_path])

View File

@ -1,459 +0,0 @@
#!/usr/bin/env python3
"""Core options v1 to v2 converter
Just run this script as follows, to convert 'libretro_core_options.h' & 'Libretro_coreoptions_intl.h' to v2:
python3 "/path/to/v1_to_v2_converter.py" "/path/to/where/libretro_core_options.h & Libretro_coreoptions_intl.h/are"
The original files will be preserved as *.v1
"""
import core_option_regex as cor
import os
import sys
def create_v2_code_file(struct_text, file_name):
def replace_option(option_match):
_offset = option_match.start(0)
if option_match.group(3):
res = option_match.group(0)[:option_match.end(2) - _offset] + ',\n NULL' + \
option_match.group(0)[option_match.end(2) - _offset:option_match.end(3) - _offset] + \
'NULL,\n NULL,\n ' + option_match.group(0)[option_match.end(3) - _offset:]
else:
return option_match.group(0)
return res
comment_v1 = '/*\n' \
' ********************************\n' \
' * VERSION: 1.3\n' \
' ********************************\n' \
' *\n' \
' * - 1.3: Move translations to libretro_core_options_intl.h\n' \
' * - libretro_core_options_intl.h includes BOM and utf-8\n' \
' * fix for MSVC 2010-2013\n' \
' * - Added HAVE_NO_LANGEXTRA flag to disable translations\n' \
' * on platforms/compilers without BOM support\n' \
' * - 1.2: Use core options v1 interface when\n' \
' * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1\n' \
' * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)\n' \
' * - 1.1: Support generation of core options v0 retro_core_option_value\n' \
' * arrays containing options with a single value\n' \
' * - 1.0: First commit\n' \
'*/\n'
comment_v2 = '/*\n' \
' ********************************\n' \
' * VERSION: 2.0\n' \
' ********************************\n' \
' *\n' \
' * - 2.0: Add support for core options v2 interface\n' \
' * - 1.3: Move translations to libretro_core_options_intl.h\n' \
' * - libretro_core_options_intl.h includes BOM and utf-8\n' \
' * fix for MSVC 2010-2013\n' \
' * - Added HAVE_NO_LANGEXTRA flag to disable translations\n' \
' * on platforms/compilers without BOM support\n' \
' * - 1.2: Use core options v1 interface when\n' \
' * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1\n' \
' * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1)\n' \
' * - 1.1: Support generation of core options v0 retro_core_option_value\n' \
' * arrays containing options with a single value\n' \
' * - 1.0: First commit\n' \
'*/\n'
p_intl = cor.p_intl
p_set = cor.p_set
new_set = 'static INLINE void libretro_set_core_options(retro_environment_t environ_cb,\n' \
' bool *categories_supported)\n' \
'{\n' \
' unsigned version = 0;\n' \
'#ifndef HAVE_NO_LANGEXTRA\n' \
' unsigned language = 0;\n' \
'#endif\n' \
'\n' \
' if (!environ_cb || !categories_supported)\n' \
' return;\n' \
'\n' \
' *categories_supported = false;\n' \
'\n' \
' if (!environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version))\n' \
' version = 0;\n' \
'\n' \
' if (version >= 2)\n' \
' {\n' \
'#ifndef HAVE_NO_LANGEXTRA\n' \
' struct retro_core_options_v2_intl core_options_intl;\n' \
'\n' \
' core_options_intl.us = &options_us;\n' \
' core_options_intl.local = NULL;\n' \
'\n' \
' if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&\n' \
' (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))\n' \
' core_options_intl.local = options_intl[language];\n' \
'\n' \
' *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL,\n' \
' &core_options_intl);\n' \
'#else\n' \
' *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2,\n' \
' &options_us);\n' \
'#endif\n' \
' }\n' \
' else\n' \
' {\n' \
' size_t i, j;\n' \
' size_t option_index = 0;\n' \
' size_t num_options = 0;\n' \
' struct retro_core_option_definition\n' \
' *option_v1_defs_us = NULL;\n' \
'#ifndef HAVE_NO_LANGEXTRA\n' \
' size_t num_options_intl = 0;\n' \
' struct retro_core_option_v2_definition\n' \
' *option_defs_intl = NULL;\n' \
' struct retro_core_option_definition\n' \
' *option_v1_defs_intl = NULL;\n' \
' struct retro_core_options_intl\n' \
' core_options_v1_intl;\n' \
'#endif\n' \
' struct retro_variable *variables = NULL;\n' \
' char **values_buf = NULL;\n' \
'\n' \
' /* Determine total number of options */\n' \
' while (true)\n' \
' {\n' \
' if (option_defs_us[num_options].key)\n' \
' num_options++;\n' \
' else\n' \
' break;\n' \
' }\n' \
'\n' \
' if (version >= 1)\n' \
' {\n' \
' /* Allocate US array */\n' \
' option_v1_defs_us = (struct retro_core_option_definition *)\n' \
' calloc(num_options + 1, sizeof(struct retro_core_option_definition));\n' \
'\n' \
' /* Copy parameters from option_defs_us array */\n' \
' for (i = 0; i < num_options; i++)\n' \
' {\n' \
' struct retro_core_option_v2_definition *option_def_us = &option_defs_us[i];\n' \
' struct retro_core_option_value *option_values = option_def_us->values;\n' \
' struct retro_core_option_definition *option_v1_def_us = &option_v1_defs_us[i];\n' \
' struct retro_core_option_value *option_v1_values = option_v1_def_us->values;\n' \
'\n' \
' option_v1_def_us->key = option_def_us->key;\n' \
' option_v1_def_us->desc = option_def_us->desc;\n' \
' option_v1_def_us->info = option_def_us->info;\n' \
' option_v1_def_us->default_value = option_def_us->default_value;\n' \
'\n' \
' /* Values must be copied individually... */\n' \
' while (option_values->value)\n' \
' {\n' \
' option_v1_values->value = option_values->value;\n' \
' option_v1_values->label = option_values->label;\n' \
'\n' \
' option_values++;\n' \
' option_v1_values++;\n' \
' }\n' \
' }\n' \
'\n' \
'#ifndef HAVE_NO_LANGEXTRA\n' \
' if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&\n' \
' (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH) &&\n' \
' options_intl[language])\n' \
' option_defs_intl = options_intl[language]->definitions;\n' \
'\n' \
' if (option_defs_intl)\n' \
' {\n' \
' /* Determine number of intl options */\n' \
' while (true)\n' \
' {\n' \
' if (option_defs_intl[num_options_intl].key)\n' \
' num_options_intl++;\n' \
' else\n' \
' break;\n' \
' }\n' \
'\n' \
' /* Allocate intl array */\n' \
' option_v1_defs_intl = (struct retro_core_option_definition *)\n' \
' calloc(num_options_intl + 1, sizeof(struct retro_core_option_definition));\n' \
'\n' \
' /* Copy parameters from option_defs_intl array */\n' \
' for (i = 0; i < num_options_intl; i++)\n' \
' {\n' \
' struct retro_core_option_v2_definition *option_def_intl = &option_defs_intl[i];\n' \
' struct retro_core_option_value *option_values = option_def_intl->values;\n' \
' struct retro_core_option_definition *option_v1_def_intl = &option_v1_defs_intl[i];\n' \
' struct retro_core_option_value *option_v1_values = option_v1_def_intl->values;\n' \
'\n' \
' option_v1_def_intl->key = option_def_intl->key;\n' \
' option_v1_def_intl->desc = option_def_intl->desc;\n' \
' option_v1_def_intl->info = option_def_intl->info;\n' \
' option_v1_def_intl->default_value = option_def_intl->default_value;\n' \
'\n' \
' /* Values must be copied individually... */\n' \
' while (option_values->value)\n' \
' {\n' \
' option_v1_values->value = option_values->value;\n' \
' option_v1_values->label = option_values->label;\n' \
'\n' \
' option_values++;\n' \
' option_v1_values++;\n' \
' }\n' \
' }\n' \
' }\n' \
'\n' \
' core_options_v1_intl.us = option_v1_defs_us;\n' \
' core_options_v1_intl.local = option_v1_defs_intl;\n' \
'\n' \
' environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_v1_intl);\n' \
'#else\n' \
' environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, option_v1_defs_us);\n' \
'#endif\n' \
' }\n' \
' else\n' \
' {\n' \
' /* Allocate arrays */\n' \
' variables = (struct retro_variable *)calloc(num_options + 1,\n' \
' sizeof(struct retro_variable));\n' \
' values_buf = (char **)calloc(num_options, sizeof(char *));\n' \
'\n' \
' if (!variables || !values_buf)\n' \
' goto error;\n' \
'\n' \
' /* Copy parameters from option_defs_us array */\n' \
' for (i = 0; i < num_options; i++)\n' \
' {\n' \
' const char *key = option_defs_us[i].key;\n' \
' const char *desc = option_defs_us[i].desc;\n' \
' const char *default_value = option_defs_us[i].default_value;\n' \
' struct retro_core_option_value *values = option_defs_us[i].values;\n' \
' size_t buf_len = 3;\n' \
' size_t default_index = 0;\n' \
'\n' \
' values_buf[i] = NULL;\n' \
'\n' \
' if (desc)\n' \
' {\n' \
' size_t num_values = 0;\n' \
'\n' \
' /* Determine number of values */\n' \
' while (true)\n' \
' {\n' \
' if (values[num_values].value)\n' \
' {\n' \
' /* Check if this is the default value */\n' \
' if (default_value)\n' \
' if (strcmp(values[num_values].value, default_value) == 0)\n' \
' default_index = num_values;\n' \
'\n' \
' buf_len += strlen(values[num_values].value);\n' \
' num_values++;\n' \
' }\n' \
' else\n' \
' break;\n' \
' }\n' \
'\n' \
' /* Build values string */\n' \
' if (num_values > 0)\n' \
' {\n' \
' buf_len += num_values - 1;\n' \
' buf_len += strlen(desc);\n' \
'\n' \
' values_buf[i] = (char *)calloc(buf_len, sizeof(char));\n' \
' if (!values_buf[i])\n' \
' goto error;\n' \
'\n' \
' strcpy(values_buf[i], desc);\n' \
' strcat(values_buf[i], "; ");\n' \
'\n' \
' /* Default value goes first */\n' \
' strcat(values_buf[i], values[default_index].value);\n' \
'\n' \
' /* Add remaining values */\n' \
' for (j = 0; j < num_values; j++)\n' \
' {\n' \
' if (j != default_index)\n' \
' {\n' \
' strcat(values_buf[i], "|");\n' \
' strcat(values_buf[i], values[j].value);\n' \
' }\n' \
' }\n' \
' }\n' \
' }\n' \
'\n' \
' variables[option_index].key = key;\n' \
' variables[option_index].value = values_buf[i];\n' \
' option_index++;\n' \
' }\n' \
'\n' \
' /* Set variables */\n' \
' environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);\n' \
' }\n' \
'\n' \
'error:\n' \
' /* Clean up */\n' \
'\n' \
' if (option_v1_defs_us)\n' \
' {\n' \
' free(option_v1_defs_us);\n' \
' option_v1_defs_us = NULL;\n' \
' }\n' \
'\n' \
'#ifndef HAVE_NO_LANGEXTRA\n' \
' if (option_v1_defs_intl)\n' \
' {\n' \
' free(option_v1_defs_intl);\n' \
' option_v1_defs_intl = NULL;\n' \
' }\n' \
'#endif\n' \
'\n' \
' if (values_buf)\n' \
' {\n' \
' for (i = 0; i < num_options; i++)\n' \
' {\n' \
' if (values_buf[i])\n' \
' {\n' \
' free(values_buf[i]);\n' \
' values_buf[i] = NULL;\n' \
' }\n' \
' }\n' \
'\n' \
' free(values_buf);\n' \
' values_buf = NULL;\n' \
' }\n' \
'\n' \
' if (variables)\n' \
' {\n' \
' free(variables);\n' \
' variables = NULL;\n' \
' }\n' \
' }\n' \
'}\n' \
'\n' \
'#ifdef __cplusplus\n' \
'}\n' \
'#endif'
struct_groups = cor.p_struct.finditer(struct_text)
out_text = struct_text
for construct in struct_groups:
repl_text = ''
declaration = construct.group(1)
struct_match = cor.p_type_name.search(declaration)
if struct_match:
if struct_match.group(3):
struct_type_name_lang = struct_match.group(1, 2, 3)
declaration_end = declaration[struct_match.end(1):]
elif struct_match.group(4):
struct_type_name_lang = struct_match.group(1, 2, 4)
declaration_end = declaration[struct_match.end(1):]
else:
struct_type_name_lang = sum((struct_match.group(1, 2), ('_us',)), ())
declaration_end = f'{declaration[struct_match.end(1):struct_match.end(2)]}_us' \
f'{declaration[struct_match.end(2):]}'
else:
return -1
if 'retro_core_option_definition' == struct_type_name_lang[0]:
import shutil
shutil.copy(file_name, file_name + '.v1')
new_declaration = f'\nstruct retro_core_option_v2_category option_cats{struct_type_name_lang[2]}[] = ' \
'{\n { NULL, NULL, NULL },\n' \
'};\n\n' \
+ declaration[:struct_match.start(1)] + \
'retro_core_option_v2_definition' \
+ declaration_end
offset = construct.start(0)
repl_text = repl_text + cor.re.sub(cor.re.escape(declaration), new_declaration,
construct.group(0)[:construct.start(2) - offset])
content = construct.group(2)
new_content = cor.p_option.sub(replace_option, content)
repl_text = repl_text + new_content + cor.re.sub(r'{\s*NULL,\s*NULL,\s*NULL,\s*{\{0}},\s*NULL\s*},\s*};',
'{ NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL },\n};'
'\n\nstruct retro_core_options_v2 options' +
struct_type_name_lang[2] + ' = {\n'
f' option_cats{struct_type_name_lang[2]},\n'
f' option_defs{struct_type_name_lang[2]}\n'
'};',
construct.group(0)[construct.end(2) - offset:])
out_text = cor.re.sub(cor.re.escape(construct.group(0)), repl_text, out_text)
else:
return -2
with open(file_name, 'w', encoding='utf-8') as code_file:
out_text = cor.re.sub(cor.re.escape(comment_v1), comment_v2, out_text)
intl = p_intl.search(out_text)
if intl:
new_intl = out_text[:intl.start(1)] \
+ 'struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST]' \
+ out_text[intl.end(1):intl.start(2)] \
+ '&options_us, /* RETRO_LANGUAGE_ENGLISH */' \
' &options_ja, /* RETRO_LANGUAGE_JAPANESE */' \
' &options_fr, /* RETRO_LANGUAGE_FRENCH */' \
' &options_es, /* RETRO_LANGUAGE_SPANISH */' \
' &options_de, /* RETRO_LANGUAGE_GERMAN */' \
' &options_it, /* RETRO_LANGUAGE_ITALIAN */' \
' &options_nl, /* RETRO_LANGUAGE_DUTCH */' \
' &options_pt_br, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */' \
' &options_pt_pt, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */' \
' &options_ru, /* RETRO_LANGUAGE_RUSSIAN */' \
' &options_ko, /* RETRO_LANGUAGE_KOREAN */' \
' &options_cht, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */' \
' &options_chs, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */' \
' &options_eo, /* RETRO_LANGUAGE_ESPERANTO */' \
' &options_pl, /* RETRO_LANGUAGE_POLISH */' \
' &options_vn, /* RETRO_LANGUAGE_VIETNAMESE */' \
' &options_ar, /* RETRO_LANGUAGE_ARABIC */' \
' &options_el, /* RETRO_LANGUAGE_GREEK */' \
' &options_tr, /* RETRO_LANGUAGE_TURKISH */' \
' &options_sv, /* RETRO_LANGUAGE_SLOVAK */' \
' &options_fa, /* RETRO_LANGUAGE_PERSIAN */' \
' &options_he, /* RETRO_LANGUAGE_HEBREW */' \
' &options_ast, /* RETRO_LANGUAGE_ASTURIAN */' \
' &options_fi, /* RETRO_LANGUAGE_FINNISH */' \
+ out_text[intl.end(2):]
out_text = p_set.sub(new_set, new_intl)
else:
out_text = p_set.sub(new_set, out_text)
code_file.write(out_text)
return 1
# -------------------- MAIN -------------------- #
if __name__ == '__main__':
try:
if os.path.isfile(sys.argv[1]):
_temp = os.path.dirname(sys.argv[1])
else:
_temp = sys.argv[1]
while _temp.endswith('/') or _temp.endswith('\\'):
_temp = _temp[:-1]
DIR_PATH = _temp
except IndexError:
DIR_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
print("No path provided, assuming parent directory:\n" + DIR_PATH)
H_FILE_PATH = os.path.join(DIR_PATH, 'libretro_core_options.h')
INTL_FILE_PATH = os.path.join(DIR_PATH, 'libretro_core_options_intl.h')
for file in (H_FILE_PATH, INTL_FILE_PATH):
if os.path.isfile(file):
with open(file, 'r+', encoding='utf-8') as h_file:
text = h_file.read()
try:
test = create_v2_code_file(text, file)
except Exception as e:
print(e)
test = -1
if -1 > test:
print('Your file looks like it already is v2? (' + file + ')')
continue
if 0 > test:
print('An error occured! Please make sure to use the complete v1 struct! (' + file + ')')
continue
else:
print(file + ' not found.')

View File

@ -989,25 +989,30 @@ struct retro_core_options_v2 options_us = {
#ifndef HAVE_NO_LANGEXTRA
struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = {
&options_us, /* RETRO_LANGUAGE_ENGLISH */
NULL, /* RETRO_LANGUAGE_JAPANESE */
NULL, /* RETRO_LANGUAGE_FRENCH */
NULL, /* RETRO_LANGUAGE_SPANISH */
NULL, /* RETRO_LANGUAGE_GERMAN */
NULL, /* RETRO_LANGUAGE_ITALIAN */
NULL, /* RETRO_LANGUAGE_DUTCH */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
NULL, /* RETRO_LANGUAGE_RUSSIAN */
NULL, /* RETRO_LANGUAGE_KOREAN */
NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
NULL, /* RETRO_LANGUAGE_ESPERANTO */
NULL, /* RETRO_LANGUAGE_POLISH */
NULL, /* RETRO_LANGUAGE_VIETNAMESE */
NULL, /* RETRO_LANGUAGE_ARABIC */
NULL, /* RETRO_LANGUAGE_GREEK */
NULL, /* RETRO_LANGUAGE_TURKISH */
&options_us, /* RETRO_LANGUAGE_ENGLISH */
&options_ja, /* RETRO_LANGUAGE_JAPANESE */
&options_fr, /* RETRO_LANGUAGE_FRENCH */
&options_es, /* RETRO_LANGUAGE_SPANISH */
&options_de, /* RETRO_LANGUAGE_GERMAN */
&options_it, /* RETRO_LANGUAGE_ITALIAN */
&options_nl, /* RETRO_LANGUAGE_DUTCH */
&options_pt_br, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
&options_pt_pt, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
&options_ru, /* RETRO_LANGUAGE_RUSSIAN */
&options_ko, /* RETRO_LANGUAGE_KOREAN */
&options_cht, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
&options_chs, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
&options_eo, /* RETRO_LANGUAGE_ESPERANTO */
&options_pl, /* RETRO_LANGUAGE_POLISH */
&options_vn, /* RETRO_LANGUAGE_VIETNAMESE */
&options_ar, /* RETRO_LANGUAGE_ARABIC */
&options_el, /* RETRO_LANGUAGE_GREEK */
&options_tr, /* RETRO_LANGUAGE_TURKISH */
&options_sk, /* RETRO_LANGUAGE_SLOVAK */
&options_fa, /* RETRO_LANGUAGE_PERSIAN */
&options_he, /* RETRO_LANGUAGE_HEBREW */
&options_ast, /* RETRO_LANGUAGE_ASTURIAN */
&options_fi, /* RETRO_LANGUAGE_FINNISH */
};
#endif