From f4c187e980a13e2b00e199eadcbd0bd1b945a10e Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 9 Jan 2017 16:46:35 -0600 Subject: [PATCH 01/90] - port slock and scond fixes from desmume - make sthread_isself return false for null test thread full disclosure: this work was done months ago. I can't be 100% sure I've merged it correctly with recent rthreads.c changes --- libretro-common/rthreads/rthreads.c | 146 ++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 19 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 1744705642..8048438079 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -87,7 +87,32 @@ struct slock struct scond { #ifdef USE_WIN32_THREADS - HANDLE event; + + /* The syntax we'll use is mind-bending unless we use a struct. Plus, we might want to store more info later */ + /* This will be used as a linked list immplementing a queue of waiting threads */ + struct QueueEntry + { + struct QueueEntry* next; + }; + + /* With this implementation of scond, we don't have any way of waking (or even identifying) specific threads */ + /* But we need to wake them in the order indicated by the queue. */ + /* This potato token will get get passed around every waiter. The bearer can test whether he's next, and hold onto the potato if he is. */ + /* When he's done he can then put it back into play to progress the queue further */ + HANDLE hot_potato; + + /* The primary signalled event. Hot potatoes are passed until this is set. */ + HANDLE event; + + /* the head of the queue; NULL if queue is empty */ + struct QueueEntry* head; + + /* equivalent to the queue length */ + int waiters; + + /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet */ + int wakens; + #else pthread_cond_t cond; #endif @@ -211,6 +236,9 @@ void sthread_join(sthread_t *thread) */ bool sthread_isself(sthread_t *thread) { + /* This thread can't possibly be a null thread */ + if (!thread) return false; + #ifdef USE_WIN32_THREADS return GetCurrentThread() == thread->thread; #else @@ -228,23 +256,25 @@ bool sthread_isself(sthread_t *thread) **/ slock_t *slock_new(void) { + bool mutex_created = false; slock_t *lock = (slock_t*)calloc(1, sizeof(*lock)); if (!lock) return NULL; #ifdef USE_WIN32_THREADS lock->lock = CreateMutex(NULL, FALSE, NULL); - if (!lock->lock) - goto error; + mutex_created = !!lock->lock; #else - if ((pthread_mutex_init(&lock->lock, NULL) < 0)) - goto error; + mutex_created = (pthread_mutex_init(&lock->lock, NULL) == 0); #endif + if (!mutex_created) + goto error; + return lock; error: - slock_free(lock); + free(lock); return NULL; } @@ -314,21 +344,33 @@ void slock_unlock(slock_t *lock) **/ scond_t *scond_new(void) { - bool event_created = false; scond_t *cond = (scond_t*)calloc(1, sizeof(*cond)); if (!cond) return NULL; #ifdef USE_WIN32_THREADS - cond->event = CreateEvent(NULL, FALSE, FALSE, NULL); - event_created = !!cond->event; -#else - event_created = (pthread_cond_init(&cond->cond, NULL) == 0); -#endif - - if (!event_created) + /* This is very complex because recreating condition variable semantics with win32 parts is not easy */ + /* The main problem is that a condition variable can be used to wake up a thread, but only if the thread is already waiting; */ + /* whereas a win32 event will 'wake up' a thread in advance (the event will be set in advance, so a 'waiter' wont even have to wait on it) */ + /* So at the very least, we need to do something clever. But there's bigger problems. */ + /* We don't even have a straightforward way in win32 to satisfy pthread_cond_wait's atomicity requirement. The bulk of this algorithm is solving that. */ + /* Note: We might could simplify this using vista+ condition variables, but we wanted an XP compatible solution. */ + cond->event = CreateEvent(NULL, FALSE, FALSE, NULL); + if(!cond->event) goto error; + cond->hot_potato = CreateEvent(NULL, FALSE, FALSE, NULL); + if(!cond->hot_potato) + { + CloseHandle(cond->event); goto error; + } + cond->waiters = cond->wakens = 0; + cond->head = NULL; + +#else + if(pthread_cond_init(&cond->cond, NULL) != 0) + goto error; +#endif return cond; @@ -350,6 +392,7 @@ void scond_free(scond_t *cond) #ifdef USE_WIN32_THREADS CloseHandle(cond->event); + CloseHandle(cond->hot_potato); #else pthread_cond_destroy(&cond->cond); #endif @@ -366,10 +409,56 @@ void scond_free(scond_t *cond) void scond_wait(scond_t *cond, slock_t *lock) { #ifdef USE_WIN32_THREADS - WaitForSingleObject(cond->event, 0); + + /* add ourselves to a queue of waiting threads */ + struct QueueEntry myentry; + struct QueueEntry** ptr = &cond->head; + while(*ptr) /* walk to the end of the linked list */ + ptr = &((*ptr)->next); + *ptr = &myentry; + myentry.next = NULL; + cond->waiters++; + + /* now the conceptual lock release and condition block are supposed to be atomic. */ + /* we can't do that in windows, but we can simulate the effects by using the queue, by the following analysis: */ + /* What happens if they aren't atomic? */ + /* 1. a signaller can rush in and signal, expecting a waiter to get it; but the waiter wouldn't, because he isn't blocked yet */ + /* solution: win32 events make this easy. the event will sit there enabled */ + /* 2. a signaller can rush in and signal, and then turn right around and wait */ + /* solution: the signaller will get queued behind the waiter, who's enqueued before he releases the mutex */ + + /* It's my turn if I'm the head of the queue. Check to see if it's my turn. */ + while (cond->head != &myentry) + { + /* As long as someone is even going to be able to wake up when they receive the potato, keep it going round */ + if (cond->wakens > 0) + SetEvent(cond->hot_potato); + + /* Wait to catch the hot potato before checking for my turn again */ + SignalObjectAndWait(lock->lock, cond->hot_potato, INFINITE, FALSE); + slock_lock(lock); + } + + /* It's my turn now -- I hold the potato */ SignalObjectAndWait(lock->lock, cond->event, INFINITE, FALSE); slock_lock(lock); + + /* Remove ourselves from the queue */ + cond->head = myentry.next; + cond->waiters--; + + /* If any other wakenings are pending, go ahead and set it up */ + /* There may actually be no waiters. That's OK. The first waiter will come in, find it's his turn, and immediately get the signaled event */ + cond->wakens--; + if(cond->wakens>0) + { + SetEvent(cond->event); + + /* Progress the queue: Put the hot potato back into play. It'll be tossed around until next in line gets it */ + SetEvent(cond->hot_potato); + } + #else pthread_cond_wait(&cond->cond, &lock->lock); #endif @@ -385,9 +474,17 @@ void scond_wait(scond_t *cond, slock_t *lock) int scond_broadcast(scond_t *cond) { #ifdef USE_WIN32_THREADS - /* FIXME _- check how this function should differ - * from scond_signal implementation. */ - SetEvent(cond->event); + + /* remember: we currently have mutex */ + if(cond->waiters == 0) return 0; + + /* awaken everything which is currently queued up */ + if(cond->wakens == 0) SetEvent(cond->event); + cond->wakens = cond->waiters; + + /* Since there is now at least one pending waken, the potato must be in play */ + SetEvent(cond->hot_potato); + return 0; #else return pthread_cond_broadcast(&cond->cond); @@ -404,7 +501,17 @@ int scond_broadcast(scond_t *cond) void scond_signal(scond_t *cond) { #ifdef USE_WIN32_THREADS - SetEvent(cond->event); + + /* remember: we currently have mutex */ + if(cond->waiters == 0) return; + + /* wake up the next thing in the queue */ + if(cond->wakens == 0) SetEvent(cond->event); + cond->wakens++; + + /* Since there is now at least one pending waken, the potato must be in play */ + SetEvent(cond->hot_potato); + #else pthread_cond_signal(&cond->cond); #endif @@ -427,6 +534,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) #ifdef USE_WIN32_THREADS DWORD ret; + /* TODO: this is woefully inadequate. It needs to be solved with the newer approach used above */ WaitForSingleObject(cond->event, 0); ret = SignalObjectAndWait(lock->lock, cond->event, (DWORD)(timeout_us) / 1000, FALSE); From 10157c58319ddade5d1209edcf292d96c9e0adc6 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 21 Jan 2017 16:49:10 -0600 Subject: [PATCH 02/90] apply feedback re: PR #4392 --- libretro-common/rthreads/rthreads.c | 58 ++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 8048438079..e9a12a8b14 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -92,7 +92,7 @@ struct scond /* This will be used as a linked list immplementing a queue of waiting threads */ struct QueueEntry { - struct QueueEntry* next; + struct QueueEntry *next; }; /* With this implementation of scond, we don't have any way of waking (or even identifying) specific threads */ @@ -102,16 +102,16 @@ struct scond HANDLE hot_potato; /* The primary signalled event. Hot potatoes are passed until this is set. */ - HANDLE event; + HANDLE event; /* the head of the queue; NULL if queue is empty */ - struct QueueEntry* head; + struct QueueEntry *head; /* equivalent to the queue length */ - int waiters; + int waiters; /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet */ - int wakens; + int wakens; #else pthread_cond_t cond; @@ -189,7 +189,7 @@ error: * @thread : pointer to thread object * * Detach a thread. When a detached thread terminates, its - * resource sare automatically released back to the system + * resources are automatically released back to the system * without the need for another thread to join with the * terminated thread. * @@ -351,15 +351,17 @@ scond_t *scond_new(void) #ifdef USE_WIN32_THREADS /* This is very complex because recreating condition variable semantics with win32 parts is not easy */ - /* The main problem is that a condition variable can be used to wake up a thread, but only if the thread is already waiting; */ - /* whereas a win32 event will 'wake up' a thread in advance (the event will be set in advance, so a 'waiter' wont even have to wait on it) */ + /* The main problem is that a condition variable can't be used to "pre-wake" a thread (it will get wakened only after it's waited) */ + /* whereas a win32 event can pre-wake a thread (the event will be set in advance, so a 'waiter' won't even have to wait on it) */ + /* Keep in mind a condition variable can apparently pre-wake a thread, insofar as spurious wakeups are always possible, */ + /* but nobody will be expecting this and it does not need to be simulated. */ /* So at the very least, we need to do something clever. But there's bigger problems. */ /* We don't even have a straightforward way in win32 to satisfy pthread_cond_wait's atomicity requirement. The bulk of this algorithm is solving that. */ /* Note: We might could simplify this using vista+ condition variables, but we wanted an XP compatible solution. */ cond->event = CreateEvent(NULL, FALSE, FALSE, NULL); - if(!cond->event) goto error; + if (!cond->event) goto error; cond->hot_potato = CreateEvent(NULL, FALSE, FALSE, NULL); - if(!cond->hot_potato) + if (!cond->hot_potato) { CloseHandle(cond->event); goto error; @@ -410,9 +412,11 @@ void scond_wait(scond_t *cond, slock_t *lock) { #ifdef USE_WIN32_THREADS + /* Reminder: `lock` is held before this is called */ + /* add ourselves to a queue of waiting threads */ struct QueueEntry myentry; - struct QueueEntry** ptr = &cond->head; + struct QueueEntry **ptr = &cond->head; while(*ptr) /* walk to the end of the linked list */ ptr = &((*ptr)->next); *ptr = &myentry; @@ -431,18 +435,36 @@ void scond_wait(scond_t *cond, slock_t *lock) /* It's my turn if I'm the head of the queue. Check to see if it's my turn. */ while (cond->head != &myentry) { + /* It isn't my turn: */ + /* As long as someone is even going to be able to wake up when they receive the potato, keep it going round */ if (cond->wakens > 0) SetEvent(cond->hot_potato); - /* Wait to catch the hot potato before checking for my turn again */ - SignalObjectAndWait(lock->lock, cond->hot_potato, INFINITE, FALSE); - slock_lock(lock); + /* Let someone else go */ + ReleaseMutex(lock->lock); + + /* Wait a while to catch the hot potato.. someone else should get a chance to go */ + /* After all, it isn't my turn (and it must be someone else's */ + Sleep(0); + WaitForSingleObject(cond->hot_potato, INFINITE); + + /* I should come out of here with the main lock taken */ + WaitForSingleObject(lock->lock, INFINITE); } - + /* It's my turn now -- I hold the potato */ - SignalObjectAndWait(lock->lock, cond->event, INFINITE, FALSE); - slock_lock(lock); + + /* I still have the main lock, in any case */ + /* I need to release it so that someone can set the event */ + ReleaseMutex(lock->lock); + + /* Wait for someone to actually signal this condition */ + /* We're the only waiter waiting on the event right now -- everyone else is waiting on something different */ + WaitForSingleObject(cond->event, INFINITE); + + /* Take the main lock so we can do work. Nobody else waits on this lock for very long, so even though it's GO TIME we won't have to wait long */ + WaitForSingleObject(lock->lock, INFINITE); /* Remove ourselves from the queue */ cond->head = myentry.next; @@ -451,7 +473,7 @@ void scond_wait(scond_t *cond, slock_t *lock) /* If any other wakenings are pending, go ahead and set it up */ /* There may actually be no waiters. That's OK. The first waiter will come in, find it's his turn, and immediately get the signaled event */ cond->wakens--; - if(cond->wakens>0) + if (cond->wakens > 0) { SetEvent(cond->event); From 3e8e02c9538be27330766bb05b08aa27ef932012 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 21 Jan 2017 17:09:38 -0600 Subject: [PATCH 03/90] change the main lock mutex to a critical section, and update copyrights year --- libretro-common/rthreads/rthreads.c | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index e9a12a8b14..fc6f14743c 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2016 The RetroArch team +/* Copyright (C) 2010-2017 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (rthreads.c). @@ -78,7 +78,7 @@ struct sthread struct slock { #ifdef USE_WIN32_THREADS - HANDLE lock; + CRITICAL_SECTION lock; #else pthread_mutex_t lock; #endif @@ -262,10 +262,10 @@ slock_t *slock_new(void) return NULL; #ifdef USE_WIN32_THREADS - lock->lock = CreateMutex(NULL, FALSE, NULL); - mutex_created = !!lock->lock; + InitializeCriticalSection(&lock->lock); + mutex_created = true; #else - mutex_created = (pthread_mutex_init(&lock->lock, NULL) == 0); + mutex_created = (pthread_mutex_init(&lock->lock, NULL) == 0); #endif if (!mutex_created) @@ -290,7 +290,7 @@ void slock_free(slock_t *lock) return; #ifdef USE_WIN32_THREADS - CloseHandle(lock->lock); + DeleteCriticalSection(&lock->lock); #else pthread_mutex_destroy(&lock->lock); #endif @@ -310,7 +310,7 @@ void slock_lock(slock_t *lock) if (!lock) return; #ifdef USE_WIN32_THREADS - WaitForSingleObject(lock->lock, INFINITE); + EnterCriticalSection(&lock->lock); #else pthread_mutex_lock(&lock->lock); #endif @@ -327,7 +327,7 @@ void slock_unlock(slock_t *lock) if (!lock) return; #ifdef USE_WIN32_THREADS - ReleaseMutex(lock->lock); + LeaveCriticalSection(&lock->lock); #else pthread_mutex_unlock(&lock->lock); #endif @@ -442,7 +442,7 @@ void scond_wait(scond_t *cond, slock_t *lock) SetEvent(cond->hot_potato); /* Let someone else go */ - ReleaseMutex(lock->lock); + LeaveCriticalSection(&lock->lock); /* Wait a while to catch the hot potato.. someone else should get a chance to go */ /* After all, it isn't my turn (and it must be someone else's */ @@ -450,21 +450,21 @@ void scond_wait(scond_t *cond, slock_t *lock) WaitForSingleObject(cond->hot_potato, INFINITE); /* I should come out of here with the main lock taken */ - WaitForSingleObject(lock->lock, INFINITE); + EnterCriticalSection(&lock->lock); } /* It's my turn now -- I hold the potato */ /* I still have the main lock, in any case */ /* I need to release it so that someone can set the event */ - ReleaseMutex(lock->lock); + LeaveCriticalSection(&lock->lock); /* Wait for someone to actually signal this condition */ /* We're the only waiter waiting on the event right now -- everyone else is waiting on something different */ WaitForSingleObject(cond->event, INFINITE); /* Take the main lock so we can do work. Nobody else waits on this lock for very long, so even though it's GO TIME we won't have to wait long */ - WaitForSingleObject(lock->lock, INFINITE); + EnterCriticalSection(&lock->lock); /* Remove ourselves from the queue */ cond->head = myentry.next; @@ -558,10 +558,10 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) /* TODO: this is woefully inadequate. It needs to be solved with the newer approach used above */ WaitForSingleObject(cond->event, 0); - ret = SignalObjectAndWait(lock->lock, cond->event, - (DWORD)(timeout_us) / 1000, FALSE); + LeaveCriticalSection(&lock->lock); + ret = WaitForSingleObject(cond->event,(DWORD)(timeout_us) / 1000); - slock_lock(lock); + EnterCriticalSection(&lock->lock); return ret == WAIT_OBJECT_0; #else int ret; From 168de31fb9d5d4c3caba6099a5986f64f316e359 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 21 Jan 2017 22:44:31 -0600 Subject: [PATCH 04/90] make scond_signal slightly more pthreads compliant (and other tidying). re: PR #4392 --- libretro-common/rthreads/rthreads.c | 47 +++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index fc6f14743c..e6ae676625 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -113,6 +113,9 @@ struct scond /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet */ int wakens; + /* used to control access to this scond, in case the user fails */ + CRITICAL_SECTION cs; + #else pthread_cond_t cond; #endif @@ -350,11 +353,14 @@ scond_t *scond_new(void) return NULL; #ifdef USE_WIN32_THREADS + /* This is very complex because recreating condition variable semantics with win32 parts is not easy */ /* The main problem is that a condition variable can't be used to "pre-wake" a thread (it will get wakened only after it's waited) */ /* whereas a win32 event can pre-wake a thread (the event will be set in advance, so a 'waiter' won't even have to wait on it) */ /* Keep in mind a condition variable can apparently pre-wake a thread, insofar as spurious wakeups are always possible, */ /* but nobody will be expecting this and it does not need to be simulated. */ + /* Moreover, we won't be doing this, because it counts as a spurious wakeup -- someone else with a genuine claim must get wakened, in any case. + /* Therefore we choose to wake only one of the correct waiting threads. */ /* So at the very least, we need to do something clever. But there's bigger problems. */ /* We don't even have a straightforward way in win32 to satisfy pthread_cond_wait's atomicity requirement. The bulk of this algorithm is solving that. */ /* Note: We might could simplify this using vista+ condition variables, but we wanted an XP compatible solution. */ @@ -366,6 +372,8 @@ scond_t *scond_new(void) CloseHandle(cond->event); goto error; } + + InitializeCriticalSection(&cond->cs); cond->waiters = cond->wakens = 0; cond->head = NULL; @@ -395,6 +403,7 @@ void scond_free(scond_t *cond) #ifdef USE_WIN32_THREADS CloseHandle(cond->event); CloseHandle(cond->hot_potato); + DeleteCriticalSection(&cond->cs); #else pthread_cond_destroy(&cond->cond); #endif @@ -412,11 +421,15 @@ void scond_wait(scond_t *cond, slock_t *lock) { #ifdef USE_WIN32_THREADS - /* Reminder: `lock` is held before this is called */ + struct QueueEntry myentry; + struct QueueEntry **ptr; + + /* Reminder: `lock` is held before this is called. */ + /* however, someone else may have called scond_signal without the lock. soo... */ + EnterCriticalSection(&cond->cs); /* add ourselves to a queue of waiting threads */ - struct QueueEntry myentry; - struct QueueEntry **ptr = &cond->head; + ptr = &cond->head; while(*ptr) /* walk to the end of the linked list */ ptr = &((*ptr)->next); *ptr = &myentry; @@ -443,14 +456,16 @@ void scond_wait(scond_t *cond, slock_t *lock) /* Let someone else go */ LeaveCriticalSection(&lock->lock); + LeaveCriticalSection(&cond->cs); /* Wait a while to catch the hot potato.. someone else should get a chance to go */ - /* After all, it isn't my turn (and it must be someone else's */ + /* After all, it isn't my turn (and it must be someone else's) */ Sleep(0); WaitForSingleObject(cond->hot_potato, INFINITE); /* I should come out of here with the main lock taken */ EnterCriticalSection(&lock->lock); + EnterCriticalSection(&cond->cs); } /* It's my turn now -- I hold the potato */ @@ -458,6 +473,7 @@ void scond_wait(scond_t *cond, slock_t *lock) /* I still have the main lock, in any case */ /* I need to release it so that someone can set the event */ LeaveCriticalSection(&lock->lock); + LeaveCriticalSection(&cond->cs); /* Wait for someone to actually signal this condition */ /* We're the only waiter waiting on the event right now -- everyone else is waiting on something different */ @@ -465,6 +481,7 @@ void scond_wait(scond_t *cond, slock_t *lock) /* Take the main lock so we can do work. Nobody else waits on this lock for very long, so even though it's GO TIME we won't have to wait long */ EnterCriticalSection(&lock->lock); + EnterCriticalSection(&cond->cs); /* Remove ourselves from the queue */ cond->head = myentry.next; @@ -481,6 +498,8 @@ void scond_wait(scond_t *cond, slock_t *lock) SetEvent(cond->hot_potato); } + LeaveCriticalSection(&cond->cs); + #else pthread_cond_wait(&cond->cond, &lock->lock); #endif @@ -524,13 +543,29 @@ void scond_signal(scond_t *cond) { #ifdef USE_WIN32_THREADS + /* Unfortunately, pthread_cond_signal does not require that the lock be held in advance */ + /* To avoid stomping on the condvar from other threads, we need to control access to it with this */ + EnterCriticalSection(&cond->cs); + /* remember: we currently have mutex */ - if(cond->waiters == 0) return; + if(cond->waiters == 0) + { + LeaveCriticalSection(&cond->cs); + return; + } /* wake up the next thing in the queue */ if(cond->wakens == 0) SetEvent(cond->event); cond->wakens++; + /* The data structure is done being modified.. I think we can leave the CS now. */ + /* This would prevent some other thread from receiving the hot potato and then + /* immediately stalling for the critical section. */ + /* But remember, we were trying to replicate a semantic where this entire scond_signal call + /* was controlled (by the user) by a lock. */ + /* So in case there's trouble with this, we can move it after SetEvent() */ + LeaveCriticalSection(&cond->cs); + /* Since there is now at least one pending waken, the potato must be in play */ SetEvent(cond->hot_potato); @@ -556,7 +591,7 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) #ifdef USE_WIN32_THREADS DWORD ret; - /* TODO: this is woefully inadequate. It needs to be solved with the newer approach used above */ + /* TODO: this is woefully inadequate. It needs to be solved with the newer approach used above. */ WaitForSingleObject(cond->event, 0); LeaveCriticalSection(&lock->lock); ret = WaitForSingleObject(cond->event,(DWORD)(timeout_us) / 1000); From 92eac105609bb01f1a6517359944310476d8feed Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Thu, 2 Feb 2017 20:21:24 -0500 Subject: [PATCH 05/90] Update sublabel for Information --- intl/msg_hash_eo.h | 2 +- intl/msg_hash_fr.h | 2 +- intl/msg_hash_it.h | 2 +- intl/msg_hash_nl.h | 2 +- intl/msg_hash_ru.h | 4 ++-- intl/msg_hash_us.h | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 1e7e7c8385..dcb2c6fffc 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1675,7 +1675,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, "Join or host a netplay session.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index e2157ab2cf..6a1d52be87 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1643,7 +1643,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, "Join or host a netplay session.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index dd5a9e6de5..675e82c027 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1659,7 +1659,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, "Search for and connect to netplay hosts on the local network.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index bfc50ab739..e64b1d218f 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1675,7 +1675,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, "Join or host a netplay session.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 2ed1d3e105..b3210f1438 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif @@ -1676,7 +1676,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, "Join or host a netplay session.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 3c4147d3fb..94e26b0098 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1775,7 +1775,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, "Search for and connect to netplay hosts on the local network.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display information for core, network, and system. Display manager for database and cursor.") + "Display core, network and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Download add-ons, components and contents for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, From 0c8ee93e3e44aecd26f485562e53ed14b9d10012 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Fri, 3 Feb 2017 10:03:57 +0000 Subject: [PATCH 06/90] Moved cheevos files to their own folder in preparation for the changes to support leaderboards --- Makefile.common | 2 +- cheevos.c => cheevos/cheevos.c | 0 cheevos.h => cheevos/cheevos.h | 0 command.c | 2 +- dynamic.c | 2 +- griffin/griffin.c | 2 +- managers/cheat_manager.c | 2 +- menu/cbs/menu_cbs_sublabel.c | 2 +- menu/menu_displaylist.c | 2 +- menu/widgets/menu_dialog.c | 2 +- network/httpserver/httpserver.c | 2 +- retroarch.cfg | 2436 ++++++++++++++++++++----------- runloop.c | 2 +- tasks/task_content.c | 2 +- 14 files changed, 1634 insertions(+), 824 deletions(-) rename cheevos.c => cheevos/cheevos.c (100%) rename cheevos.h => cheevos/cheevos.h (100%) diff --git a/Makefile.common b/Makefile.common index 42f0a0d8af..bdceae0169 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1197,7 +1197,7 @@ ifeq ($(HAVE_NETWORKING), 1) ifeq ($(HAVE_CHEEVOS), 1) ifeq ($(HAVE_THREADS), 1) DEFINES += -DHAVE_CHEEVOS - OBJ += cheevos.o \ + OBJ += cheevos/cheevos.o \ $(LIBRETRO_COMM_DIR)/utils/md5.o endif endif diff --git a/cheevos.c b/cheevos/cheevos.c similarity index 100% rename from cheevos.c rename to cheevos/cheevos.c diff --git a/cheevos.h b/cheevos/cheevos.h similarity index 100% rename from cheevos.h rename to cheevos/cheevos.h diff --git a/command.c b/command.c index 03e8dd4f37..548c75a279 100644 --- a/command.c +++ b/command.c @@ -43,7 +43,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "cheevos.h" +#include "cheevos/cheevos.h" #endif #ifdef HAVE_MENU diff --git a/dynamic.c b/dynamic.c index 4d18ad1380..0159bd7327 100644 --- a/dynamic.c +++ b/dynamic.c @@ -33,7 +33,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "cheevos.h" +#include "cheevos/cheevos.h" #endif #ifdef HAVE_NETWORKING diff --git a/griffin/griffin.c b/griffin/griffin.c index dc0f2784ef..cf1efc8d58 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -133,7 +133,7 @@ ACHIEVEMENTS #include "../libretro-common/formats/json/jsonsax.c" #include "../network/net_http_special.c" -#include "../cheevos.c" +#include "../cheevos/cheevos.c" #endif /*============================================================ diff --git a/managers/cheat_manager.c b/managers/cheat_manager.c index 5740449e00..10d4974d51 100644 --- a/managers/cheat_manager.c +++ b/managers/cheat_manager.c @@ -30,7 +30,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "../cheevos.h" +#include "../cheevos/cheevos.h" #endif #include "cheat_manager.h" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 3e0f42ed7d..9360d9ad40 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -19,7 +19,7 @@ #include "../menu_cbs.h" #ifdef HAVE_CHEEVOS -#include "../../cheevos.h" +#include "../../cheevos/cheevos.h" #endif #include "../../verbosity.h" diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 6a833cd959..14142c15da 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -37,7 +37,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "../cheevos.h" +#include "../cheevos/cheevos.h" #endif #ifdef HAVE_NETWORKING diff --git a/menu/widgets/menu_dialog.c b/menu/widgets/menu_dialog.c index d2a1f26fa0..00170c516e 100644 --- a/menu/widgets/menu_dialog.c +++ b/menu/widgets/menu_dialog.c @@ -22,7 +22,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "../../cheevos.h" +#include "../../cheevos/cheevos.h" #endif #include "menu_dialog.h" diff --git a/network/httpserver/httpserver.c b/network/httpserver/httpserver.c index 6a7ade8dc2..45958ba060 100644 --- a/network/httpserver/httpserver.c +++ b/network/httpserver/httpserver.c @@ -29,7 +29,7 @@ #include "../../core.h" #include "../../gfx/video_driver.h" #include "../../managers/core_option_manager.h" -#include "../../cheevos.h" +#include "../../cheevos/cheevos.h" #include "../../content.h" #define BASIC_INFO "info" diff --git a/retroarch.cfg b/retroarch.cfg index 990783191d..103657b7f2 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -1,813 +1,1623 @@ -## Skeleton config file for RetroArch - -# Save all save files (*.srm) to this directory. This includes related files like .bsv, .rtc, .psrm, etc ... -# This will be overridden by explicit command line options. -# savefile_directory = - -# Save all save states (*.state) to this directory. -# This will be overridden by explicit command line options. -# savestate_directory = - -# If set to a directory, content which is temporarily extracted -# will be extracted to this directory. -# cache_directory = - -# Save all downloaded files to this directory. -# core_assets_directory = - -# Save all remapped controls to this directory. -# input_remapping_directory = - -# Save all playlists/collections to this directory. -# playlist_directory = - -# If set to a directory, the content history playlist will be saved -# to this directory. -# content_history_dir = - -# Saved queries are stored to this directory. -# cursor_directory = - -# Automatically saves a savestate at the end of RetroArch's lifetime. -# The path is $SRAM_PATH.auto. -# RetroArch will automatically load any savestate with this path on startup if savestate_auto_load is set. -# savestate_auto_save = false -# savestate_auto_load = true - -# Load libretro from a dynamic location for dynamically built RetroArch. -# This option is mandatory. - -# Path to a libretro implementation. -# libretro_path = "/path/to/libretro.so" - -# A directory for where to search for libretro core implementations. -# libretro_directory = - -# A directory for where to search for libretro core information. -# libretro_info_path = - -# Sets log level for libretro cores (GET_LOG_INTERFACE). -# If a log level issued by a libretro core is below libretro_log_level, it is ignored. -# DEBUG logs are always ignored unless verbose mode is activated (--verbose). -# DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3. -# libretro_log_level = 0 - -# Enable or disable verbosity level of frontend. -# log_verbosity = false - -# If this option is enabled, every content file loaded in RetroArch will be -# automatically added to a history list. -# history_list_enable = true - -# Enable performance counters -# perfcnt_enable = false - -# Path to core options config file. -# This config file is used to expose core-specific options. -# It will be written to by RetroArch. -# A default path will be assigned if not set. -# core_options_path = - -# Path to content history file. -# RetroArch keeps track of all content loaded in the menu and from CLI directly for convenient quick loading. -# A default path will be assigned if not set. -# content_history_path = - -# Path to music content history file (optional). -# RetroArch keeps track of all music content loaded in the menu and from CLI directly for convenient quick loading. -# A default path will be assigned if not set. -# content_music_history_path = - -# Path to image content history file (optional). -# RetroArch keeps track of all image content loaded in the menu and from CLI directly for convenient quick loading. -# A default path will be assigned if not set. -# content_image_history_path = - -# Path to video content history file (optional). -# RetroArch keeps track of all video content loaded in the menu and from CLI directly for convenient quick loading. -# A default path will be assigned if not set. -# content_video_history_path = - -# Number of entries that will be kept in content history file. -# content_history_size = 100 - -# Sets the "system" directory. -# Implementations can query for this directory to load BIOSes, system-specific configs, etc. -# system_directory = - -# Sets start directory for menu file browser. -# rgui_browser_directory = - -# Content directory. Interacts with RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY. -# Usually set by developers who bundle libretro/RetroArch apps to point to assets. -# content_directory = - -# Assets directory. This location is queried by default when menu interfaces try to look for -# loadable assets, etc. -# assets_directory = - -# Dynamic wallpapers directory. The place to store the wallpapers dynamically -# loaded by the menu depending on context. -# dynamic_wallpapers_directory = - -# Thumbnails directory. To store thumbnail files. -# thumbnails_directory = - -# Sets start directory for menu config browser. -# rgui_config_directory = - -# Show startup screen in menu. -# Is automatically set to false when seen for the first time. -# This is only updated in config if config_save_on_exit is set to true, however. -# rgui_show_start_screen = true - -# Flushes config to disk on exit. Useful for menu as settings can be modified. -# Overwrites the config. #include's and comments are not preserved. -# config_save_on_exit = true - -# Shows hidden files and folders in directory listings. -# show_hidden_files = true - -#### Video - -# Video driver to use. "gl", "xvideo", "sdl", "d3d" -# video_driver = "gl" - -# Which context implementation to use. -# Possible ones for desktop are: glx, x-egl, kms-egl, sdl-gl, wgl. -# By default, tries to use first suitable driver. -# video_context_driver = - -# Windowed x resolution scale and y resolution scale -# (Real x res: base_size * xscale * aspect_ratio, real y res: base_size * yscale) -# video_scale = 3.0 - -# Fullscreen resolution. Resolution of 0 uses the resolution of the desktop. -# video_fullscreen_x = 0 -# video_fullscreen_y = 0 - -# Start in fullscreen. Can be changed at runtime. -# video_fullscreen = false - -# If fullscreen, prefer using a windowed fullscreen mode. -# video_windowed_fullscreen = true - -# Which monitor to prefer. 0 (default) means no particular monitor is preferred, 1 and up (1 being first monitor), -# suggests RetroArch to use that particular monitor. -# video_monitor_index = 0 - -# Forcibly disable composition. Only works in Windows Vista/7 for now. -# video_disable_composition = false - -# Video vsync. -# video_vsync = true - -# Interval at which a Vsync swap is performed. -# 1 is normal, 2 is doubled frames, 3 is tripled frames, etc. -# video_swap_interval = 1 - -# Max amount of swapchain images. -# Single buffering = 1, Double buffering = 2, 3 = Triple buffering -# video_max_swapchain_images = 3 - -# Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows -# have video problems with sRGB FBO support enabled. -# video_force_srgb_disable = false - -# Attempts to hard-synchronize CPU and GPU. Can reduce latency at cost of performance. -# video_hard_sync = false - -# Sets how many frames CPU can run ahead of GPU when using video_hard_sync. -# Maximum is 3. -# video_hard_sync_frames = 0 - -# Sets how many milliseconds to delay after VSync before running the core. -# Can reduce latency at cost of higher risk of stuttering. -# Maximum is 15. -# video_frame_delay = 0 - -# Inserts a black frame inbetween frames. -# Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. -# video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2). -# video_black_frame_insertion = false - -# Use threaded video driver. Using this might improve performance at possible cost of latency and more video stuttering. -# video_threaded = false - -# Use a shared context for HW rendered libretro cores. -# Avoids having to assume HW state changes inbetween frames. -# video_shared_context = false - -# Smoothens picture with bilinear filtering. Should be disabled if using pixel shaders. -# video_smooth = true - -# Forces rendering area to stay equal to content aspect ratio or as defined in video_aspect_ratio. -# video_force_aspect = true - -# Only scales video in integer steps. -# The base size depends on system-reported geometry and aspect ratio. -# If video_force_aspect is not set, X/Y will be integer scaled independently. -# video_scale_integer = false - -# Index of the aspect ratio selection in the menu. -# 19 = Config, 20 = 1:1 PAR, 21 = Core Provided, 22 = Custom Aspect Ratio -# aspect_ratio_index = 19 - -# A floating point value for video aspect ratio (width / height). -# If this is not set, aspect ratio is assumed to be automatic. -# Behavior then is defined by video_aspect_ratio_auto. -# video_aspect_ratio = - -# If this is true and video_aspect_ratio is not set, -# aspect ratio is decided by libretro implementation. -# If this is false, 1:1 PAR will always be assumed if video_aspect_ratio is not set. -# video_aspect_ratio_auto = false - -# Forces cropping of overscanned frames. -# Exact behavior of this option is implementation specific. -# video_crop_overscan = true - -# Path to shader. Shader can be either Cg, CGP (Cg preset) or GLSL, GLSLP (GLSL preset) -# video_shader = "/path/to/shader.{cg,cgp,glsl,glslp}" - -# Load video_shader on startup. -# Other shaders can still be loaded later in runtime. -# video_shader_enable = false - -# Defines a directory where shaders (Cg, CGP, GLSL) are kept for easy access. -# video_shader_dir = - -# CPU-based video filter. Path to a dynamic library. -# video_filter = - -# Defines a directory where CPU-based video filters are kept. -# video_filter_dir = - -# Path to a font used for rendering messages. This path must be defined to enable fonts. -# Do note that the _full_ path of the font is necessary! -# video_font_path = - -# Size of the font rendered in points. -# video_font_size = 32 - -# Enable usage of OSD messages. -# video_font_enable = true - -# Offset for where messages will be placed on screen. Values are in range 0.0 to 1.0 for both x and y values. -# [0.0, 0.0] maps to the lower left corner of the screen. -# video_message_pos_x = 0.05 -# video_message_pos_y = 0.05 - -# Color for message. The value is treated as a hexadecimal value. -# It is a regular RGB hex number, i.e. red is "ff0000". -# video_message_color = ffffff - -# Video refresh rate of your monitor. -# Used to calculate a suitable audio input rate. -# video_refresh_rate = 59.94 - -# Allows libretro cores to set rotation modes. -# Setting this to false will honor, but ignore this request. -# This is useful for vertically oriented content where one manually rotates the monitor. -# video_allow_rotate = true - -# Forces a certain rotation of the screen. -# The rotation is added to rotations which the libretro core sets (see video_allow_rotate). -# The angle is * 90 degrees counter-clockwise. -# video_rotation = 0 - -#### Audio - -# Enable audio. -# audio_enable = true - -# Mutes audio. -# audio_mute_enable = false - -# Audio output samplerate. -# audio_out_rate = 48000 - -# Audio resampler backend. Which audio resampler to use. -# Default will use "sinc". -# audio_resampler = - -# Audio driver backend. Depending on configuration possible candidates are: alsa, pulse, oss, jack, rsound, roar, openal, sdl, xaudio. -# audio_driver = - -# Override the default audio device the audio_driver uses. This is driver dependant. E.g. ALSA wants a PCM device, OSS wants a path (e.g. /dev/dsp), Jack wants portnames (e.g. system:playback1,system:playback_2), and so on ... -# audio_device = - -# Audio DSP plugin that processes audio before it's sent to the driver. Path to a dynamic library. -# audio_dsp_plugin = - -# Directory where DSP plugins are kept. -# audio_filter_dir = - -# Will sync (block) on audio. Recommended. -# audio_sync = true - -# Desired audio latency in milliseconds. Might not be honored if driver can't provide given latency. -# audio_latency = 64 - -# Enable audio rate control. -# audio_rate_control = true - -# Controls audio rate control delta. Defines how much input rate can be adjusted dynamically. -# Input rate = in_rate * (1.0 +/- audio_rate_control_delta) -# audio_rate_control_delta = 0.005 - -# Controls maximum audio timing skew. Defines the maximum change in input rate. -# Input rate = in_rate * (1.0 +/- max_timing_skew) -# audio_max_timing_skew = 0.05 - -# Audio volume. Volume is expressed in dB. -# 0 dB is normal volume. No gain will be applied. -# Gain can be controlled in runtime with input_volume_up/input_volume_down. -# audio_volume = 0.0 - -#### Overlay - -# Defines a directory where overlays are kept for easy access. -# overlay_directory = - -# Enable the overlay. -# input_overlay_enable = true - -# Hide the current overlay from appearing inside the menu. -# input_overlay_hide_in_menu = true - -# Path to input overlay. -# input_overlay = - -# Opacity of all the UI elements of the overlay. -# input_overlay_opacity = 1.0 - -# Scale of all UI elements of the overlay. -# input_overlay_scale = 1.0 - -#### Input - -# Input driver. Depending on video driver, it might force a different input driver. -# input_driver = sdl - -# Joypad driver. (Valid: linuxraw, sdl, dinput) -# input_joypad_driver = - -# Path to input remapping file. -# input_remapping_path = - -# Input bind timer timeout. -# Amount of seconds to wait until proceeding to the next bind. Default: 5, minimum: 1 -# input_bind_timeout = 1 - -# If enabled, overrides the input binds with the remapped binds set for the current core. -# input_remap_binds_enable = true - -# Maximum amount of users supported by RetroArch. -# input_max_users = 16 - -# Keyboard layout for input driver if applicable (udev/evdev for now). -# Syntax is either just layout (e.g. "no"), or a layout and variant separated with colon ("no:nodeadkeys"). -# input_keyboard_layout = - -# Defines axis threshold. Possible values are [0.0, 1.0] -# input_axis_threshold = 0.5 - -# Enable input auto-detection. Will attempt to autoconfigure -# joypads, Plug-and-Play style. -# input_autodetect_enable = true - -# Show the input descriptors set by the core instead of the -# default ones. -# input_descriptor_label_show = true - -# Hide input descriptors that were not set by the core. -# input_descriptor_hide_unbound = false - -# Influence how input polling is done inside RetroArch. -# 0 : Early - Input polling is performed before call to retro_run. -# 1 : Normal - Input polling is performed when retro_input_poll is -# requested. -# 2 : Late - Input polling is performed on first call to retro_input_state -# per frame -# -# Setting it to 0 or 2 can result in less latency depending on -# your configuration. -# -# When netplay is enabled, the default polling behavior (1) will -# be used regardless of the value set here. -# input_poll_type_behavior = 1 - -# Directory for joypad autoconfigs. -# If a joypad is plugged in, that joypad will be autoconfigured if a config file -# corresponding to that joypad is present in joypad_autoconfig_dir. -# Input binds which are made explicit (input_playerN_*_btn/axis) will take priority over autoconfigs. -# Autoconfigs can be created with retroarch-joyconfig, manually, or with a frontend. -# Requires input_autodetect_enable to be enabled. -# joypad_autoconfig_dir = - -# Sets which libretro device is used for a user. -# Devices are indentified with a number. -# This is normally saved by the menu. -# Device IDs are found in libretro.h. -# These settings are overridden by explicit command-line arguments which refer to input devices. -# None: 0 -# Joypad (RetroPad): 1 -# Mouse: 2 -# Keyboard: 3 -# Generic Lightgun: 4 -# Joypad w/ Analog (RetroPad + Analog sticks): 5 -# Multitap (SNES specific): 257 -# Super Scope (SNES specific): 260 -# Justifier (SNES specific): 516 -# Justifiers (SNES specific): 772 - -# input_libretro_device_p1 = -# input_libretro_device_p2 = -# input_libretro_device_p3 = -# input_libretro_device_p4 = -# input_libretro_device_p5 = -# input_libretro_device_p6 = -# input_libretro_device_p7 = -# input_libretro_device_p8 = - -# Keyboard input. Will recognize letters ("a" to "z") and the following special keys (where "kp_" -# is for keypad keys): -# -# left, right, up, down, enter, kp_enter, tab, insert, del, end, home, -# rshift, shift, ctrl, alt, space, escape, add, subtract, kp_plus, kp_minus, -# f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, -# num0, num1, num2, num3, num4, num5, num6, num7, num8, num9, pageup, pagedown, -# keypad0, keypad1, keypad2, keypad3, keypad4, keypad5, keypad6, keypad7, keypad8, keypad9, -# period, capslock, numlock, backspace, multiply, divide, print_screen, scroll_lock, -# tilde, backquote, pause, quote, comma, minus, slash, semicolon, equals, leftbracket, -# backslash, rightbracket, kp_period, kp_equals, rctrl, ralt -# -# Keyboard input, Joypad and Joyaxis will all obey the "nul" bind, which disables the bind completely, -# rather than relying on a default. -# input_player1_a = "x" -# input_player1_b = "z" -# input_player1_y = "a" -# input_player1_x = "s" -# input_player1_start = "enter" -# input_player1_select = "rshift" -# input_player1_l = "q" -# input_player1_r = "w" -# input_player1_left = "left" -# input_player1_right = "right" -# input_player1_up = "up" -# input_player1_down = "down" -# input_player1_l2 = -# input_player1_r2 = -# input_player1_l3 = -# input_player1_r3 = - -# Two analog sticks (DualShock-esque). -# Bound as usual, however, if a real analog axis is bound, -# it can be read as a true analog. -# Positive X axis is right, Positive Y axis is down. -# input_player1_l_x_plus = -# input_player1_l_x_minus = -# input_player1_l_y_plus = -# input_player1_l_y_minus = -# input_player1_r_x_plus = -# input_player1_r_x_minus = -# input_player1_r_y_plus = -# input_player1_r_y_minus = - -# If desired, it is possible to override which joypads are being used for user 1 through 8. -# First joypad available is 0. -# input_player1_joypad_index = 0 -# input_player2_joypad_index = 1 -# input_player3_joypad_index = 2 -# input_player4_joypad_index = 3 -# input_player5_joypad_index = 4 -# input_player6_joypad_index = 5 -# input_player7_joypad_index = 6 -# input_player8_joypad_index = 7 - -# Input device buttons. -# Figure these out by using RetroArch-Phoenix or retroarch-joyconfig. -# You can use joypad hats with hnxx, where n is the hat, and xx is a string representing direction. -# E.g. "h0up" -# input_player1_a_btn = -# input_player1_b_btn = -# input_player1_y_btn = -# input_player1_x_btn = -# input_player1_start_btn = -# input_player1_select_btn = -# input_player1_l_btn = -# input_player1_r_btn = -# input_player1_left_btn = -# input_player1_right_btn = -# input_player1_up_btn = -# input_player1_down_btn = -# input_player1_l2_btn = -# input_player1_r2_btn = -# input_player1_l3_btn = -# input_player1_r3_btn = - -# Menu buttons. -# menu_search_btn = -# menu_info_btn = -# menu_default_btn = -# menu_scroll_down_btn = -# menu_scroll_up_btn = - -# Swap buttons for OK/Cancel -# menu_swap_ok_cancel_buttons = false - -# Axis for RetroArch D-Pad. -# Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number. -# Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity. -# input_player1_left_axis = -# input_player1_right_axis = -# input_player1_up_axis = -# input_player1_down_axis = - -# Holding the turbo while pressing another button will let the button enter a turbo mode -# where the button state is modulated with a periodic signal. -# The modulation stops when the button itself (not turbo button) is released. -# input_player1_turbo = - -# Describes the period and how long of that period a turbo-enabled button should behave. -# Numbers are described in frames. -# input_turbo_period = 6 -# input_turbo_duty_cycle = 3 - -# This goes all the way to user 8 (*_player2_*, *_player3_*, etc), but omitted for clarity. -# All input binds have corresponding binds for keyboard (none), joykeys (_btn) and joyaxes (_axis) as well. - -# Toggles fullscreen. -# input_toggle_fullscreen = f - -# Saves state. -# input_save_state = f2 -# Loads state. -# input_load_state = f4 - -# State slots. With slot set to 0, save state name is *.state (or whatever defined on commandline). -# When slot is != 0, path will be $path%d, where %d is slot number. -# input_state_slot_increase = f7 -# input_state_slot_decrease = f6 - -# Toggles between fast-forwarding and normal speed. -# input_toggle_fast_forward = space - -# Hold for fast-forward. Releasing button disables fast-forward. -# input_hold_fast_forward = l - -# Key to exit RetroArch cleanly. -# Killing it in any hard way (SIGKILL, etc) will terminate RetroArch without saving RAM, etc. -# On Unix-likes, SIGINT/SIGTERM allows a clean deinitialization. -# input_exit_emulator = escape - - -# Applies next and previous shader in directory. -# input_shader_next = m -# input_shader_prev = n - -# Hold button down to rewind. Rewinding must be enabled. -# input_rewind = r - -# Toggle between recording and not. -# input_movie_record_toggle = o - -# Toggle between paused and non-paused state -# input_pause_toggle = p - -# Frame advance when content is paused -# input_frame_advance = k - -# Reset the content. -# input_reset = h - -# Cheats. -# input_cheat_index_plus = y -# input_cheat_index_minus = t -# input_cheat_toggle = u - -# Mute/unmute audio -# input_audio_mute = f9 - -# Take screenshot -# input_screenshot = f8 - -# Netplay flip users. -# input_netplay_flip_players = i - -# Hold for slowmotion. -# input_slowmotion = e - -# Enable other hotkeys. -# If this hotkey is bound to either keyboard, joybutton or joyaxis, -# all other hotkeys will be disabled unless this hotkey is also held at the same time. -# This is useful for RETRO_KEYBOARD centric implementations -# which query a large area of the keyboard, where it is not desirable -# that hotkeys get in the way. - -# Alternatively, all hotkeys for keyboard could be disabled by the user. -# input_enable_hotkey_btn = - -# Increases audio volume. -# input_volume_up = kp_plus -# Decreases audio volume. -# input_volume_down = kp_minus - -# Toggles to next overlay. Wraps around. -# input_overlay_next = - -# Toggles eject for disks. Used for multiple-disk content. -# input_disk_eject_toggle = - -# Cycles through disk images. Use after ejecting. -# Complete by toggling eject again. -# input_disk_next = - -# Toggles menu. -# input_menu_toggle = f1 - -# RetroPad button combination to toggle menu -# 0 = none, 1 = L + R + Y + D-Pad Down, 2 = L3 + R3, 3 = Start + Select -# input_menu_toggle_gamepad_combo = 0 - -# allow any RetroPad to control the menu -# all_users_control_menu = false - -# Toggles mouse grab. When mouse is grabbed, RetroArch hides the mouse, -# and keeps the mouse pointer inside the window to allow relative mouse input -# to work better. -# input_grab_mouse_toggle = f11 - -#### Menu - -# Menu driver to use. "rgui", "lakka", etc. -# menu_driver = "rgui" - -# If disabled, the libretro core will keep running in the background when we -# are in the menu. -# menu_pause_libretro = false - -# If disabled, we use separate controls for menu operation. -# menu_unified_controls = false - -# Enable mouse controls inside the menu. -# menu_mouse_enable = false - -# Enable touch controls inside the menu. -# menu_pointer_enable = false - -# Shows current date and/or time inside menu. -# menu_timedate_enable = true - -# Shows current battery level inside menu. -# menu_battery_level_enable = true - -# Shows current core inside menu. -# menu_core_enable = true - -# Path to an image to set as menu wallpaper. -# menu_wallpaper = - -# Dynamically load a new wallpaper depending on context. -# menu_dynamic_wallpaper_enable = false - -# Type of thumbnail to display. 0 = none, 1 = snaps, 2 = titles, 3 = boxarts -# menu_thumbnails = 0 - -# Wrap-around to beginning and/or end if boundary of list is reached horizontally or vertically. -# menu_navigation_wraparound_enable = false - -# Filter files being shown in filebrowser by supported extensions. -# menu_navigation_browser_filter_supported_extensions_enable = true - -# Collapse subgroup settings into main group to create one big listing of settings -# per category. -# menu_collapse_subgroups_enable = false - -#### Core -# -# Prevent libretro cores from closing RetroArch on exit by loading a dummy core. -# load_dummy_on_core_shutdown = "true" - -# Check for firmware requirement(s) before loading a content. -# check_firmware_before_loading = "false" - -#### UI - -# Suspends the screensaver if set to true. Is a hint that does not necessarily have to be honored -# by video driver. -# suspend_screensaver_enable = true - -# Start UI companion driver's interface on boot (if available). -# ui_companion_start_on_boot = true - -#### Camera - -# Override the default camera device the camera driver uses. This is driver dependant. -# camera_device = - -# Override the default privacy permission for cores that want to access camera services. Is "false" by default. -# camera_allow = false - -#### Location - -# Override the default privacy permission for cores that want to access location services. Is "false" by default. -# location_allow = false - -#### Core Updater - -# URL to core update directory on buildbot. -# core_updater_buildbot_url = "http://buildbot.libretro.com" - -# URL to assets update directory on buildbot. -# core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" - -# After downloading, automatically extract archives that the downloads are contained inside. -# core_updater_auto_extract_archive = true - -#### Network - -# When being client over netplay, use keybinds for user 1. -# netplay_client_swap_input = false - -# The username of the person running RetroArch. This will be used for playing online, for instance. -# netplay_nickname = - -# The amount of delay frames to use for netplay. Increasing this value will increase -# performance, but introduce more latency. -# netplay_delay_frames = 0 - -# Netplay mode for the current user. -# false is Server, true is Client. -# netplay_mode = false - -# Enable or disable spectator mode for the user during netplay. -# netplay_spectator_mode_enable = false - -# The IP Address of the host to connect to. -# netplay_ip_address = - -# The port of the host IP Address. Can be either a TCP or UDP port. -# netplay_ip_port = 55435 - -#### Misc - -# Enable rewinding. This will take a performance hit when playing, so it is disabled by default. -# rewind_enable = false - -# Rewinding buffer size in megabytes. Bigger rewinding buffer means you can rewind longer. -# The buffer should be approx. 20MB per minute of buffer time. -# rewind_buffer_size = 20 - -# Rewind granularity. When rewinding defined number of frames, you can rewind several frames at a time, increasing the rewinding speed. -# rewind_granularity = 1 - -# Pause gameplay when window focus is lost. -# pause_nonactive = true - -# Autosaves the non-volatile SRAM at a regular interval. This is disabled by default unless set otherwise. -# The interval is measured in seconds. A value of 0 disables autosave. -# autosave_interval = - -# Path to content database directory. -# content_database_path = - -# Path to cheat database directory. -# cheat_database_path = - -# Directory to dump screenshots to. -# screenshot_directory = - -# Records video after CPU video filter. -# video_post_filter_record = false - -# Records output of GPU shaded material if available. -# video_gpu_record = false - -# Screenshots output of GPU shaded material if available. -# video_gpu_screenshot = true - -# Block SRAM from being overwritten when loading save states. -# Might potentially lead to buggy games. -# block_sram_overwrite = false - -# When saving a savestate, save state index is automatically increased before -# it is saved. -# Also, when loading content, the index will be set to the highest existing index. -# There is no upper bound on the index. -# savestate_auto_index = false - -# Slowmotion ratio. When slowmotion, content will slow down by factor. -# slowmotion_ratio = 3.0 - -# The maximum rate at which content will be run when using fast forward. (E.g. 5.0 for 60 fps content => 300 fps cap). -# RetroArch will go to sleep to ensure that the maximum rate will not be exceeded. -# Do not rely on this cap to be perfectly accurate. -# If this is set at 0, then fastforward ratio is unlimited (no FPS cap) -# fastforward_ratio = 0.0 - -# Enable stdin/network command interface. -# network_cmd_enable = false -# network_cmd_port = 55355 -# stdin_cmd_enable = false +core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/win-x86_64/latest/" +core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" +libretro_directory = ":\cores" +libretro_info_path = ":\info" +content_database_path = ":\database\rdb" +cheat_database_path = ":\cheats" +content_history_path = ":\content_history.lpl" +content_music_history_path = ":\content_music_history.lpl" +content_video_history_path = ":\content_video_history.lpl" +content_image_history_path = ":\content_image_history.lpl" +cursor_directory = ":\database\cursors" +screenshot_directory = "default" +system_directory = "default" +input_remapping_directory = ":\config\remaps" +video_shader_dir = ":\shaders" +video_filter_dir = ":\filters\video" +core_assets_directory = ":\downloads" +assets_directory = ":\assets" +dynamic_wallpapers_directory = ":\assets\wallpapers" +thumbnails_directory = ":\thumbnails" +playlist_directory = ":\playlists" +joypad_autoconfig_dir = ":\autoconfig" +audio_filter_dir = ":\filters\audio" +savefile_directory = "default" +savestate_directory = "default" +rgui_browser_directory = "default" +rgui_config_directory = ":\config" +overlay_directory = ":\overlays" +screenshot_directory = "default" +video_driver = "gl" +record_driver = "null" +camera_driver = "null" +wifi_driver = "null" +location_driver = "null" +menu_driver = "xmb" +audio_driver = "xaudio" +audio_resampler = "sinc" +input_driver = "dinput" +input_joypad_driver = "xinput" +video_aspect_ratio = "-1.000000" +video_scale = "3.000000" +video_refresh_rate = "59.940060" +audio_rate_control_delta = "0.005000" +audio_max_timing_skew = "0.050000" +audio_volume = "0.000000" +input_overlay_opacity = "0.700000" +input_overlay_scale = "1.000000" +menu_wallpaper_opacity = "0.300000" +menu_footer_opacity = "1.000000" +menu_header_opacity = "1.000000" +video_message_pos_x = "0.050000" +video_message_pos_y = "0.050000" +video_font_size = "32.000000" +fastforward_ratio = "0.000000" +slowmotion_ratio = "3.000000" +input_axis_threshold = "0.500000" +input_bind_timeout = "5" +input_turbo_period = "6" +input_duty_cycle = "3" +input_max_users = "5" +input_menu_toggle_gamepad_combo = "0" +audio_latency = "64" +audio_block_frames = "0" +rewind_granularity = "1" +autosave_interval = "0" +libretro_log_level = "0" +keyboard_gamepad_mapping_type = "1" +input_poll_type_behavior = "2" +video_monitor_index = "0" +video_fullscreen_x = "0" +video_fullscreen_y = "0" +video_window_x = "0" +video_window_y = "0" +network_cmd_port = "55355" +network_remote_base_port = "55400" +dpi_override_value = "200" +menu_thumbnails = "3" +xmb_alpha_factor = "75" +xmb_scale_factor = "100" +xmb_theme = "0" +xmb_menu_color_theme = "4" +materialui_menu_color_theme = "0" +menu_shader_pipeline = "2" +audio_out_rate = "48000" +custom_viewport_width = "960" +custom_viewport_height = "720" +custom_viewport_x = "0" +custom_viewport_y = "0" +content_history_size = "100" +video_hard_sync_frames = "0" +video_frame_delay = "0" +video_max_swapchain_images = "3" +video_swap_interval = "1" +video_rotation = "0" +aspect_ratio_index = "21" +state_slot = "0" +netplay_ip_port = "55435" +netplay_check_frames = "30" +netplay_input_latency_frames_min = "0" +netplay_input_latency_frames_range = "0" +user_language = "0" +bundle_assets_extract_version_current = "0" +bundle_assets_extract_last_version = "0" +input_device_p1 = "0" +input_player1_joypad_index = "0" +input_libretro_device_p1 = "1" +input_player1_analog_dpad_mode = "0" +input_device_p2 = "0" +input_player2_joypad_index = "1" +input_libretro_device_p2 = "1" +input_player2_analog_dpad_mode = "0" +input_device_p3 = "0" +input_player3_joypad_index = "2" +input_libretro_device_p3 = "1" +input_player3_analog_dpad_mode = "0" +input_device_p4 = "0" +input_player4_joypad_index = "3" +input_libretro_device_p4 = "1" +input_player4_analog_dpad_mode = "0" +input_device_p5 = "0" +input_player5_joypad_index = "4" +input_libretro_device_p5 = "1" +input_player5_analog_dpad_mode = "0" +input_device_p6 = "0" +input_player6_joypad_index = "5" +input_libretro_device_p6 = "1" +input_player6_analog_dpad_mode = "0" +input_device_p7 = "0" +input_player7_joypad_index = "6" +input_libretro_device_p7 = "1" +input_player7_analog_dpad_mode = "0" +input_device_p8 = "0" +input_player8_joypad_index = "7" +input_libretro_device_p8 = "1" +input_player8_analog_dpad_mode = "0" +input_device_p9 = "0" +input_player9_joypad_index = "8" +input_libretro_device_p9 = "1" +input_player9_analog_dpad_mode = "0" +input_device_p10 = "0" +input_player10_joypad_index = "9" +input_libretro_device_p10 = "1" +input_player10_analog_dpad_mode = "0" +input_device_p11 = "0" +input_player11_joypad_index = "10" +input_libretro_device_p11 = "1" +input_player11_analog_dpad_mode = "0" +input_device_p12 = "0" +input_player12_joypad_index = "11" +input_libretro_device_p12 = "1" +input_player12_analog_dpad_mode = "0" +input_device_p13 = "0" +input_player13_joypad_index = "12" +input_libretro_device_p13 = "1" +input_player13_analog_dpad_mode = "0" +input_device_p14 = "0" +input_player14_joypad_index = "13" +input_libretro_device_p14 = "1" +input_player14_analog_dpad_mode = "0" +input_device_p15 = "0" +input_player15_joypad_index = "14" +input_libretro_device_p15 = "1" +input_player15_analog_dpad_mode = "0" +input_device_p16 = "0" +input_player16_joypad_index = "15" +input_libretro_device_p16 = "1" +input_player16_analog_dpad_mode = "0" +ui_companion_start_on_boot = "true" +ui_companion_enable = "false" +video_gpu_record = "false" +input_remap_binds_enable = "true" +all_users_control_menu = "false" +menu_swap_ok_cancel_buttons = "true" +netplay_stateless_mode = "false" +netplay_client_swap_input = "true" +input_descriptor_label_show = "true" +input_descriptor_hide_unbound = "false" +load_dummy_on_core_shutdown = "true" +check_firmware_before_loading = "false" +builtin_mediaplayer_enable = "false" +builtin_imageviewer_enable = "true" +fps_show = "false" +ui_menubar_enable = "true" +suspend_screensaver_enable = "true" +rewind_enable = "false" +audio_sync = "true" +video_shader_enable = "false" +video_aspect_ratio_auto = "false" +video_allow_rotate = "true" +video_windowed_fullscreen = "true" +video_crop_overscan = "true" +video_scale_integer = "false" +video_smooth = "true" +video_force_aspect = "true" +video_threaded = "false" +video_shared_context = "false" +auto_screenshot_filename = "true" +video_force_srgb_disable = "false" +video_fullscreen = "false" +bundle_assets_extract_enable = "false" +video_vsync = "true" +video_hard_sync = "false" +video_black_frame_insertion = "false" +video_disable_composition = "false" +pause_nonactive = "true" +video_gpu_screenshot = "true" +video_post_filter_record = "false" +keyboard_gamepad_enable = "true" +core_set_supports_no_game_enable = "true" +audio_enable = "true" +audio_mute_enable = "false" +location_allow = "false" +video_font_enable = "true" +core_updater_auto_extract_archive = "true" +camera_allow = "false" +menu_unified_controls = "false" +threaded_data_runloop_enable = "true" +menu_throttle_framerate = "true" +menu_linear_filter = "true" +dpi_override_enable = "true" +menu_pause_libretro = "true" +menu_mouse_enable = "true" +menu_pointer_enable = "false" +menu_timedate_enable = "true" +menu_battery_level_enable = "true" +menu_core_enable = "true" +menu_dynamic_wallpaper_enable = "false" +xmb_shadows_enable = "true" +xmb_show_settings = "true" +xmb_show_images = "true" +xmb_show_history = "true" +xmb_show_add = "true" +rgui_show_start_screen = "false" +menu_navigation_wraparound_enable = "true" +menu_navigation_browser_filter_supported_extensions_enable = "true" +menu_show_advanced_settings = "false" +cheevos_enable = "false" +cheevos_test_unofficial = "false" +cheevos_hardcore_mode_enable = "false" +input_overlay_enable = "true" +input_overlay_enable_autopreferred = "true" +input_overlay_hide_in_menu = "true" +network_cmd_enable = "false" +stdin_cmd_enable = "false" +network_remote_enable = "false" +netplay_nat_traversal = "true" +block_sram_overwrite = "false" +savestate_auto_index = "false" +savestate_auto_save = "false" +savestate_auto_load = "false" +savestate_thumbnail_enable = "false" +history_list_enable = "true" +playlist_entry_remove = "true" +game_specific_options = "false" +auto_overrides_enable = "true" +auto_remaps_enable = "true" +auto_shaders_enable = "true" +sort_savefiles_enable = "false" +sort_savestates_enable = "false" +config_save_on_exit = "true" +show_hidden_files = "true" +input_autodetect_enable = "true" +audio_rate_control = "true" +custom_bgm_enable = "false" +network_remote_enable_user_p1 = "false" +network_remote_enable_user_p2 = "false" +network_remote_enable_user_p3 = "false" +network_remote_enable_user_p4 = "false" +network_remote_enable_user_p5 = "false" +network_remote_enable_user_p6 = "false" +network_remote_enable_user_p7 = "false" +network_remote_enable_user_p8 = "false" +network_remote_enable_user_p9 = "false" +network_remote_enable_user_p10 = "false" +network_remote_enable_user_p11 = "false" +network_remote_enable_user_p12 = "false" +network_remote_enable_user_p13 = "false" +network_remote_enable_user_p14 = "false" +network_remote_enable_user_p15 = "false" +network_remote_enable_user_p16 = "false" +log_verbosity = "false" +perfcnt_enable = "false" +video_message_color = "ffff00" +menu_entry_normal_color = "ffffffff" +menu_entry_hover_color = "ff64ff64" +menu_title_color = "ff64ff64" +gamma_correction = "false" +flicker_filter_enable = "false" +soft_filter_enable = "false" +soft_filter_index = "0" +current_resolution_id = "0" +flicker_filter_index = "0" +input_player1_b = "z" +input_player1_b_btn = "nul" +input_player1_b_axis = "nul" +input_player1_y = "a" +input_player1_y_btn = "nul" +input_player1_y_axis = "nul" +input_player1_select = "rshift" +input_player1_select_btn = "nul" +input_player1_select_axis = "nul" +input_player1_start = "enter" +input_player1_start_btn = "nul" +input_player1_start_axis = "nul" +input_player1_up = "up" +input_player1_up_btn = "nul" +input_player1_up_axis = "nul" +input_player1_down = "down" +input_player1_down_btn = "nul" +input_player1_down_axis = "nul" +input_player1_left = "left" +input_player1_left_btn = "nul" +input_player1_left_axis = "nul" +input_player1_right = "right" +input_player1_right_btn = "nul" +input_player1_right_axis = "nul" +input_player1_a = "x" +input_player1_a_btn = "nul" +input_player1_a_axis = "nul" +input_player1_x = "s" +input_player1_x_btn = "nul" +input_player1_x_axis = "nul" +input_player1_l = "q" +input_player1_l_btn = "nul" +input_player1_l_axis = "nul" +input_player1_r = "w" +input_player1_r_btn = "nul" +input_player1_r_axis = "nul" +input_player1_l2 = "nul" +input_player1_l2_btn = "nul" +input_player1_l2_axis = "nul" +input_player1_r2 = "nul" +input_player1_r2_btn = "nul" +input_player1_r2_axis = "nul" +input_player1_l3 = "nul" +input_player1_l3_btn = "nul" +input_player1_l3_axis = "nul" +input_player1_r3 = "nul" +input_player1_r3_btn = "nul" +input_player1_r3_axis = "nul" +input_player1_l_x_plus = "nul" +input_player1_l_x_plus_btn = "nul" +input_player1_l_x_plus_axis = "nul" +input_player1_l_x_minus = "nul" +input_player1_l_x_minus_btn = "nul" +input_player1_l_x_minus_axis = "nul" +input_player1_l_y_plus = "nul" +input_player1_l_y_plus_btn = "nul" +input_player1_l_y_plus_axis = "nul" +input_player1_l_y_minus = "nul" +input_player1_l_y_minus_btn = "nul" +input_player1_l_y_minus_axis = "nul" +input_player1_r_x_plus = "nul" +input_player1_r_x_plus_btn = "nul" +input_player1_r_x_plus_axis = "nul" +input_player1_r_x_minus = "nul" +input_player1_r_x_minus_btn = "nul" +input_player1_r_x_minus_axis = "nul" +input_player1_r_y_plus = "nul" +input_player1_r_y_plus_btn = "nul" +input_player1_r_y_plus_axis = "nul" +input_player1_r_y_minus = "nul" +input_player1_r_y_minus_btn = "nul" +input_player1_r_y_minus_axis = "nul" +input_player1_turbo = "nul" +input_player1_turbo_btn = "nul" +input_player1_turbo_axis = "nul" +input_toggle_fast_forward = "space" +input_toggle_fast_forward_btn = "nul" +input_toggle_fast_forward_axis = "nul" +input_hold_fast_forward = "l" +input_hold_fast_forward_btn = "nul" +input_hold_fast_forward_axis = "nul" +input_load_state = "f4" +input_load_state_btn = "nul" +input_load_state_axis = "nul" +input_save_state = "f2" +input_save_state_btn = "nul" +input_save_state_axis = "nul" +input_toggle_fullscreen = "f" +input_toggle_fullscreen_btn = "nul" +input_toggle_fullscreen_axis = "nul" +input_exit_emulator = "escape" +input_exit_emulator_btn = "nul" +input_exit_emulator_axis = "nul" +input_state_slot_increase = "f7" +input_state_slot_increase_btn = "nul" +input_state_slot_increase_axis = "nul" +input_state_slot_decrease = "f6" +input_state_slot_decrease_btn = "nul" +input_state_slot_decrease_axis = "nul" +input_rewind = "r" +input_rewind_btn = "nul" +input_rewind_axis = "nul" +input_movie_record_toggle = "o" +input_movie_record_toggle_btn = "nul" +input_movie_record_toggle_axis = "nul" +input_pause_toggle = "p" +input_pause_toggle_btn = "nul" +input_pause_toggle_axis = "nul" +input_frame_advance = "k" +input_frame_advance_btn = "nul" +input_frame_advance_axis = "nul" +input_reset = "h" +input_reset_btn = "nul" +input_reset_axis = "nul" +input_shader_next = "m" +input_shader_next_btn = "nul" +input_shader_next_axis = "nul" +input_shader_prev = "n" +input_shader_prev_btn = "nul" +input_shader_prev_axis = "nul" +input_cheat_index_plus = "y" +input_cheat_index_plus_btn = "nul" +input_cheat_index_plus_axis = "nul" +input_cheat_index_minus = "t" +input_cheat_index_minus_btn = "nul" +input_cheat_index_minus_axis = "nul" +input_cheat_toggle = "u" +input_cheat_toggle_btn = "nul" +input_cheat_toggle_axis = "nul" +input_screenshot = "f8" +input_screenshot_btn = "nul" +input_screenshot_axis = "nul" +input_audio_mute = "f9" +input_audio_mute_btn = "nul" +input_audio_mute_axis = "nul" +input_osk_toggle = "f12" +input_osk_toggle_btn = "nul" +input_osk_toggle_axis = "nul" +input_netplay_flip_players_1_2 = "nul" +input_netplay_flip_players_1_2_btn = "nul" +input_netplay_flip_players_1_2_axis = "nul" +input_netplay_game_watch = "i" +input_netplay_game_watch_btn = "nul" +input_netplay_game_watch_axis = "nul" +input_slowmotion = "e" +input_slowmotion_btn = "nul" +input_slowmotion_axis = "nul" +input_enable_hotkey = "nul" +input_enable_hotkey_btn = "nul" +input_enable_hotkey_axis = "nul" +input_volume_up = "add" +input_volume_up_btn = "nul" +input_volume_up_axis = "nul" +input_volume_down = "subtract" +input_volume_down_btn = "nul" +input_volume_down_axis = "nul" +input_overlay_next = "nul" +input_overlay_next_btn = "nul" +input_overlay_next_axis = "nul" +input_disk_eject_toggle = "nul" +input_disk_eject_toggle_btn = "nul" +input_disk_eject_toggle_axis = "nul" +input_disk_next = "nul" +input_disk_next_btn = "nul" +input_disk_next_axis = "nul" +input_disk_prev = "nul" +input_disk_prev_btn = "nul" +input_disk_prev_axis = "nul" +input_grab_mouse_toggle = "f11" +input_grab_mouse_toggle_btn = "nul" +input_grab_mouse_toggle_axis = "nul" +input_game_focus_toggle = "scroll_lock" +input_game_focus_toggle_btn = "nul" +input_game_focus_toggle_axis = "nul" +input_menu_toggle = "f1" +input_menu_toggle_btn = "nul" +input_menu_toggle_axis = "nul" +input_player2_b = "nul" +input_player2_b_btn = "nul" +input_player2_b_axis = "nul" +input_player2_y = "nul" +input_player2_y_btn = "nul" +input_player2_y_axis = "nul" +input_player2_select = "nul" +input_player2_select_btn = "nul" +input_player2_select_axis = "nul" +input_player2_start = "nul" +input_player2_start_btn = "nul" +input_player2_start_axis = "nul" +input_player2_up = "nul" +input_player2_up_btn = "nul" +input_player2_up_axis = "nul" +input_player2_down = "nul" +input_player2_down_btn = "nul" +input_player2_down_axis = "nul" +input_player2_left = "nul" +input_player2_left_btn = "nul" +input_player2_left_axis = "nul" +input_player2_right = "nul" +input_player2_right_btn = "nul" +input_player2_right_axis = "nul" +input_player2_a = "nul" +input_player2_a_btn = "nul" +input_player2_a_axis = "nul" +input_player2_x = "nul" +input_player2_x_btn = "nul" +input_player2_x_axis = "nul" +input_player2_l = "nul" +input_player2_l_btn = "nul" +input_player2_l_axis = "nul" +input_player2_r = "nul" +input_player2_r_btn = "nul" +input_player2_r_axis = "nul" +input_player2_l2 = "nul" +input_player2_l2_btn = "nul" +input_player2_l2_axis = "nul" +input_player2_r2 = "nul" +input_player2_r2_btn = "nul" +input_player2_r2_axis = "nul" +input_player2_l3 = "nul" +input_player2_l3_btn = "nul" +input_player2_l3_axis = "nul" +input_player2_r3 = "nul" +input_player2_r3_btn = "nul" +input_player2_r3_axis = "nul" +input_player2_l_x_plus = "nul" +input_player2_l_x_plus_btn = "nul" +input_player2_l_x_plus_axis = "nul" +input_player2_l_x_minus = "nul" +input_player2_l_x_minus_btn = "nul" +input_player2_l_x_minus_axis = "nul" +input_player2_l_y_plus = "nul" +input_player2_l_y_plus_btn = "nul" +input_player2_l_y_plus_axis = "nul" +input_player2_l_y_minus = "nul" +input_player2_l_y_minus_btn = "nul" +input_player2_l_y_minus_axis = "nul" +input_player2_r_x_plus = "nul" +input_player2_r_x_plus_btn = "nul" +input_player2_r_x_plus_axis = "nul" +input_player2_r_x_minus = "nul" +input_player2_r_x_minus_btn = "nul" +input_player2_r_x_minus_axis = "nul" +input_player2_r_y_plus = "nul" +input_player2_r_y_plus_btn = "nul" +input_player2_r_y_plus_axis = "nul" +input_player2_r_y_minus = "nul" +input_player2_r_y_minus_btn = "nul" +input_player2_r_y_minus_axis = "nul" +input_player2_turbo = "nul" +input_player2_turbo_btn = "nul" +input_player2_turbo_axis = "nul" +input_player3_b = "nul" +input_player3_b_btn = "nul" +input_player3_b_axis = "nul" +input_player3_y = "nul" +input_player3_y_btn = "nul" +input_player3_y_axis = "nul" +input_player3_select = "nul" +input_player3_select_btn = "nul" +input_player3_select_axis = "nul" +input_player3_start = "nul" +input_player3_start_btn = "nul" +input_player3_start_axis = "nul" +input_player3_up = "nul" +input_player3_up_btn = "nul" +input_player3_up_axis = "nul" +input_player3_down = "nul" +input_player3_down_btn = "nul" +input_player3_down_axis = "nul" +input_player3_left = "nul" +input_player3_left_btn = "nul" +input_player3_left_axis = "nul" +input_player3_right = "nul" +input_player3_right_btn = "nul" +input_player3_right_axis = "nul" +input_player3_a = "nul" +input_player3_a_btn = "nul" +input_player3_a_axis = "nul" +input_player3_x = "nul" +input_player3_x_btn = "nul" +input_player3_x_axis = "nul" +input_player3_l = "nul" +input_player3_l_btn = "nul" +input_player3_l_axis = "nul" +input_player3_r = "nul" +input_player3_r_btn = "nul" +input_player3_r_axis = "nul" +input_player3_l2 = "nul" +input_player3_l2_btn = "nul" +input_player3_l2_axis = "nul" +input_player3_r2 = "nul" +input_player3_r2_btn = "nul" +input_player3_r2_axis = "nul" +input_player3_l3 = "nul" +input_player3_l3_btn = "nul" +input_player3_l3_axis = "nul" +input_player3_r3 = "nul" +input_player3_r3_btn = "nul" +input_player3_r3_axis = "nul" +input_player3_l_x_plus = "nul" +input_player3_l_x_plus_btn = "nul" +input_player3_l_x_plus_axis = "nul" +input_player3_l_x_minus = "nul" +input_player3_l_x_minus_btn = "nul" +input_player3_l_x_minus_axis = "nul" +input_player3_l_y_plus = "nul" +input_player3_l_y_plus_btn = "nul" +input_player3_l_y_plus_axis = "nul" +input_player3_l_y_minus = "nul" +input_player3_l_y_minus_btn = "nul" +input_player3_l_y_minus_axis = "nul" +input_player3_r_x_plus = "nul" +input_player3_r_x_plus_btn = "nul" +input_player3_r_x_plus_axis = "nul" +input_player3_r_x_minus = "nul" +input_player3_r_x_minus_btn = "nul" +input_player3_r_x_minus_axis = "nul" +input_player3_r_y_plus = "nul" +input_player3_r_y_plus_btn = "nul" +input_player3_r_y_plus_axis = "nul" +input_player3_r_y_minus = "nul" +input_player3_r_y_minus_btn = "nul" +input_player3_r_y_minus_axis = "nul" +input_player3_turbo = "nul" +input_player3_turbo_btn = "nul" +input_player3_turbo_axis = "nul" +input_player4_b = "nul" +input_player4_b_btn = "nul" +input_player4_b_axis = "nul" +input_player4_y = "nul" +input_player4_y_btn = "nul" +input_player4_y_axis = "nul" +input_player4_select = "nul" +input_player4_select_btn = "nul" +input_player4_select_axis = "nul" +input_player4_start = "nul" +input_player4_start_btn = "nul" +input_player4_start_axis = "nul" +input_player4_up = "nul" +input_player4_up_btn = "nul" +input_player4_up_axis = "nul" +input_player4_down = "nul" +input_player4_down_btn = "nul" +input_player4_down_axis = "nul" +input_player4_left = "nul" +input_player4_left_btn = "nul" +input_player4_left_axis = "nul" +input_player4_right = "nul" +input_player4_right_btn = "nul" +input_player4_right_axis = "nul" +input_player4_a = "nul" +input_player4_a_btn = "nul" +input_player4_a_axis = "nul" +input_player4_x = "nul" +input_player4_x_btn = "nul" +input_player4_x_axis = "nul" +input_player4_l = "nul" +input_player4_l_btn = "nul" +input_player4_l_axis = "nul" +input_player4_r = "nul" +input_player4_r_btn = "nul" +input_player4_r_axis = "nul" +input_player4_l2 = "nul" +input_player4_l2_btn = "nul" +input_player4_l2_axis = "nul" +input_player4_r2 = "nul" +input_player4_r2_btn = "nul" +input_player4_r2_axis = "nul" +input_player4_l3 = "nul" +input_player4_l3_btn = "nul" +input_player4_l3_axis = "nul" +input_player4_r3 = "nul" +input_player4_r3_btn = "nul" +input_player4_r3_axis = "nul" +input_player4_l_x_plus = "nul" +input_player4_l_x_plus_btn = "nul" +input_player4_l_x_plus_axis = "nul" +input_player4_l_x_minus = "nul" +input_player4_l_x_minus_btn = "nul" +input_player4_l_x_minus_axis = "nul" +input_player4_l_y_plus = "nul" +input_player4_l_y_plus_btn = "nul" +input_player4_l_y_plus_axis = "nul" +input_player4_l_y_minus = "nul" +input_player4_l_y_minus_btn = "nul" +input_player4_l_y_minus_axis = "nul" +input_player4_r_x_plus = "nul" +input_player4_r_x_plus_btn = "nul" +input_player4_r_x_plus_axis = "nul" +input_player4_r_x_minus = "nul" +input_player4_r_x_minus_btn = "nul" +input_player4_r_x_minus_axis = "nul" +input_player4_r_y_plus = "nul" +input_player4_r_y_plus_btn = "nul" +input_player4_r_y_plus_axis = "nul" +input_player4_r_y_minus = "nul" +input_player4_r_y_minus_btn = "nul" +input_player4_r_y_minus_axis = "nul" +input_player4_turbo = "nul" +input_player4_turbo_btn = "nul" +input_player4_turbo_axis = "nul" +input_player5_b = "nul" +input_player5_b_btn = "nul" +input_player5_b_axis = "nul" +input_player5_y = "nul" +input_player5_y_btn = "nul" +input_player5_y_axis = "nul" +input_player5_select = "nul" +input_player5_select_btn = "nul" +input_player5_select_axis = "nul" +input_player5_start = "nul" +input_player5_start_btn = "nul" +input_player5_start_axis = "nul" +input_player5_up = "nul" +input_player5_up_btn = "nul" +input_player5_up_axis = "nul" +input_player5_down = "nul" +input_player5_down_btn = "nul" +input_player5_down_axis = "nul" +input_player5_left = "nul" +input_player5_left_btn = "nul" +input_player5_left_axis = "nul" +input_player5_right = "nul" +input_player5_right_btn = "nul" +input_player5_right_axis = "nul" +input_player5_a = "nul" +input_player5_a_btn = "nul" +input_player5_a_axis = "nul" +input_player5_x = "nul" +input_player5_x_btn = "nul" +input_player5_x_axis = "nul" +input_player5_l = "nul" +input_player5_l_btn = "nul" +input_player5_l_axis = "nul" +input_player5_r = "nul" +input_player5_r_btn = "nul" +input_player5_r_axis = "nul" +input_player5_l2 = "nul" +input_player5_l2_btn = "nul" +input_player5_l2_axis = "nul" +input_player5_r2 = "nul" +input_player5_r2_btn = "nul" +input_player5_r2_axis = "nul" +input_player5_l3 = "nul" +input_player5_l3_btn = "nul" +input_player5_l3_axis = "nul" +input_player5_r3 = "nul" +input_player5_r3_btn = "nul" +input_player5_r3_axis = "nul" +input_player5_l_x_plus = "nul" +input_player5_l_x_plus_btn = "nul" +input_player5_l_x_plus_axis = "nul" +input_player5_l_x_minus = "nul" +input_player5_l_x_minus_btn = "nul" +input_player5_l_x_minus_axis = "nul" +input_player5_l_y_plus = "nul" +input_player5_l_y_plus_btn = "nul" +input_player5_l_y_plus_axis = "nul" +input_player5_l_y_minus = "nul" +input_player5_l_y_minus_btn = "nul" +input_player5_l_y_minus_axis = "nul" +input_player5_r_x_plus = "nul" +input_player5_r_x_plus_btn = "nul" +input_player5_r_x_plus_axis = "nul" +input_player5_r_x_minus = "nul" +input_player5_r_x_minus_btn = "nul" +input_player5_r_x_minus_axis = "nul" +input_player5_r_y_plus = "nul" +input_player5_r_y_plus_btn = "nul" +input_player5_r_y_plus_axis = "nul" +input_player5_r_y_minus = "nul" +input_player5_r_y_minus_btn = "nul" +input_player5_r_y_minus_axis = "nul" +input_player5_turbo = "nul" +input_player5_turbo_btn = "nul" +input_player5_turbo_axis = "nul" +input_player6_b = "nul" +input_player6_b_btn = "nul" +input_player6_b_axis = "nul" +input_player6_y = "nul" +input_player6_y_btn = "nul" +input_player6_y_axis = "nul" +input_player6_select = "nul" +input_player6_select_btn = "nul" +input_player6_select_axis = "nul" +input_player6_start = "nul" +input_player6_start_btn = "nul" +input_player6_start_axis = "nul" +input_player6_up = "nul" +input_player6_up_btn = "nul" +input_player6_up_axis = "nul" +input_player6_down = "nul" +input_player6_down_btn = "nul" +input_player6_down_axis = "nul" +input_player6_left = "nul" +input_player6_left_btn = "nul" +input_player6_left_axis = "nul" +input_player6_right = "nul" +input_player6_right_btn = "nul" +input_player6_right_axis = "nul" +input_player6_a = "nul" +input_player6_a_btn = "nul" +input_player6_a_axis = "nul" +input_player6_x = "nul" +input_player6_x_btn = "nul" +input_player6_x_axis = "nul" +input_player6_l = "nul" +input_player6_l_btn = "nul" +input_player6_l_axis = "nul" +input_player6_r = "nul" +input_player6_r_btn = "nul" +input_player6_r_axis = "nul" +input_player6_l2 = "nul" +input_player6_l2_btn = "nul" +input_player6_l2_axis = "nul" +input_player6_r2 = "nul" +input_player6_r2_btn = "nul" +input_player6_r2_axis = "nul" +input_player6_l3 = "nul" +input_player6_l3_btn = "nul" +input_player6_l3_axis = "nul" +input_player6_r3 = "nul" +input_player6_r3_btn = "nul" +input_player6_r3_axis = "nul" +input_player6_l_x_plus = "nul" +input_player6_l_x_plus_btn = "nul" +input_player6_l_x_plus_axis = "nul" +input_player6_l_x_minus = "nul" +input_player6_l_x_minus_btn = "nul" +input_player6_l_x_minus_axis = "nul" +input_player6_l_y_plus = "nul" +input_player6_l_y_plus_btn = "nul" +input_player6_l_y_plus_axis = "nul" +input_player6_l_y_minus = "nul" +input_player6_l_y_minus_btn = "nul" +input_player6_l_y_minus_axis = "nul" +input_player6_r_x_plus = "nul" +input_player6_r_x_plus_btn = "nul" +input_player6_r_x_plus_axis = "nul" +input_player6_r_x_minus = "nul" +input_player6_r_x_minus_btn = "nul" +input_player6_r_x_minus_axis = "nul" +input_player6_r_y_plus = "nul" +input_player6_r_y_plus_btn = "nul" +input_player6_r_y_plus_axis = "nul" +input_player6_r_y_minus = "nul" +input_player6_r_y_minus_btn = "nul" +input_player6_r_y_minus_axis = "nul" +input_player6_turbo = "nul" +input_player6_turbo_btn = "nul" +input_player6_turbo_axis = "nul" +input_player7_b = "nul" +input_player7_b_btn = "nul" +input_player7_b_axis = "nul" +input_player7_y = "nul" +input_player7_y_btn = "nul" +input_player7_y_axis = "nul" +input_player7_select = "nul" +input_player7_select_btn = "nul" +input_player7_select_axis = "nul" +input_player7_start = "nul" +input_player7_start_btn = "nul" +input_player7_start_axis = "nul" +input_player7_up = "nul" +input_player7_up_btn = "nul" +input_player7_up_axis = "nul" +input_player7_down = "nul" +input_player7_down_btn = "nul" +input_player7_down_axis = "nul" +input_player7_left = "nul" +input_player7_left_btn = "nul" +input_player7_left_axis = "nul" +input_player7_right = "nul" +input_player7_right_btn = "nul" +input_player7_right_axis = "nul" +input_player7_a = "nul" +input_player7_a_btn = "nul" +input_player7_a_axis = "nul" +input_player7_x = "nul" +input_player7_x_btn = "nul" +input_player7_x_axis = "nul" +input_player7_l = "nul" +input_player7_l_btn = "nul" +input_player7_l_axis = "nul" +input_player7_r = "nul" +input_player7_r_btn = "nul" +input_player7_r_axis = "nul" +input_player7_l2 = "nul" +input_player7_l2_btn = "nul" +input_player7_l2_axis = "nul" +input_player7_r2 = "nul" +input_player7_r2_btn = "nul" +input_player7_r2_axis = "nul" +input_player7_l3 = "nul" +input_player7_l3_btn = "nul" +input_player7_l3_axis = "nul" +input_player7_r3 = "nul" +input_player7_r3_btn = "nul" +input_player7_r3_axis = "nul" +input_player7_l_x_plus = "nul" +input_player7_l_x_plus_btn = "nul" +input_player7_l_x_plus_axis = "nul" +input_player7_l_x_minus = "nul" +input_player7_l_x_minus_btn = "nul" +input_player7_l_x_minus_axis = "nul" +input_player7_l_y_plus = "nul" +input_player7_l_y_plus_btn = "nul" +input_player7_l_y_plus_axis = "nul" +input_player7_l_y_minus = "nul" +input_player7_l_y_minus_btn = "nul" +input_player7_l_y_minus_axis = "nul" +input_player7_r_x_plus = "nul" +input_player7_r_x_plus_btn = "nul" +input_player7_r_x_plus_axis = "nul" +input_player7_r_x_minus = "nul" +input_player7_r_x_minus_btn = "nul" +input_player7_r_x_minus_axis = "nul" +input_player7_r_y_plus = "nul" +input_player7_r_y_plus_btn = "nul" +input_player7_r_y_plus_axis = "nul" +input_player7_r_y_minus = "nul" +input_player7_r_y_minus_btn = "nul" +input_player7_r_y_minus_axis = "nul" +input_player7_turbo = "nul" +input_player7_turbo_btn = "nul" +input_player7_turbo_axis = "nul" +input_player8_b = "nul" +input_player8_b_btn = "nul" +input_player8_b_axis = "nul" +input_player8_y = "nul" +input_player8_y_btn = "nul" +input_player8_y_axis = "nul" +input_player8_select = "nul" +input_player8_select_btn = "nul" +input_player8_select_axis = "nul" +input_player8_start = "nul" +input_player8_start_btn = "nul" +input_player8_start_axis = "nul" +input_player8_up = "nul" +input_player8_up_btn = "nul" +input_player8_up_axis = "nul" +input_player8_down = "nul" +input_player8_down_btn = "nul" +input_player8_down_axis = "nul" +input_player8_left = "nul" +input_player8_left_btn = "nul" +input_player8_left_axis = "nul" +input_player8_right = "nul" +input_player8_right_btn = "nul" +input_player8_right_axis = "nul" +input_player8_a = "nul" +input_player8_a_btn = "nul" +input_player8_a_axis = "nul" +input_player8_x = "nul" +input_player8_x_btn = "nul" +input_player8_x_axis = "nul" +input_player8_l = "nul" +input_player8_l_btn = "nul" +input_player8_l_axis = "nul" +input_player8_r = "nul" +input_player8_r_btn = "nul" +input_player8_r_axis = "nul" +input_player8_l2 = "nul" +input_player8_l2_btn = "nul" +input_player8_l2_axis = "nul" +input_player8_r2 = "nul" +input_player8_r2_btn = "nul" +input_player8_r2_axis = "nul" +input_player8_l3 = "nul" +input_player8_l3_btn = "nul" +input_player8_l3_axis = "nul" +input_player8_r3 = "nul" +input_player8_r3_btn = "nul" +input_player8_r3_axis = "nul" +input_player8_l_x_plus = "nul" +input_player8_l_x_plus_btn = "nul" +input_player8_l_x_plus_axis = "nul" +input_player8_l_x_minus = "nul" +input_player8_l_x_minus_btn = "nul" +input_player8_l_x_minus_axis = "nul" +input_player8_l_y_plus = "nul" +input_player8_l_y_plus_btn = "nul" +input_player8_l_y_plus_axis = "nul" +input_player8_l_y_minus = "nul" +input_player8_l_y_minus_btn = "nul" +input_player8_l_y_minus_axis = "nul" +input_player8_r_x_plus = "nul" +input_player8_r_x_plus_btn = "nul" +input_player8_r_x_plus_axis = "nul" +input_player8_r_x_minus = "nul" +input_player8_r_x_minus_btn = "nul" +input_player8_r_x_minus_axis = "nul" +input_player8_r_y_plus = "nul" +input_player8_r_y_plus_btn = "nul" +input_player8_r_y_plus_axis = "nul" +input_player8_r_y_minus = "nul" +input_player8_r_y_minus_btn = "nul" +input_player8_r_y_minus_axis = "nul" +input_player8_turbo = "nul" +input_player8_turbo_btn = "nul" +input_player8_turbo_axis = "nul" +input_player9_b = "nul" +input_player9_b_btn = "nul" +input_player9_b_axis = "nul" +input_player9_y = "nul" +input_player9_y_btn = "nul" +input_player9_y_axis = "nul" +input_player9_select = "nul" +input_player9_select_btn = "nul" +input_player9_select_axis = "nul" +input_player9_start = "nul" +input_player9_start_btn = "nul" +input_player9_start_axis = "nul" +input_player9_up = "nul" +input_player9_up_btn = "nul" +input_player9_up_axis = "nul" +input_player9_down = "nul" +input_player9_down_btn = "nul" +input_player9_down_axis = "nul" +input_player9_left = "nul" +input_player9_left_btn = "nul" +input_player9_left_axis = "nul" +input_player9_right = "nul" +input_player9_right_btn = "nul" +input_player9_right_axis = "nul" +input_player9_a = "nul" +input_player9_a_btn = "nul" +input_player9_a_axis = "nul" +input_player9_x = "nul" +input_player9_x_btn = "nul" +input_player9_x_axis = "nul" +input_player9_l = "nul" +input_player9_l_btn = "nul" +input_player9_l_axis = "nul" +input_player9_r = "nul" +input_player9_r_btn = "nul" +input_player9_r_axis = "nul" +input_player9_l2 = "nul" +input_player9_l2_btn = "nul" +input_player9_l2_axis = "nul" +input_player9_r2 = "nul" +input_player9_r2_btn = "nul" +input_player9_r2_axis = "nul" +input_player9_l3 = "nul" +input_player9_l3_btn = "nul" +input_player9_l3_axis = "nul" +input_player9_r3 = "nul" +input_player9_r3_btn = "nul" +input_player9_r3_axis = "nul" +input_player9_l_x_plus = "nul" +input_player9_l_x_plus_btn = "nul" +input_player9_l_x_plus_axis = "nul" +input_player9_l_x_minus = "nul" +input_player9_l_x_minus_btn = "nul" +input_player9_l_x_minus_axis = "nul" +input_player9_l_y_plus = "nul" +input_player9_l_y_plus_btn = "nul" +input_player9_l_y_plus_axis = "nul" +input_player9_l_y_minus = "nul" +input_player9_l_y_minus_btn = "nul" +input_player9_l_y_minus_axis = "nul" +input_player9_r_x_plus = "nul" +input_player9_r_x_plus_btn = "nul" +input_player9_r_x_plus_axis = "nul" +input_player9_r_x_minus = "nul" +input_player9_r_x_minus_btn = "nul" +input_player9_r_x_minus_axis = "nul" +input_player9_r_y_plus = "nul" +input_player9_r_y_plus_btn = "nul" +input_player9_r_y_plus_axis = "nul" +input_player9_r_y_minus = "nul" +input_player9_r_y_minus_btn = "nul" +input_player9_r_y_minus_axis = "nul" +input_player9_turbo = "nul" +input_player9_turbo_btn = "nul" +input_player9_turbo_axis = "nul" +input_player10_b = "nul" +input_player10_b_btn = "nul" +input_player10_b_axis = "nul" +input_player10_y = "nul" +input_player10_y_btn = "nul" +input_player10_y_axis = "nul" +input_player10_select = "nul" +input_player10_select_btn = "nul" +input_player10_select_axis = "nul" +input_player10_start = "nul" +input_player10_start_btn = "nul" +input_player10_start_axis = "nul" +input_player10_up = "nul" +input_player10_up_btn = "nul" +input_player10_up_axis = "nul" +input_player10_down = "nul" +input_player10_down_btn = "nul" +input_player10_down_axis = "nul" +input_player10_left = "nul" +input_player10_left_btn = "nul" +input_player10_left_axis = "nul" +input_player10_right = "nul" +input_player10_right_btn = "nul" +input_player10_right_axis = "nul" +input_player10_a = "nul" +input_player10_a_btn = "nul" +input_player10_a_axis = "nul" +input_player10_x = "nul" +input_player10_x_btn = "nul" +input_player10_x_axis = "nul" +input_player10_l = "nul" +input_player10_l_btn = "nul" +input_player10_l_axis = "nul" +input_player10_r = "nul" +input_player10_r_btn = "nul" +input_player10_r_axis = "nul" +input_player10_l2 = "nul" +input_player10_l2_btn = "nul" +input_player10_l2_axis = "nul" +input_player10_r2 = "nul" +input_player10_r2_btn = "nul" +input_player10_r2_axis = "nul" +input_player10_l3 = "nul" +input_player10_l3_btn = "nul" +input_player10_l3_axis = "nul" +input_player10_r3 = "nul" +input_player10_r3_btn = "nul" +input_player10_r3_axis = "nul" +input_player10_l_x_plus = "nul" +input_player10_l_x_plus_btn = "nul" +input_player10_l_x_plus_axis = "nul" +input_player10_l_x_minus = "nul" +input_player10_l_x_minus_btn = "nul" +input_player10_l_x_minus_axis = "nul" +input_player10_l_y_plus = "nul" +input_player10_l_y_plus_btn = "nul" +input_player10_l_y_plus_axis = "nul" +input_player10_l_y_minus = "nul" +input_player10_l_y_minus_btn = "nul" +input_player10_l_y_minus_axis = "nul" +input_player10_r_x_plus = "nul" +input_player10_r_x_plus_btn = "nul" +input_player10_r_x_plus_axis = "nul" +input_player10_r_x_minus = "nul" +input_player10_r_x_minus_btn = "nul" +input_player10_r_x_minus_axis = "nul" +input_player10_r_y_plus = "nul" +input_player10_r_y_plus_btn = "nul" +input_player10_r_y_plus_axis = "nul" +input_player10_r_y_minus = "nul" +input_player10_r_y_minus_btn = "nul" +input_player10_r_y_minus_axis = "nul" +input_player10_turbo = "nul" +input_player10_turbo_btn = "nul" +input_player10_turbo_axis = "nul" +input_player11_b = "nul" +input_player11_b_btn = "nul" +input_player11_b_axis = "nul" +input_player11_y = "nul" +input_player11_y_btn = "nul" +input_player11_y_axis = "nul" +input_player11_select = "nul" +input_player11_select_btn = "nul" +input_player11_select_axis = "nul" +input_player11_start = "nul" +input_player11_start_btn = "nul" +input_player11_start_axis = "nul" +input_player11_up = "nul" +input_player11_up_btn = "nul" +input_player11_up_axis = "nul" +input_player11_down = "nul" +input_player11_down_btn = "nul" +input_player11_down_axis = "nul" +input_player11_left = "nul" +input_player11_left_btn = "nul" +input_player11_left_axis = "nul" +input_player11_right = "nul" +input_player11_right_btn = "nul" +input_player11_right_axis = "nul" +input_player11_a = "nul" +input_player11_a_btn = "nul" +input_player11_a_axis = "nul" +input_player11_x = "nul" +input_player11_x_btn = "nul" +input_player11_x_axis = "nul" +input_player11_l = "nul" +input_player11_l_btn = "nul" +input_player11_l_axis = "nul" +input_player11_r = "nul" +input_player11_r_btn = "nul" +input_player11_r_axis = "nul" +input_player11_l2 = "nul" +input_player11_l2_btn = "nul" +input_player11_l2_axis = "nul" +input_player11_r2 = "nul" +input_player11_r2_btn = "nul" +input_player11_r2_axis = "nul" +input_player11_l3 = "nul" +input_player11_l3_btn = "nul" +input_player11_l3_axis = "nul" +input_player11_r3 = "nul" +input_player11_r3_btn = "nul" +input_player11_r3_axis = "nul" +input_player11_l_x_plus = "nul" +input_player11_l_x_plus_btn = "nul" +input_player11_l_x_plus_axis = "nul" +input_player11_l_x_minus = "nul" +input_player11_l_x_minus_btn = "nul" +input_player11_l_x_minus_axis = "nul" +input_player11_l_y_plus = "nul" +input_player11_l_y_plus_btn = "nul" +input_player11_l_y_plus_axis = "nul" +input_player11_l_y_minus = "nul" +input_player11_l_y_minus_btn = "nul" +input_player11_l_y_minus_axis = "nul" +input_player11_r_x_plus = "nul" +input_player11_r_x_plus_btn = "nul" +input_player11_r_x_plus_axis = "nul" +input_player11_r_x_minus = "nul" +input_player11_r_x_minus_btn = "nul" +input_player11_r_x_minus_axis = "nul" +input_player11_r_y_plus = "nul" +input_player11_r_y_plus_btn = "nul" +input_player11_r_y_plus_axis = "nul" +input_player11_r_y_minus = "nul" +input_player11_r_y_minus_btn = "nul" +input_player11_r_y_minus_axis = "nul" +input_player11_turbo = "nul" +input_player11_turbo_btn = "nul" +input_player11_turbo_axis = "nul" +input_player12_b = "nul" +input_player12_b_btn = "nul" +input_player12_b_axis = "nul" +input_player12_y = "nul" +input_player12_y_btn = "nul" +input_player12_y_axis = "nul" +input_player12_select = "nul" +input_player12_select_btn = "nul" +input_player12_select_axis = "nul" +input_player12_start = "nul" +input_player12_start_btn = "nul" +input_player12_start_axis = "nul" +input_player12_up = "nul" +input_player12_up_btn = "nul" +input_player12_up_axis = "nul" +input_player12_down = "nul" +input_player12_down_btn = "nul" +input_player12_down_axis = "nul" +input_player12_left = "nul" +input_player12_left_btn = "nul" +input_player12_left_axis = "nul" +input_player12_right = "nul" +input_player12_right_btn = "nul" +input_player12_right_axis = "nul" +input_player12_a = "nul" +input_player12_a_btn = "nul" +input_player12_a_axis = "nul" +input_player12_x = "nul" +input_player12_x_btn = "nul" +input_player12_x_axis = "nul" +input_player12_l = "nul" +input_player12_l_btn = "nul" +input_player12_l_axis = "nul" +input_player12_r = "nul" +input_player12_r_btn = "nul" +input_player12_r_axis = "nul" +input_player12_l2 = "nul" +input_player12_l2_btn = "nul" +input_player12_l2_axis = "nul" +input_player12_r2 = "nul" +input_player12_r2_btn = "nul" +input_player12_r2_axis = "nul" +input_player12_l3 = "nul" +input_player12_l3_btn = "nul" +input_player12_l3_axis = "nul" +input_player12_r3 = "nul" +input_player12_r3_btn = "nul" +input_player12_r3_axis = "nul" +input_player12_l_x_plus = "nul" +input_player12_l_x_plus_btn = "nul" +input_player12_l_x_plus_axis = "nul" +input_player12_l_x_minus = "nul" +input_player12_l_x_minus_btn = "nul" +input_player12_l_x_minus_axis = "nul" +input_player12_l_y_plus = "nul" +input_player12_l_y_plus_btn = "nul" +input_player12_l_y_plus_axis = "nul" +input_player12_l_y_minus = "nul" +input_player12_l_y_minus_btn = "nul" +input_player12_l_y_minus_axis = "nul" +input_player12_r_x_plus = "nul" +input_player12_r_x_plus_btn = "nul" +input_player12_r_x_plus_axis = "nul" +input_player12_r_x_minus = "nul" +input_player12_r_x_minus_btn = "nul" +input_player12_r_x_minus_axis = "nul" +input_player12_r_y_plus = "nul" +input_player12_r_y_plus_btn = "nul" +input_player12_r_y_plus_axis = "nul" +input_player12_r_y_minus = "nul" +input_player12_r_y_minus_btn = "nul" +input_player12_r_y_minus_axis = "nul" +input_player12_turbo = "nul" +input_player12_turbo_btn = "nul" +input_player12_turbo_axis = "nul" +input_player13_b = "nul" +input_player13_b_btn = "nul" +input_player13_b_axis = "nul" +input_player13_y = "nul" +input_player13_y_btn = "nul" +input_player13_y_axis = "nul" +input_player13_select = "nul" +input_player13_select_btn = "nul" +input_player13_select_axis = "nul" +input_player13_start = "nul" +input_player13_start_btn = "nul" +input_player13_start_axis = "nul" +input_player13_up = "nul" +input_player13_up_btn = "nul" +input_player13_up_axis = "nul" +input_player13_down = "nul" +input_player13_down_btn = "nul" +input_player13_down_axis = "nul" +input_player13_left = "nul" +input_player13_left_btn = "nul" +input_player13_left_axis = "nul" +input_player13_right = "nul" +input_player13_right_btn = "nul" +input_player13_right_axis = "nul" +input_player13_a = "nul" +input_player13_a_btn = "nul" +input_player13_a_axis = "nul" +input_player13_x = "nul" +input_player13_x_btn = "nul" +input_player13_x_axis = "nul" +input_player13_l = "nul" +input_player13_l_btn = "nul" +input_player13_l_axis = "nul" +input_player13_r = "nul" +input_player13_r_btn = "nul" +input_player13_r_axis = "nul" +input_player13_l2 = "nul" +input_player13_l2_btn = "nul" +input_player13_l2_axis = "nul" +input_player13_r2 = "nul" +input_player13_r2_btn = "nul" +input_player13_r2_axis = "nul" +input_player13_l3 = "nul" +input_player13_l3_btn = "nul" +input_player13_l3_axis = "nul" +input_player13_r3 = "nul" +input_player13_r3_btn = "nul" +input_player13_r3_axis = "nul" +input_player13_l_x_plus = "nul" +input_player13_l_x_plus_btn = "nul" +input_player13_l_x_plus_axis = "nul" +input_player13_l_x_minus = "nul" +input_player13_l_x_minus_btn = "nul" +input_player13_l_x_minus_axis = "nul" +input_player13_l_y_plus = "nul" +input_player13_l_y_plus_btn = "nul" +input_player13_l_y_plus_axis = "nul" +input_player13_l_y_minus = "nul" +input_player13_l_y_minus_btn = "nul" +input_player13_l_y_minus_axis = "nul" +input_player13_r_x_plus = "nul" +input_player13_r_x_plus_btn = "nul" +input_player13_r_x_plus_axis = "nul" +input_player13_r_x_minus = "nul" +input_player13_r_x_minus_btn = "nul" +input_player13_r_x_minus_axis = "nul" +input_player13_r_y_plus = "nul" +input_player13_r_y_plus_btn = "nul" +input_player13_r_y_plus_axis = "nul" +input_player13_r_y_minus = "nul" +input_player13_r_y_minus_btn = "nul" +input_player13_r_y_minus_axis = "nul" +input_player13_turbo = "nul" +input_player13_turbo_btn = "nul" +input_player13_turbo_axis = "nul" +input_player14_b = "nul" +input_player14_b_btn = "nul" +input_player14_b_axis = "nul" +input_player14_y = "nul" +input_player14_y_btn = "nul" +input_player14_y_axis = "nul" +input_player14_select = "nul" +input_player14_select_btn = "nul" +input_player14_select_axis = "nul" +input_player14_start = "nul" +input_player14_start_btn = "nul" +input_player14_start_axis = "nul" +input_player14_up = "nul" +input_player14_up_btn = "nul" +input_player14_up_axis = "nul" +input_player14_down = "nul" +input_player14_down_btn = "nul" +input_player14_down_axis = "nul" +input_player14_left = "nul" +input_player14_left_btn = "nul" +input_player14_left_axis = "nul" +input_player14_right = "nul" +input_player14_right_btn = "nul" +input_player14_right_axis = "nul" +input_player14_a = "nul" +input_player14_a_btn = "nul" +input_player14_a_axis = "nul" +input_player14_x = "nul" +input_player14_x_btn = "nul" +input_player14_x_axis = "nul" +input_player14_l = "nul" +input_player14_l_btn = "nul" +input_player14_l_axis = "nul" +input_player14_r = "nul" +input_player14_r_btn = "nul" +input_player14_r_axis = "nul" +input_player14_l2 = "nul" +input_player14_l2_btn = "nul" +input_player14_l2_axis = "nul" +input_player14_r2 = "nul" +input_player14_r2_btn = "nul" +input_player14_r2_axis = "nul" +input_player14_l3 = "nul" +input_player14_l3_btn = "nul" +input_player14_l3_axis = "nul" +input_player14_r3 = "nul" +input_player14_r3_btn = "nul" +input_player14_r3_axis = "nul" +input_player14_l_x_plus = "nul" +input_player14_l_x_plus_btn = "nul" +input_player14_l_x_plus_axis = "nul" +input_player14_l_x_minus = "nul" +input_player14_l_x_minus_btn = "nul" +input_player14_l_x_minus_axis = "nul" +input_player14_l_y_plus = "nul" +input_player14_l_y_plus_btn = "nul" +input_player14_l_y_plus_axis = "nul" +input_player14_l_y_minus = "nul" +input_player14_l_y_minus_btn = "nul" +input_player14_l_y_minus_axis = "nul" +input_player14_r_x_plus = "nul" +input_player14_r_x_plus_btn = "nul" +input_player14_r_x_plus_axis = "nul" +input_player14_r_x_minus = "nul" +input_player14_r_x_minus_btn = "nul" +input_player14_r_x_minus_axis = "nul" +input_player14_r_y_plus = "nul" +input_player14_r_y_plus_btn = "nul" +input_player14_r_y_plus_axis = "nul" +input_player14_r_y_minus = "nul" +input_player14_r_y_minus_btn = "nul" +input_player14_r_y_minus_axis = "nul" +input_player14_turbo = "nul" +input_player14_turbo_btn = "nul" +input_player14_turbo_axis = "nul" +input_player15_b = "nul" +input_player15_b_btn = "nul" +input_player15_b_axis = "nul" +input_player15_y = "nul" +input_player15_y_btn = "nul" +input_player15_y_axis = "nul" +input_player15_select = "nul" +input_player15_select_btn = "nul" +input_player15_select_axis = "nul" +input_player15_start = "nul" +input_player15_start_btn = "nul" +input_player15_start_axis = "nul" +input_player15_up = "nul" +input_player15_up_btn = "nul" +input_player15_up_axis = "nul" +input_player15_down = "nul" +input_player15_down_btn = "nul" +input_player15_down_axis = "nul" +input_player15_left = "nul" +input_player15_left_btn = "nul" +input_player15_left_axis = "nul" +input_player15_right = "nul" +input_player15_right_btn = "nul" +input_player15_right_axis = "nul" +input_player15_a = "nul" +input_player15_a_btn = "nul" +input_player15_a_axis = "nul" +input_player15_x = "nul" +input_player15_x_btn = "nul" +input_player15_x_axis = "nul" +input_player15_l = "nul" +input_player15_l_btn = "nul" +input_player15_l_axis = "nul" +input_player15_r = "nul" +input_player15_r_btn = "nul" +input_player15_r_axis = "nul" +input_player15_l2 = "nul" +input_player15_l2_btn = "nul" +input_player15_l2_axis = "nul" +input_player15_r2 = "nul" +input_player15_r2_btn = "nul" +input_player15_r2_axis = "nul" +input_player15_l3 = "nul" +input_player15_l3_btn = "nul" +input_player15_l3_axis = "nul" +input_player15_r3 = "nul" +input_player15_r3_btn = "nul" +input_player15_r3_axis = "nul" +input_player15_l_x_plus = "nul" +input_player15_l_x_plus_btn = "nul" +input_player15_l_x_plus_axis = "nul" +input_player15_l_x_minus = "nul" +input_player15_l_x_minus_btn = "nul" +input_player15_l_x_minus_axis = "nul" +input_player15_l_y_plus = "nul" +input_player15_l_y_plus_btn = "nul" +input_player15_l_y_plus_axis = "nul" +input_player15_l_y_minus = "nul" +input_player15_l_y_minus_btn = "nul" +input_player15_l_y_minus_axis = "nul" +input_player15_r_x_plus = "nul" +input_player15_r_x_plus_btn = "nul" +input_player15_r_x_plus_axis = "nul" +input_player15_r_x_minus = "nul" +input_player15_r_x_minus_btn = "nul" +input_player15_r_x_minus_axis = "nul" +input_player15_r_y_plus = "nul" +input_player15_r_y_plus_btn = "nul" +input_player15_r_y_plus_axis = "nul" +input_player15_r_y_minus = "nul" +input_player15_r_y_minus_btn = "nul" +input_player15_r_y_minus_axis = "nul" +input_player15_turbo = "nul" +input_player15_turbo_btn = "nul" +input_player15_turbo_axis = "nul" +input_player16_b = "nul" +input_player16_b_btn = "nul" +input_player16_b_axis = "nul" +input_player16_y = "nul" +input_player16_y_btn = "nul" +input_player16_y_axis = "nul" +input_player16_select = "nul" +input_player16_select_btn = "nul" +input_player16_select_axis = "nul" +input_player16_start = "nul" +input_player16_start_btn = "nul" +input_player16_start_axis = "nul" +input_player16_up = "nul" +input_player16_up_btn = "nul" +input_player16_up_axis = "nul" +input_player16_down = "nul" +input_player16_down_btn = "nul" +input_player16_down_axis = "nul" +input_player16_left = "nul" +input_player16_left_btn = "nul" +input_player16_left_axis = "nul" +input_player16_right = "nul" +input_player16_right_btn = "nul" +input_player16_right_axis = "nul" +input_player16_a = "nul" +input_player16_a_btn = "nul" +input_player16_a_axis = "nul" +input_player16_x = "nul" +input_player16_x_btn = "nul" +input_player16_x_axis = "nul" +input_player16_l = "nul" +input_player16_l_btn = "nul" +input_player16_l_axis = "nul" +input_player16_r = "nul" +input_player16_r_btn = "nul" +input_player16_r_axis = "nul" +input_player16_l2 = "nul" +input_player16_l2_btn = "nul" +input_player16_l2_axis = "nul" +input_player16_r2 = "nul" +input_player16_r2_btn = "nul" +input_player16_r2_axis = "nul" +input_player16_l3 = "nul" +input_player16_l3_btn = "nul" +input_player16_l3_axis = "nul" +input_player16_r3 = "nul" +input_player16_r3_btn = "nul" +input_player16_r3_axis = "nul" +input_player16_l_x_plus = "nul" +input_player16_l_x_plus_btn = "nul" +input_player16_l_x_plus_axis = "nul" +input_player16_l_x_minus = "nul" +input_player16_l_x_minus_btn = "nul" +input_player16_l_x_minus_axis = "nul" +input_player16_l_y_plus = "nul" +input_player16_l_y_plus_btn = "nul" +input_player16_l_y_plus_axis = "nul" +input_player16_l_y_minus = "nul" +input_player16_l_y_minus_btn = "nul" +input_player16_l_y_minus_axis = "nul" +input_player16_r_x_plus = "nul" +input_player16_r_x_plus_btn = "nul" +input_player16_r_x_plus_axis = "nul" +input_player16_r_x_minus = "nul" +input_player16_r_x_minus_btn = "nul" +input_player16_r_x_minus_axis = "nul" +input_player16_r_y_plus = "nul" +input_player16_r_y_plus_btn = "nul" +input_player16_r_y_plus_axis = "nul" +input_player16_r_y_minus = "nul" +input_player16_r_y_minus_btn = "nul" +input_player16_r_y_minus_axis = "nul" +input_player16_turbo = "nul" +input_player16_turbo_btn = "nul" +input_player16_turbo_axis = "nul" +xmb_font = "" +netplay_nickname = "" +video_filter = "" +audio_dsp_plugin = "" +netplay_ip_address = "" +netplay_password = "" +netplay_spectate_password = "" +core_options_path = "" +video_shader = "" +menu_wallpaper = "" +input_overlay = "" +video_font_path = "" +content_history_dir = "" +cache_directory = "" +resampler_directory = "" +recording_output_directory = "" +recording_config_directory = "" +xmb_font = "" +playlist_names = "" +playlist_cores = "" +audio_device = "" +camera_device = "" +cheevos_username = "" +cheevos_password = "" +video_context_driver = "" +input_keyboard_layout = "" +bundle_assets_src_path = "" +bundle_assets_dst_path = "" +bundle_assets_dst_path_subdir = "" diff --git a/runloop.c b/runloop.c index cfa6ba3283..bb9bce5e28 100644 --- a/runloop.c +++ b/runloop.c @@ -37,7 +37,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "cheevos.h" +#include "cheevos/cheevos.h" #endif #ifdef HAVE_MENU diff --git a/tasks/task_content.c b/tasks/task_content.c index bfef13e18d..0fa393c798 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -66,7 +66,7 @@ #endif #ifdef HAVE_CHEEVOS -#include "../cheevos.h" +#include "../cheevos/cheevos.h" #endif #include "tasks_internal.h" From 233c13228e2f1aec70c513711205c650bd6455fa Mon Sep 17 00:00:00 2001 From: zeromus Date: Fri, 3 Feb 2017 21:52:52 -0600 Subject: [PATCH 07/90] attempt win32 scond_wait_timeout --- libretro-common/rthreads/rthreads.c | 135 +++++++++++++++++++++------- 1 file changed, 103 insertions(+), 32 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index e6ae676625..32a306cfb1 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -38,6 +38,7 @@ #else #define WIN32_LEAN_AND_MEAN #include +#include #endif #elif defined(GEKKO) #include "gx_pthread.h" @@ -84,17 +85,18 @@ struct slock #endif }; +#ifdef USE_WIN32_THREADS +/* The syntax we'll use is mind-bending unless we use a struct. Plus, we might want to store more info later */ +/* This will be used as a linked list immplementing a queue of waiting threads */ +struct QueueEntry +{ + struct QueueEntry *next; +}; +#endif + struct scond { #ifdef USE_WIN32_THREADS - - /* The syntax we'll use is mind-bending unless we use a struct. Plus, we might want to store more info later */ - /* This will be used as a linked list immplementing a queue of waiting threads */ - struct QueueEntry - { - struct QueueEntry *next; - }; - /* With this implementation of scond, we don't have any way of waking (or even identifying) specific threads */ /* But we need to wake them in the order indicated by the queue. */ /* This potato token will get get passed around every waiter. The bearer can test whether he's next, and hold onto the potato if he is. */ @@ -110,7 +112,7 @@ struct scond /* equivalent to the queue length */ int waiters; - /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet */ + /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet) */ int wakens; /* used to control access to this scond, in case the user fails */ @@ -359,7 +361,7 @@ scond_t *scond_new(void) /* whereas a win32 event can pre-wake a thread (the event will be set in advance, so a 'waiter' won't even have to wait on it) */ /* Keep in mind a condition variable can apparently pre-wake a thread, insofar as spurious wakeups are always possible, */ /* but nobody will be expecting this and it does not need to be simulated. */ - /* Moreover, we won't be doing this, because it counts as a spurious wakeup -- someone else with a genuine claim must get wakened, in any case. + /* Moreover, we won't be doing this, because it counts as a spurious wakeup -- someone else with a genuine claim must get wakened, in any case. */ /* Therefore we choose to wake only one of the correct waiting threads. */ /* So at the very least, we need to do something clever. But there's bigger problems. */ /* We don't even have a straightforward way in win32 to satisfy pthread_cond_wait's atomicity requirement. The bulk of this algorithm is solving that. */ @@ -410,24 +412,33 @@ void scond_free(scond_t *cond) free(cond); } -/** - * scond_wait: - * @cond : pointer to condition variable object - * @lock : pointer to mutex object - * - * Block on a condition variable (i.e. wait on a condition). - **/ -void scond_wait(scond_t *cond, slock_t *lock) -{ #ifdef USE_WIN32_THREADS - +static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds) +{ + static bool beginPeriod = false; + struct QueueEntry myentry; struct QueueEntry **ptr; + DWORD tsBegin; + DWORD dwFinalTimeout = dwMilliseconds; /* Careful! in case we begin in the head, we don't do the hot potato stuff, so this timeout needs presetting */ + DWORD waitResult; /* Reminder: `lock` is held before this is called. */ /* however, someone else may have called scond_signal without the lock. soo... */ EnterCriticalSection(&cond->cs); + /* since this library is meant for realtime game software I have no problem setting this to 1 and forgetting about it. */ + if(!beginPeriod) + { + beginPeriod = true; + timeBeginPeriod(1); + } + + /* Now we can take a good timestamp for use in faking the timeout ourselves. */ + /* But don't bother unless we need to (to save a little time) */ + if(dwMilliseconds != INFINITE) + tsBegin = timeGetTime(); + /* add ourselves to a queue of waiting threads */ ptr = &cond->head; while(*ptr) /* walk to the end of the linked list */ @@ -450,10 +461,25 @@ void scond_wait(scond_t *cond, slock_t *lock) { /* It isn't my turn: */ + DWORD timeout = INFINITE; + /* As long as someone is even going to be able to wake up when they receive the potato, keep it going round */ if (cond->wakens > 0) SetEvent(cond->hot_potato); + /* Assess the remaining timeout time */ + if(dwMilliseconds != INFINITE) + { + DWORD now = timeGetTime(); + DWORD elapsed = now - tsBegin; + if(elapsed > dwMilliseconds) + { + /* Try one last time with a zero timeout (keeps the code simpler) */ + elapsed = dwMilliseconds; + } + timeout = dwMilliseconds - elapsed; + } + /* Let someone else go */ LeaveCriticalSection(&lock->lock); LeaveCriticalSection(&cond->cs); @@ -461,14 +487,39 @@ void scond_wait(scond_t *cond, slock_t *lock) /* Wait a while to catch the hot potato.. someone else should get a chance to go */ /* After all, it isn't my turn (and it must be someone else's) */ Sleep(0); - WaitForSingleObject(cond->hot_potato, INFINITE); + waitResult = WaitForSingleObject(cond->hot_potato, timeout); /* I should come out of here with the main lock taken */ EnterCriticalSection(&lock->lock); EnterCriticalSection(&cond->cs); + + if(waitResult == WAIT_TIMEOUT) + { + /* Out of time! Now, let's think about this. I do have the potato now--maybe it's my turn, and I have the event? */ + /* If that's the case, I could proceed right now without aborting due to timeout. */ + /* However.. I DID wait a real long time. The caller was willing to wait that long. */ + /* I choose to give him one last chance with a zero timeout in the next step */ + if(cond->head == &myentry) + { + dwFinalTimeout = 0; + break; + } + else + { + /* It's not our turn and we're out of time. Give up. */ + /* Remove ourself from the queue and bail. */ + struct QueueEntry* curr = cond->head; + while(curr->next != &myentry) curr = curr->next; + curr->next = myentry.next; + cond->waiters--; + LeaveCriticalSection(&cond->cs); + return false; + } + } + } - /* It's my turn now -- I hold the potato */ + /* It's my turn now -- and I hold the potato */ /* I still have the main lock, in any case */ /* I need to release it so that someone can set the event */ @@ -477,7 +528,7 @@ void scond_wait(scond_t *cond, slock_t *lock) /* Wait for someone to actually signal this condition */ /* We're the only waiter waiting on the event right now -- everyone else is waiting on something different */ - WaitForSingleObject(cond->event, INFINITE); + waitResult = WaitForSingleObject(cond->event, dwFinalTimeout); /* Take the main lock so we can do work. Nobody else waits on this lock for very long, so even though it's GO TIME we won't have to wait long */ EnterCriticalSection(&lock->lock); @@ -487,8 +538,16 @@ void scond_wait(scond_t *cond, slock_t *lock) cond->head = myentry.next; cond->waiters--; + if(waitResult == WAIT_TIMEOUT) + { + /* Oops! ran out of time in the final wait. Just bail. */ + LeaveCriticalSection(&cond->cs); + return false; + } + /* If any other wakenings are pending, go ahead and set it up */ /* There may actually be no waiters. That's OK. The first waiter will come in, find it's his turn, and immediately get the signaled event */ + printf("%d\n",cond->wakens); cond->wakens--; if (cond->wakens > 0) { @@ -499,7 +558,21 @@ void scond_wait(scond_t *cond, slock_t *lock) } LeaveCriticalSection(&cond->cs); + return true; +} +#endif +/** + * scond_wait: + * @cond : pointer to condition variable object + * @lock : pointer to mutex object + * + * Block on a condition variable (i.e. wait on a condition). + **/ +void scond_wait(scond_t *cond, slock_t *lock) +{ +#ifdef USE_WIN32_THREADS + _scond_wait_win32(cond, lock, INFINITE); #else pthread_cond_wait(&cond->cond, &lock->lock); #endif @@ -589,15 +662,13 @@ void scond_signal(scond_t *cond) bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) { #ifdef USE_WIN32_THREADS - DWORD ret; - - /* TODO: this is woefully inadequate. It needs to be solved with the newer approach used above. */ - WaitForSingleObject(cond->event, 0); - LeaveCriticalSection(&lock->lock); - ret = WaitForSingleObject(cond->event,(DWORD)(timeout_us) / 1000); - - EnterCriticalSection(&lock->lock); - return ret == WAIT_OBJECT_0; + /* How to convert a us timeout to ms? */ + /* Someone asking for a 0 timeout clearly wants no timeout. */ + /* Someone asking for a 1 timeout clearly wants an actual timeout of the minimum length */ + /* Someone asking for 1000 or 1001 timeout shouldn't accidentally get 2ms. */ + DWORD dwMilliseconds = timeout_us/1000; + if(timeout_us < 1000) dwMilliseconds = 1; + return _scond_wait_win32(cond,lock,dwMilliseconds); #else int ret; int64_t seconds, remainder; From a06380e9cab1e5a59c70826fb2735566221e4149 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Feb 2017 09:00:49 +0100 Subject: [PATCH 08/90] Fix ./configure --enable-python --- gfx/drivers_tracker/video_state_python.c | 26 +++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/gfx/drivers_tracker/video_state_python.c b/gfx/drivers_tracker/video_state_python.c index dc86caa010..8c62bb7bdd 100644 --- a/gfx/drivers_tracker/video_state_python.c +++ b/gfx/drivers_tracker/video_state_python.c @@ -27,6 +27,8 @@ #include #include "video_state_python.h" + +#include "../../configuration.h" #include "../../dynamic.h" #include "../../core.h" #include "../../verbosity.h" @@ -106,9 +108,10 @@ static PyObject* py_read_vram(PyObject *self, PyObject *args) static PyObject *py_read_input(PyObject *self, PyObject *args) { unsigned user, key, i; + rarch_joypad_info_t joypad_info; const struct retro_keybind *py_binds[MAX_USERS]; - int16_t res = 0; - settings_t *settings = config_get_ptr(); + int16_t res = 0; + settings_t *settings = config_get_ptr(); for (i = 0; i < MAX_USERS; i++) py_binds[i] = settings->input.binds[i]; @@ -121,8 +124,12 @@ static PyObject *py_read_input(PyObject *self, PyObject *args) if (user > MAX_USERS || user < 1 || key >= RARCH_FIRST_META_KEY) return NULL; + joypad_info.joy_idx = settings->input.joypad_map[user - 1]; + joypad_info.auto_binds = settings->input.autoconf_binds[joypad_info.joy_idx]; + if (!input_driver_is_libretro_input_blocked()) - res = current_input->input_state(current_input_data, py_binds, + res = current_input->input_state(current_input_data, joypad_info, + py_binds, user - 1, RETRO_DEVICE_JOYPAD, 0, key); return PyBool_FromLong(res); } @@ -130,9 +137,10 @@ static PyObject *py_read_input(PyObject *self, PyObject *args) static PyObject *py_read_analog(PyObject *self, PyObject *args) { unsigned user, index, id, i; - int16_t res = 0; - settings_t *settings = config_get_ptr(); + rarch_joypad_info_t joypad_info; const struct retro_keybind *py_binds[MAX_USERS]; + int16_t res = 0; + settings_t *settings = config_get_ptr(); for (i = 0; i < MAX_USERS; i++) py_binds[i] = settings->input.binds[i]; @@ -145,8 +153,12 @@ static PyObject *py_read_analog(PyObject *self, PyObject *args) if (user > MAX_USERS || user < 1 || index > 1 || id > 1) return NULL; - res = current_input->input_state(current_input_data, py_binds, - user - 1, RETRO_DEVICE_ANALOG, index, id) + joypad_info.joy_idx = settings->input.joypad_map[user - 1]; + joypad_info.auto_binds = settings->input.autoconf_binds[joypad_info.joy_idx]; + + res = current_input->input_state(current_input_data, + joypad_info, py_binds, + user - 1, RETRO_DEVICE_ANALOG, index, id); return PyFloat_FromDouble((double)res / 0x7fff); } From e3a1b1859d9ccdb86418ff59491b60b7d981a726 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Feb 2017 09:20:41 +0100 Subject: [PATCH 09/90] Fix ./configure --disable-rgui --- input/input_driver.c | 6 ++++ input/input_overlay.c | 1 + network/netplay/netplay_handshake.c | 25 +++++++++++++--- runloop.c | 6 +++- setting_list.c | 45 +++++++++++++++++++++++++++++ tasks/task_netplay_lan_scan.c | 20 ++++++++++--- tasks/task_wifi.c | 17 +++++++---- 7 files changed, 105 insertions(+), 15 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 485a49d19a..470986d2d9 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -606,6 +606,7 @@ static INLINE bool input_menu_keys_pressed_internal( return false; } +#ifdef HAVE_MENU static bool input_driver_toggle_button_combo( unsigned mode, uint64_t *trigger_input) { @@ -650,6 +651,7 @@ static bool input_driver_toggle_button_combo( return true; } +#endif /** * input_menu_keys_pressed: @@ -723,6 +725,7 @@ uint64_t input_menu_keys_pressed( input_driver_block_hotkey = true; } +#ifdef HAVE_MENU if ( ((settings->input.menu_toggle_gamepad_combo != INPUT_TOGGLE_NONE) && input_driver_toggle_button_combo( settings->input.menu_toggle_gamepad_combo, &old_input)) @@ -731,6 +734,7 @@ uint64_t input_menu_keys_pressed( settings->input.binds[0][RARCH_MENU_TOGGLE].valid, settings->input.all_users_control_menu)) ret |= (UINT64_C(1) << RARCH_MENU_TOGGLE); +#endif for (i = 0; i < RARCH_BIND_LIST_END; i++) { @@ -944,11 +948,13 @@ uint64_t input_keys_pressed( input_driver_block_hotkey = false; } +#ifdef HAVE_MENU if ( ((settings->input.menu_toggle_gamepad_combo != INPUT_TOGGLE_NONE) && input_driver_toggle_button_combo(settings->input.menu_toggle_gamepad_combo, &old_input)) || input_keys_pressed_internal(settings, joypad_info, RARCH_MENU_TOGGLE, binds)) ret |= (UINT64_C(1) << RARCH_MENU_TOGGLE); +#endif for (i = 0; i < RARCH_BIND_LIST_END; i++) { diff --git a/input/input_overlay.c b/input/input_overlay.c index 3a04b2738c..a252ebbb3d 100644 --- a/input/input_overlay.c +++ b/input/input_overlay.c @@ -30,6 +30,7 @@ #endif #include "../verbosity.h" +#include "../gfx/video_driver.h" #include "input_overlay.h" #include "input_keyboard.h" diff --git a/network/netplay/netplay_handshake.c b/network/netplay/netplay_handshake.c index ad58ea3cf0..4df482e0e9 100644 --- a/network/netplay/netplay_handshake.c +++ b/network/netplay/netplay_handshake.c @@ -25,13 +25,20 @@ #include "netplay_private.h" +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + #include "../../autosave.h" #include "../../configuration.h" #include "../../content.h" #include "../../retroarch.h" #include "../../runloop.h" #include "../../version.h" + +#ifdef HAVE_MENU #include "../../menu/widgets/menu_input_dialog.h" +#endif #ifndef HAVE_SOCKET_LEGACY /* Custom inet_ntop. Win32 doesn't seem to support this ... */ @@ -265,8 +272,9 @@ struct info_buf_s } \ else if (recvd < 0) -static netplay_t *handshake_password_netplay; +static netplay_t *handshake_password_netplay = NULL; +#ifdef HAVE_MENU static void handshake_password(void *ignore, const char *line) { struct password_buf_s password_buf; @@ -285,9 +293,12 @@ static void handshake_password(void *ignore, const char *line) if (netplay_send(&connection->send_packet_buffer, connection->fd, &password_buf, sizeof(password_buf))) netplay_send_flush(&connection->send_packet_buffer, connection->fd, false); +#ifdef HAVE_MENU menu_input_dialog_end(); rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); +#endif } +#endif /** * netplay_handshake_init @@ -381,15 +392,21 @@ bool netplay_handshake_init(netplay_t *netplay, /* If a password is demanded, ask for it */ if (!netplay->is_server && (connection->salt = ntohl(header[3]))) { +#ifdef HAVE_MENU menu_input_ctx_line_t line; rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); - memset(&line, 0, sizeof(line)); +#endif + handshake_password_netplay = netplay; - line.label = msg_hash_to_str(MSG_NETPLAY_ENTER_PASSWORD); + +#ifdef HAVE_MENU + memset(&line, 0, sizeof(line)); + line.label = msg_hash_to_str(MSG_NETPLAY_ENTER_PASSWORD); line.label_setting = "no_setting"; - line.cb = handshake_password; + line.cb = handshake_password; if (!menu_input_dialog_start(&line)) return false; +#endif } /* Send our nick */ diff --git a/runloop.c b/runloop.c index bb9bce5e28..a4c60ab324 100644 --- a/runloop.c +++ b/runloop.c @@ -711,7 +711,11 @@ static enum runloop_state runloop_check_state( if (runloop_cmd_triggered(trigger_input, RARCH_FULLSCREEN_TOGGLE_KEY)) { - bool fullscreen_toggled = !runloop_paused || menu_driver_is_alive(); + bool fullscreen_toggled = !runloop_paused +#ifdef HAVE_MENU + || menu_driver_is_alive(); +#endif + ; if (fullscreen_toggled) command_event(CMD_EVENT_FULLSCREEN_TOGGLE, NULL); diff --git a/setting_list.c b/setting_list.c index 1b7af3fd02..9cb30d5a7e 100644 --- a/setting_list.c +++ b/setting_list.c @@ -124,13 +124,17 @@ static int setting_bind_action_ok(void *data, bool wraparound) static int setting_int_action_right_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; +#ifdef HAVE_MENU double min = 0.0f; +#endif double max = 0.0f; if (!setting) return -1; +#ifdef HAVE_MENU min = setting->min; +#endif max = setting->max; (void)wraparound; /* TODO/FIXME - handle this */ @@ -231,13 +235,17 @@ static int setting_uint_action_left_default(void *data, bool wraparound) static int setting_uint_action_right_default(void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; +#ifdef HAVE_MENU double min = 0.0f; +#endif double max = 0.0f; if (!setting) return -1; +#ifdef HAVE_MENU min = setting->min; +#endif max = setting->max; (void)wraparound; /* TODO/FIXME - handle this */ @@ -419,13 +427,17 @@ static int setting_fraction_action_right_default( void *data, bool wraparound) { rarch_setting_t *setting = (rarch_setting_t*)data; +#ifdef HAVE_MENU double min = 0.0f; +#endif double max = 0.0f; if (!setting) return -1; +#ifdef HAVE_MENU min = setting->min; +#endif max = setting->max; (void)wraparound; /* TODO/FIXME - handle this */ @@ -1526,8 +1538,12 @@ bool CONFIG_BOOL( (*list)[list_info->index++] = value; if (flags != SD_FLAG_NONE) settings_data_list_current_add_flags(list, list_info, flags); + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } @@ -1555,8 +1571,12 @@ bool CONFIG_INT( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } @@ -1608,8 +1628,12 @@ bool CONFIG_UINT( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } @@ -1634,8 +1658,12 @@ bool CONFIG_FLOAT( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } @@ -1664,8 +1692,10 @@ bool CONFIG_PATH( value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_EMPTY); +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif return true; } @@ -1700,8 +1730,10 @@ bool CONFIG_DIR( list_info, SD_FLAG_ALLOW_EMPTY | SD_FLAG_PATH_DIR | SD_FLAG_BROWSER_ACTION); +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif return true; } @@ -1728,8 +1760,10 @@ bool CONFIG_STRING( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif return true; } @@ -1757,8 +1791,11 @@ bool CONFIG_STRING_OPTIONS( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif /* Request values to be freed later */ settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_VALUES); @@ -1788,8 +1825,12 @@ bool CONFIG_HEX( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } @@ -1889,8 +1930,12 @@ bool CONFIG_ACTION( if (value.name) value.name_hash = msg_hash_calculate(value.name); (*list)[list_info->index++] = value; + +#ifdef HAVE_MENU menu_settings_list_current_add_enum_idx(list, list_info, name_enum_idx); menu_settings_list_current_add_enum_value_idx(list, list_info, SHORT_enum_idx); +#endif + return true; } diff --git a/tasks/task_netplay_lan_scan.c b/tasks/task_netplay_lan_scan.c index 38c86c3789..edf58b837e 100644 --- a/tasks/task_netplay_lan_scan.c +++ b/tasks/task_netplay_lan_scan.c @@ -13,25 +13,36 @@ * If not, see . */ +#include #include #include "tasks_internal.h" + +#ifdef HAVE_CONFIG_H +#include "../config.h" +#endif + #include "../verbosity.h" #include "../network/netplay/netplay_discovery.h" + +#ifdef HAVE_MENU #include "../menu/menu_entries.h" #include "../menu/menu_driver.h" +#endif static void netplay_lan_scan_callback(void *task_data, void *user_data, const char *error) { unsigned i; - unsigned menu_type = 0; - const char *path = NULL; - const char *label = NULL; - enum msg_hash_enums enum_idx = MSG_UNKNOWN; file_list_t *file_list = NULL; struct netplay_host_list *netplay_hosts = NULL; +#ifdef HAVE_MENU + enum msg_hash_enums enum_idx = MSG_UNKNOWN; + unsigned menu_type = 0; + const char *label = NULL; + const char *path = NULL; + menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); /* Don't push the results if we left the LAN scan menu */ @@ -60,6 +71,7 @@ static void netplay_lan_scan_callback(void *task_data, MENU_NETPLAY_LAN_SCAN, 0, 0); } } +#endif } static void task_netplay_lan_scan_handler(retro_task_t *task) diff --git a/tasks/task_wifi.c b/tasks/task_wifi.c index 8fc081cbcb..050766d301 100644 --- a/tasks/task_wifi.c +++ b/tasks/task_wifi.c @@ -39,13 +39,15 @@ static void wifi_scan_callback(void *task_data, void *user_data, const char *error) { unsigned i; - unsigned menu_type = 0; - const char *path = NULL; - const char *label = NULL; - enum msg_hash_enums enum_idx = MSG_UNKNOWN; file_list_t *file_list = NULL; struct string_list *ssid_list = NULL; +#ifdef HAVE_MENU + const char *path = NULL; + const char *label = NULL; + unsigned menu_type = 0; + enum msg_hash_enums enum_idx = MSG_UNKNOWN; + menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); /* Don't push the results if we left the wifi menu */ @@ -54,12 +56,14 @@ static void wifi_scan_callback(void *task_data, return; file_list = menu_entries_get_selection_buf_ptr(0); - ssid_list = string_list_new(); - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list); +#endif + + ssid_list = string_list_new(); driver_wifi_get_ssids(ssid_list); +#ifdef HAVE_MENU for (i = 0; i < ssid_list->size; i++) { const char *ssid = ssid_list->elems[i].data; @@ -69,6 +73,7 @@ static void wifi_scan_callback(void *task_data, MENU_ENUM_LABEL_CONNECT_WIFI, MENU_WIFI, 0, 0); } +#endif string_list_free(ssid_list); } From b3cd6f13a53cfa22d746d1d071ae7af83b0601b1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 4 Feb 2017 09:22:17 +0100 Subject: [PATCH 10/90] Fix ./configure --disable-rgui --- intl/msg_hash_us.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 722bf1ea90..5e20c7a319 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2721,14 +2721,17 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, "View previous searches.") MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, "Captures an image of the screen.") +#ifdef HAVE_DYNAMIC MSG_HASH( MENU_ENUM_SUBLABEL_CLOSE_CONTENT, -#ifdef HAVE_DYNAMIC "Closes the current game and application. Any unsaved changes might be lost." -#else - "Closes the current game. Any unsaved changes might be lost." -#endif ) +#else +MSG_HASH( + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Closes the current game. Any unsaved changes might be lost." + ) +#endif MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, "Load a saved state from the currently selected slot.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, From 38bfed4a93a733f79b6dd5d230c017ca784fedaa Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 4 Feb 2017 14:01:57 -0500 Subject: [PATCH 11/90] revert retroarch.cfg overwrite --- retroarch.cfg | 2436 +++++++++++++++++-------------------------------- 1 file changed, 813 insertions(+), 1623 deletions(-) diff --git a/retroarch.cfg b/retroarch.cfg index 103657b7f2..990783191d 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -1,1623 +1,813 @@ -core_updater_buildbot_url = "http://buildbot.libretro.com/nightly/win-x86_64/latest/" -core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" -libretro_directory = ":\cores" -libretro_info_path = ":\info" -content_database_path = ":\database\rdb" -cheat_database_path = ":\cheats" -content_history_path = ":\content_history.lpl" -content_music_history_path = ":\content_music_history.lpl" -content_video_history_path = ":\content_video_history.lpl" -content_image_history_path = ":\content_image_history.lpl" -cursor_directory = ":\database\cursors" -screenshot_directory = "default" -system_directory = "default" -input_remapping_directory = ":\config\remaps" -video_shader_dir = ":\shaders" -video_filter_dir = ":\filters\video" -core_assets_directory = ":\downloads" -assets_directory = ":\assets" -dynamic_wallpapers_directory = ":\assets\wallpapers" -thumbnails_directory = ":\thumbnails" -playlist_directory = ":\playlists" -joypad_autoconfig_dir = ":\autoconfig" -audio_filter_dir = ":\filters\audio" -savefile_directory = "default" -savestate_directory = "default" -rgui_browser_directory = "default" -rgui_config_directory = ":\config" -overlay_directory = ":\overlays" -screenshot_directory = "default" -video_driver = "gl" -record_driver = "null" -camera_driver = "null" -wifi_driver = "null" -location_driver = "null" -menu_driver = "xmb" -audio_driver = "xaudio" -audio_resampler = "sinc" -input_driver = "dinput" -input_joypad_driver = "xinput" -video_aspect_ratio = "-1.000000" -video_scale = "3.000000" -video_refresh_rate = "59.940060" -audio_rate_control_delta = "0.005000" -audio_max_timing_skew = "0.050000" -audio_volume = "0.000000" -input_overlay_opacity = "0.700000" -input_overlay_scale = "1.000000" -menu_wallpaper_opacity = "0.300000" -menu_footer_opacity = "1.000000" -menu_header_opacity = "1.000000" -video_message_pos_x = "0.050000" -video_message_pos_y = "0.050000" -video_font_size = "32.000000" -fastforward_ratio = "0.000000" -slowmotion_ratio = "3.000000" -input_axis_threshold = "0.500000" -input_bind_timeout = "5" -input_turbo_period = "6" -input_duty_cycle = "3" -input_max_users = "5" -input_menu_toggle_gamepad_combo = "0" -audio_latency = "64" -audio_block_frames = "0" -rewind_granularity = "1" -autosave_interval = "0" -libretro_log_level = "0" -keyboard_gamepad_mapping_type = "1" -input_poll_type_behavior = "2" -video_monitor_index = "0" -video_fullscreen_x = "0" -video_fullscreen_y = "0" -video_window_x = "0" -video_window_y = "0" -network_cmd_port = "55355" -network_remote_base_port = "55400" -dpi_override_value = "200" -menu_thumbnails = "3" -xmb_alpha_factor = "75" -xmb_scale_factor = "100" -xmb_theme = "0" -xmb_menu_color_theme = "4" -materialui_menu_color_theme = "0" -menu_shader_pipeline = "2" -audio_out_rate = "48000" -custom_viewport_width = "960" -custom_viewport_height = "720" -custom_viewport_x = "0" -custom_viewport_y = "0" -content_history_size = "100" -video_hard_sync_frames = "0" -video_frame_delay = "0" -video_max_swapchain_images = "3" -video_swap_interval = "1" -video_rotation = "0" -aspect_ratio_index = "21" -state_slot = "0" -netplay_ip_port = "55435" -netplay_check_frames = "30" -netplay_input_latency_frames_min = "0" -netplay_input_latency_frames_range = "0" -user_language = "0" -bundle_assets_extract_version_current = "0" -bundle_assets_extract_last_version = "0" -input_device_p1 = "0" -input_player1_joypad_index = "0" -input_libretro_device_p1 = "1" -input_player1_analog_dpad_mode = "0" -input_device_p2 = "0" -input_player2_joypad_index = "1" -input_libretro_device_p2 = "1" -input_player2_analog_dpad_mode = "0" -input_device_p3 = "0" -input_player3_joypad_index = "2" -input_libretro_device_p3 = "1" -input_player3_analog_dpad_mode = "0" -input_device_p4 = "0" -input_player4_joypad_index = "3" -input_libretro_device_p4 = "1" -input_player4_analog_dpad_mode = "0" -input_device_p5 = "0" -input_player5_joypad_index = "4" -input_libretro_device_p5 = "1" -input_player5_analog_dpad_mode = "0" -input_device_p6 = "0" -input_player6_joypad_index = "5" -input_libretro_device_p6 = "1" -input_player6_analog_dpad_mode = "0" -input_device_p7 = "0" -input_player7_joypad_index = "6" -input_libretro_device_p7 = "1" -input_player7_analog_dpad_mode = "0" -input_device_p8 = "0" -input_player8_joypad_index = "7" -input_libretro_device_p8 = "1" -input_player8_analog_dpad_mode = "0" -input_device_p9 = "0" -input_player9_joypad_index = "8" -input_libretro_device_p9 = "1" -input_player9_analog_dpad_mode = "0" -input_device_p10 = "0" -input_player10_joypad_index = "9" -input_libretro_device_p10 = "1" -input_player10_analog_dpad_mode = "0" -input_device_p11 = "0" -input_player11_joypad_index = "10" -input_libretro_device_p11 = "1" -input_player11_analog_dpad_mode = "0" -input_device_p12 = "0" -input_player12_joypad_index = "11" -input_libretro_device_p12 = "1" -input_player12_analog_dpad_mode = "0" -input_device_p13 = "0" -input_player13_joypad_index = "12" -input_libretro_device_p13 = "1" -input_player13_analog_dpad_mode = "0" -input_device_p14 = "0" -input_player14_joypad_index = "13" -input_libretro_device_p14 = "1" -input_player14_analog_dpad_mode = "0" -input_device_p15 = "0" -input_player15_joypad_index = "14" -input_libretro_device_p15 = "1" -input_player15_analog_dpad_mode = "0" -input_device_p16 = "0" -input_player16_joypad_index = "15" -input_libretro_device_p16 = "1" -input_player16_analog_dpad_mode = "0" -ui_companion_start_on_boot = "true" -ui_companion_enable = "false" -video_gpu_record = "false" -input_remap_binds_enable = "true" -all_users_control_menu = "false" -menu_swap_ok_cancel_buttons = "true" -netplay_stateless_mode = "false" -netplay_client_swap_input = "true" -input_descriptor_label_show = "true" -input_descriptor_hide_unbound = "false" -load_dummy_on_core_shutdown = "true" -check_firmware_before_loading = "false" -builtin_mediaplayer_enable = "false" -builtin_imageviewer_enable = "true" -fps_show = "false" -ui_menubar_enable = "true" -suspend_screensaver_enable = "true" -rewind_enable = "false" -audio_sync = "true" -video_shader_enable = "false" -video_aspect_ratio_auto = "false" -video_allow_rotate = "true" -video_windowed_fullscreen = "true" -video_crop_overscan = "true" -video_scale_integer = "false" -video_smooth = "true" -video_force_aspect = "true" -video_threaded = "false" -video_shared_context = "false" -auto_screenshot_filename = "true" -video_force_srgb_disable = "false" -video_fullscreen = "false" -bundle_assets_extract_enable = "false" -video_vsync = "true" -video_hard_sync = "false" -video_black_frame_insertion = "false" -video_disable_composition = "false" -pause_nonactive = "true" -video_gpu_screenshot = "true" -video_post_filter_record = "false" -keyboard_gamepad_enable = "true" -core_set_supports_no_game_enable = "true" -audio_enable = "true" -audio_mute_enable = "false" -location_allow = "false" -video_font_enable = "true" -core_updater_auto_extract_archive = "true" -camera_allow = "false" -menu_unified_controls = "false" -threaded_data_runloop_enable = "true" -menu_throttle_framerate = "true" -menu_linear_filter = "true" -dpi_override_enable = "true" -menu_pause_libretro = "true" -menu_mouse_enable = "true" -menu_pointer_enable = "false" -menu_timedate_enable = "true" -menu_battery_level_enable = "true" -menu_core_enable = "true" -menu_dynamic_wallpaper_enable = "false" -xmb_shadows_enable = "true" -xmb_show_settings = "true" -xmb_show_images = "true" -xmb_show_history = "true" -xmb_show_add = "true" -rgui_show_start_screen = "false" -menu_navigation_wraparound_enable = "true" -menu_navigation_browser_filter_supported_extensions_enable = "true" -menu_show_advanced_settings = "false" -cheevos_enable = "false" -cheevos_test_unofficial = "false" -cheevos_hardcore_mode_enable = "false" -input_overlay_enable = "true" -input_overlay_enable_autopreferred = "true" -input_overlay_hide_in_menu = "true" -network_cmd_enable = "false" -stdin_cmd_enable = "false" -network_remote_enable = "false" -netplay_nat_traversal = "true" -block_sram_overwrite = "false" -savestate_auto_index = "false" -savestate_auto_save = "false" -savestate_auto_load = "false" -savestate_thumbnail_enable = "false" -history_list_enable = "true" -playlist_entry_remove = "true" -game_specific_options = "false" -auto_overrides_enable = "true" -auto_remaps_enable = "true" -auto_shaders_enable = "true" -sort_savefiles_enable = "false" -sort_savestates_enable = "false" -config_save_on_exit = "true" -show_hidden_files = "true" -input_autodetect_enable = "true" -audio_rate_control = "true" -custom_bgm_enable = "false" -network_remote_enable_user_p1 = "false" -network_remote_enable_user_p2 = "false" -network_remote_enable_user_p3 = "false" -network_remote_enable_user_p4 = "false" -network_remote_enable_user_p5 = "false" -network_remote_enable_user_p6 = "false" -network_remote_enable_user_p7 = "false" -network_remote_enable_user_p8 = "false" -network_remote_enable_user_p9 = "false" -network_remote_enable_user_p10 = "false" -network_remote_enable_user_p11 = "false" -network_remote_enable_user_p12 = "false" -network_remote_enable_user_p13 = "false" -network_remote_enable_user_p14 = "false" -network_remote_enable_user_p15 = "false" -network_remote_enable_user_p16 = "false" -log_verbosity = "false" -perfcnt_enable = "false" -video_message_color = "ffff00" -menu_entry_normal_color = "ffffffff" -menu_entry_hover_color = "ff64ff64" -menu_title_color = "ff64ff64" -gamma_correction = "false" -flicker_filter_enable = "false" -soft_filter_enable = "false" -soft_filter_index = "0" -current_resolution_id = "0" -flicker_filter_index = "0" -input_player1_b = "z" -input_player1_b_btn = "nul" -input_player1_b_axis = "nul" -input_player1_y = "a" -input_player1_y_btn = "nul" -input_player1_y_axis = "nul" -input_player1_select = "rshift" -input_player1_select_btn = "nul" -input_player1_select_axis = "nul" -input_player1_start = "enter" -input_player1_start_btn = "nul" -input_player1_start_axis = "nul" -input_player1_up = "up" -input_player1_up_btn = "nul" -input_player1_up_axis = "nul" -input_player1_down = "down" -input_player1_down_btn = "nul" -input_player1_down_axis = "nul" -input_player1_left = "left" -input_player1_left_btn = "nul" -input_player1_left_axis = "nul" -input_player1_right = "right" -input_player1_right_btn = "nul" -input_player1_right_axis = "nul" -input_player1_a = "x" -input_player1_a_btn = "nul" -input_player1_a_axis = "nul" -input_player1_x = "s" -input_player1_x_btn = "nul" -input_player1_x_axis = "nul" -input_player1_l = "q" -input_player1_l_btn = "nul" -input_player1_l_axis = "nul" -input_player1_r = "w" -input_player1_r_btn = "nul" -input_player1_r_axis = "nul" -input_player1_l2 = "nul" -input_player1_l2_btn = "nul" -input_player1_l2_axis = "nul" -input_player1_r2 = "nul" -input_player1_r2_btn = "nul" -input_player1_r2_axis = "nul" -input_player1_l3 = "nul" -input_player1_l3_btn = "nul" -input_player1_l3_axis = "nul" -input_player1_r3 = "nul" -input_player1_r3_btn = "nul" -input_player1_r3_axis = "nul" -input_player1_l_x_plus = "nul" -input_player1_l_x_plus_btn = "nul" -input_player1_l_x_plus_axis = "nul" -input_player1_l_x_minus = "nul" -input_player1_l_x_minus_btn = "nul" -input_player1_l_x_minus_axis = "nul" -input_player1_l_y_plus = "nul" -input_player1_l_y_plus_btn = "nul" -input_player1_l_y_plus_axis = "nul" -input_player1_l_y_minus = "nul" -input_player1_l_y_minus_btn = "nul" -input_player1_l_y_minus_axis = "nul" -input_player1_r_x_plus = "nul" -input_player1_r_x_plus_btn = "nul" -input_player1_r_x_plus_axis = "nul" -input_player1_r_x_minus = "nul" -input_player1_r_x_minus_btn = "nul" -input_player1_r_x_minus_axis = "nul" -input_player1_r_y_plus = "nul" -input_player1_r_y_plus_btn = "nul" -input_player1_r_y_plus_axis = "nul" -input_player1_r_y_minus = "nul" -input_player1_r_y_minus_btn = "nul" -input_player1_r_y_minus_axis = "nul" -input_player1_turbo = "nul" -input_player1_turbo_btn = "nul" -input_player1_turbo_axis = "nul" -input_toggle_fast_forward = "space" -input_toggle_fast_forward_btn = "nul" -input_toggle_fast_forward_axis = "nul" -input_hold_fast_forward = "l" -input_hold_fast_forward_btn = "nul" -input_hold_fast_forward_axis = "nul" -input_load_state = "f4" -input_load_state_btn = "nul" -input_load_state_axis = "nul" -input_save_state = "f2" -input_save_state_btn = "nul" -input_save_state_axis = "nul" -input_toggle_fullscreen = "f" -input_toggle_fullscreen_btn = "nul" -input_toggle_fullscreen_axis = "nul" -input_exit_emulator = "escape" -input_exit_emulator_btn = "nul" -input_exit_emulator_axis = "nul" -input_state_slot_increase = "f7" -input_state_slot_increase_btn = "nul" -input_state_slot_increase_axis = "nul" -input_state_slot_decrease = "f6" -input_state_slot_decrease_btn = "nul" -input_state_slot_decrease_axis = "nul" -input_rewind = "r" -input_rewind_btn = "nul" -input_rewind_axis = "nul" -input_movie_record_toggle = "o" -input_movie_record_toggle_btn = "nul" -input_movie_record_toggle_axis = "nul" -input_pause_toggle = "p" -input_pause_toggle_btn = "nul" -input_pause_toggle_axis = "nul" -input_frame_advance = "k" -input_frame_advance_btn = "nul" -input_frame_advance_axis = "nul" -input_reset = "h" -input_reset_btn = "nul" -input_reset_axis = "nul" -input_shader_next = "m" -input_shader_next_btn = "nul" -input_shader_next_axis = "nul" -input_shader_prev = "n" -input_shader_prev_btn = "nul" -input_shader_prev_axis = "nul" -input_cheat_index_plus = "y" -input_cheat_index_plus_btn = "nul" -input_cheat_index_plus_axis = "nul" -input_cheat_index_minus = "t" -input_cheat_index_minus_btn = "nul" -input_cheat_index_minus_axis = "nul" -input_cheat_toggle = "u" -input_cheat_toggle_btn = "nul" -input_cheat_toggle_axis = "nul" -input_screenshot = "f8" -input_screenshot_btn = "nul" -input_screenshot_axis = "nul" -input_audio_mute = "f9" -input_audio_mute_btn = "nul" -input_audio_mute_axis = "nul" -input_osk_toggle = "f12" -input_osk_toggle_btn = "nul" -input_osk_toggle_axis = "nul" -input_netplay_flip_players_1_2 = "nul" -input_netplay_flip_players_1_2_btn = "nul" -input_netplay_flip_players_1_2_axis = "nul" -input_netplay_game_watch = "i" -input_netplay_game_watch_btn = "nul" -input_netplay_game_watch_axis = "nul" -input_slowmotion = "e" -input_slowmotion_btn = "nul" -input_slowmotion_axis = "nul" -input_enable_hotkey = "nul" -input_enable_hotkey_btn = "nul" -input_enable_hotkey_axis = "nul" -input_volume_up = "add" -input_volume_up_btn = "nul" -input_volume_up_axis = "nul" -input_volume_down = "subtract" -input_volume_down_btn = "nul" -input_volume_down_axis = "nul" -input_overlay_next = "nul" -input_overlay_next_btn = "nul" -input_overlay_next_axis = "nul" -input_disk_eject_toggle = "nul" -input_disk_eject_toggle_btn = "nul" -input_disk_eject_toggle_axis = "nul" -input_disk_next = "nul" -input_disk_next_btn = "nul" -input_disk_next_axis = "nul" -input_disk_prev = "nul" -input_disk_prev_btn = "nul" -input_disk_prev_axis = "nul" -input_grab_mouse_toggle = "f11" -input_grab_mouse_toggle_btn = "nul" -input_grab_mouse_toggle_axis = "nul" -input_game_focus_toggle = "scroll_lock" -input_game_focus_toggle_btn = "nul" -input_game_focus_toggle_axis = "nul" -input_menu_toggle = "f1" -input_menu_toggle_btn = "nul" -input_menu_toggle_axis = "nul" -input_player2_b = "nul" -input_player2_b_btn = "nul" -input_player2_b_axis = "nul" -input_player2_y = "nul" -input_player2_y_btn = "nul" -input_player2_y_axis = "nul" -input_player2_select = "nul" -input_player2_select_btn = "nul" -input_player2_select_axis = "nul" -input_player2_start = "nul" -input_player2_start_btn = "nul" -input_player2_start_axis = "nul" -input_player2_up = "nul" -input_player2_up_btn = "nul" -input_player2_up_axis = "nul" -input_player2_down = "nul" -input_player2_down_btn = "nul" -input_player2_down_axis = "nul" -input_player2_left = "nul" -input_player2_left_btn = "nul" -input_player2_left_axis = "nul" -input_player2_right = "nul" -input_player2_right_btn = "nul" -input_player2_right_axis = "nul" -input_player2_a = "nul" -input_player2_a_btn = "nul" -input_player2_a_axis = "nul" -input_player2_x = "nul" -input_player2_x_btn = "nul" -input_player2_x_axis = "nul" -input_player2_l = "nul" -input_player2_l_btn = "nul" -input_player2_l_axis = "nul" -input_player2_r = "nul" -input_player2_r_btn = "nul" -input_player2_r_axis = "nul" -input_player2_l2 = "nul" -input_player2_l2_btn = "nul" -input_player2_l2_axis = "nul" -input_player2_r2 = "nul" -input_player2_r2_btn = "nul" -input_player2_r2_axis = "nul" -input_player2_l3 = "nul" -input_player2_l3_btn = "nul" -input_player2_l3_axis = "nul" -input_player2_r3 = "nul" -input_player2_r3_btn = "nul" -input_player2_r3_axis = "nul" -input_player2_l_x_plus = "nul" -input_player2_l_x_plus_btn = "nul" -input_player2_l_x_plus_axis = "nul" -input_player2_l_x_minus = "nul" -input_player2_l_x_minus_btn = "nul" -input_player2_l_x_minus_axis = "nul" -input_player2_l_y_plus = "nul" -input_player2_l_y_plus_btn = "nul" -input_player2_l_y_plus_axis = "nul" -input_player2_l_y_minus = "nul" -input_player2_l_y_minus_btn = "nul" -input_player2_l_y_minus_axis = "nul" -input_player2_r_x_plus = "nul" -input_player2_r_x_plus_btn = "nul" -input_player2_r_x_plus_axis = "nul" -input_player2_r_x_minus = "nul" -input_player2_r_x_minus_btn = "nul" -input_player2_r_x_minus_axis = "nul" -input_player2_r_y_plus = "nul" -input_player2_r_y_plus_btn = "nul" -input_player2_r_y_plus_axis = "nul" -input_player2_r_y_minus = "nul" -input_player2_r_y_minus_btn = "nul" -input_player2_r_y_minus_axis = "nul" -input_player2_turbo = "nul" -input_player2_turbo_btn = "nul" -input_player2_turbo_axis = "nul" -input_player3_b = "nul" -input_player3_b_btn = "nul" -input_player3_b_axis = "nul" -input_player3_y = "nul" -input_player3_y_btn = "nul" -input_player3_y_axis = "nul" -input_player3_select = "nul" -input_player3_select_btn = "nul" -input_player3_select_axis = "nul" -input_player3_start = "nul" -input_player3_start_btn = "nul" -input_player3_start_axis = "nul" -input_player3_up = "nul" -input_player3_up_btn = "nul" -input_player3_up_axis = "nul" -input_player3_down = "nul" -input_player3_down_btn = "nul" -input_player3_down_axis = "nul" -input_player3_left = "nul" -input_player3_left_btn = "nul" -input_player3_left_axis = "nul" -input_player3_right = "nul" -input_player3_right_btn = "nul" -input_player3_right_axis = "nul" -input_player3_a = "nul" -input_player3_a_btn = "nul" -input_player3_a_axis = "nul" -input_player3_x = "nul" -input_player3_x_btn = "nul" -input_player3_x_axis = "nul" -input_player3_l = "nul" -input_player3_l_btn = "nul" -input_player3_l_axis = "nul" -input_player3_r = "nul" -input_player3_r_btn = "nul" -input_player3_r_axis = "nul" -input_player3_l2 = "nul" -input_player3_l2_btn = "nul" -input_player3_l2_axis = "nul" -input_player3_r2 = "nul" -input_player3_r2_btn = "nul" -input_player3_r2_axis = "nul" -input_player3_l3 = "nul" -input_player3_l3_btn = "nul" -input_player3_l3_axis = "nul" -input_player3_r3 = "nul" -input_player3_r3_btn = "nul" -input_player3_r3_axis = "nul" -input_player3_l_x_plus = "nul" -input_player3_l_x_plus_btn = "nul" -input_player3_l_x_plus_axis = "nul" -input_player3_l_x_minus = "nul" -input_player3_l_x_minus_btn = "nul" -input_player3_l_x_minus_axis = "nul" -input_player3_l_y_plus = "nul" -input_player3_l_y_plus_btn = "nul" -input_player3_l_y_plus_axis = "nul" -input_player3_l_y_minus = "nul" -input_player3_l_y_minus_btn = "nul" -input_player3_l_y_minus_axis = "nul" -input_player3_r_x_plus = "nul" -input_player3_r_x_plus_btn = "nul" -input_player3_r_x_plus_axis = "nul" -input_player3_r_x_minus = "nul" -input_player3_r_x_minus_btn = "nul" -input_player3_r_x_minus_axis = "nul" -input_player3_r_y_plus = "nul" -input_player3_r_y_plus_btn = "nul" -input_player3_r_y_plus_axis = "nul" -input_player3_r_y_minus = "nul" -input_player3_r_y_minus_btn = "nul" -input_player3_r_y_minus_axis = "nul" -input_player3_turbo = "nul" -input_player3_turbo_btn = "nul" -input_player3_turbo_axis = "nul" -input_player4_b = "nul" -input_player4_b_btn = "nul" -input_player4_b_axis = "nul" -input_player4_y = "nul" -input_player4_y_btn = "nul" -input_player4_y_axis = "nul" -input_player4_select = "nul" -input_player4_select_btn = "nul" -input_player4_select_axis = "nul" -input_player4_start = "nul" -input_player4_start_btn = "nul" -input_player4_start_axis = "nul" -input_player4_up = "nul" -input_player4_up_btn = "nul" -input_player4_up_axis = "nul" -input_player4_down = "nul" -input_player4_down_btn = "nul" -input_player4_down_axis = "nul" -input_player4_left = "nul" -input_player4_left_btn = "nul" -input_player4_left_axis = "nul" -input_player4_right = "nul" -input_player4_right_btn = "nul" -input_player4_right_axis = "nul" -input_player4_a = "nul" -input_player4_a_btn = "nul" -input_player4_a_axis = "nul" -input_player4_x = "nul" -input_player4_x_btn = "nul" -input_player4_x_axis = "nul" -input_player4_l = "nul" -input_player4_l_btn = "nul" -input_player4_l_axis = "nul" -input_player4_r = "nul" -input_player4_r_btn = "nul" -input_player4_r_axis = "nul" -input_player4_l2 = "nul" -input_player4_l2_btn = "nul" -input_player4_l2_axis = "nul" -input_player4_r2 = "nul" -input_player4_r2_btn = "nul" -input_player4_r2_axis = "nul" -input_player4_l3 = "nul" -input_player4_l3_btn = "nul" -input_player4_l3_axis = "nul" -input_player4_r3 = "nul" -input_player4_r3_btn = "nul" -input_player4_r3_axis = "nul" -input_player4_l_x_plus = "nul" -input_player4_l_x_plus_btn = "nul" -input_player4_l_x_plus_axis = "nul" -input_player4_l_x_minus = "nul" -input_player4_l_x_minus_btn = "nul" -input_player4_l_x_minus_axis = "nul" -input_player4_l_y_plus = "nul" -input_player4_l_y_plus_btn = "nul" -input_player4_l_y_plus_axis = "nul" -input_player4_l_y_minus = "nul" -input_player4_l_y_minus_btn = "nul" -input_player4_l_y_minus_axis = "nul" -input_player4_r_x_plus = "nul" -input_player4_r_x_plus_btn = "nul" -input_player4_r_x_plus_axis = "nul" -input_player4_r_x_minus = "nul" -input_player4_r_x_minus_btn = "nul" -input_player4_r_x_minus_axis = "nul" -input_player4_r_y_plus = "nul" -input_player4_r_y_plus_btn = "nul" -input_player4_r_y_plus_axis = "nul" -input_player4_r_y_minus = "nul" -input_player4_r_y_minus_btn = "nul" -input_player4_r_y_minus_axis = "nul" -input_player4_turbo = "nul" -input_player4_turbo_btn = "nul" -input_player4_turbo_axis = "nul" -input_player5_b = "nul" -input_player5_b_btn = "nul" -input_player5_b_axis = "nul" -input_player5_y = "nul" -input_player5_y_btn = "nul" -input_player5_y_axis = "nul" -input_player5_select = "nul" -input_player5_select_btn = "nul" -input_player5_select_axis = "nul" -input_player5_start = "nul" -input_player5_start_btn = "nul" -input_player5_start_axis = "nul" -input_player5_up = "nul" -input_player5_up_btn = "nul" -input_player5_up_axis = "nul" -input_player5_down = "nul" -input_player5_down_btn = "nul" -input_player5_down_axis = "nul" -input_player5_left = "nul" -input_player5_left_btn = "nul" -input_player5_left_axis = "nul" -input_player5_right = "nul" -input_player5_right_btn = "nul" -input_player5_right_axis = "nul" -input_player5_a = "nul" -input_player5_a_btn = "nul" -input_player5_a_axis = "nul" -input_player5_x = "nul" -input_player5_x_btn = "nul" -input_player5_x_axis = "nul" -input_player5_l = "nul" -input_player5_l_btn = "nul" -input_player5_l_axis = "nul" -input_player5_r = "nul" -input_player5_r_btn = "nul" -input_player5_r_axis = "nul" -input_player5_l2 = "nul" -input_player5_l2_btn = "nul" -input_player5_l2_axis = "nul" -input_player5_r2 = "nul" -input_player5_r2_btn = "nul" -input_player5_r2_axis = "nul" -input_player5_l3 = "nul" -input_player5_l3_btn = "nul" -input_player5_l3_axis = "nul" -input_player5_r3 = "nul" -input_player5_r3_btn = "nul" -input_player5_r3_axis = "nul" -input_player5_l_x_plus = "nul" -input_player5_l_x_plus_btn = "nul" -input_player5_l_x_plus_axis = "nul" -input_player5_l_x_minus = "nul" -input_player5_l_x_minus_btn = "nul" -input_player5_l_x_minus_axis = "nul" -input_player5_l_y_plus = "nul" -input_player5_l_y_plus_btn = "nul" -input_player5_l_y_plus_axis = "nul" -input_player5_l_y_minus = "nul" -input_player5_l_y_minus_btn = "nul" -input_player5_l_y_minus_axis = "nul" -input_player5_r_x_plus = "nul" -input_player5_r_x_plus_btn = "nul" -input_player5_r_x_plus_axis = "nul" -input_player5_r_x_minus = "nul" -input_player5_r_x_minus_btn = "nul" -input_player5_r_x_minus_axis = "nul" -input_player5_r_y_plus = "nul" -input_player5_r_y_plus_btn = "nul" -input_player5_r_y_plus_axis = "nul" -input_player5_r_y_minus = "nul" -input_player5_r_y_minus_btn = "nul" -input_player5_r_y_minus_axis = "nul" -input_player5_turbo = "nul" -input_player5_turbo_btn = "nul" -input_player5_turbo_axis = "nul" -input_player6_b = "nul" -input_player6_b_btn = "nul" -input_player6_b_axis = "nul" -input_player6_y = "nul" -input_player6_y_btn = "nul" -input_player6_y_axis = "nul" -input_player6_select = "nul" -input_player6_select_btn = "nul" -input_player6_select_axis = "nul" -input_player6_start = "nul" -input_player6_start_btn = "nul" -input_player6_start_axis = "nul" -input_player6_up = "nul" -input_player6_up_btn = "nul" -input_player6_up_axis = "nul" -input_player6_down = "nul" -input_player6_down_btn = "nul" -input_player6_down_axis = "nul" -input_player6_left = "nul" -input_player6_left_btn = "nul" -input_player6_left_axis = "nul" -input_player6_right = "nul" -input_player6_right_btn = "nul" -input_player6_right_axis = "nul" -input_player6_a = "nul" -input_player6_a_btn = "nul" -input_player6_a_axis = "nul" -input_player6_x = "nul" -input_player6_x_btn = "nul" -input_player6_x_axis = "nul" -input_player6_l = "nul" -input_player6_l_btn = "nul" -input_player6_l_axis = "nul" -input_player6_r = "nul" -input_player6_r_btn = "nul" -input_player6_r_axis = "nul" -input_player6_l2 = "nul" -input_player6_l2_btn = "nul" -input_player6_l2_axis = "nul" -input_player6_r2 = "nul" -input_player6_r2_btn = "nul" -input_player6_r2_axis = "nul" -input_player6_l3 = "nul" -input_player6_l3_btn = "nul" -input_player6_l3_axis = "nul" -input_player6_r3 = "nul" -input_player6_r3_btn = "nul" -input_player6_r3_axis = "nul" -input_player6_l_x_plus = "nul" -input_player6_l_x_plus_btn = "nul" -input_player6_l_x_plus_axis = "nul" -input_player6_l_x_minus = "nul" -input_player6_l_x_minus_btn = "nul" -input_player6_l_x_minus_axis = "nul" -input_player6_l_y_plus = "nul" -input_player6_l_y_plus_btn = "nul" -input_player6_l_y_plus_axis = "nul" -input_player6_l_y_minus = "nul" -input_player6_l_y_minus_btn = "nul" -input_player6_l_y_minus_axis = "nul" -input_player6_r_x_plus = "nul" -input_player6_r_x_plus_btn = "nul" -input_player6_r_x_plus_axis = "nul" -input_player6_r_x_minus = "nul" -input_player6_r_x_minus_btn = "nul" -input_player6_r_x_minus_axis = "nul" -input_player6_r_y_plus = "nul" -input_player6_r_y_plus_btn = "nul" -input_player6_r_y_plus_axis = "nul" -input_player6_r_y_minus = "nul" -input_player6_r_y_minus_btn = "nul" -input_player6_r_y_minus_axis = "nul" -input_player6_turbo = "nul" -input_player6_turbo_btn = "nul" -input_player6_turbo_axis = "nul" -input_player7_b = "nul" -input_player7_b_btn = "nul" -input_player7_b_axis = "nul" -input_player7_y = "nul" -input_player7_y_btn = "nul" -input_player7_y_axis = "nul" -input_player7_select = "nul" -input_player7_select_btn = "nul" -input_player7_select_axis = "nul" -input_player7_start = "nul" -input_player7_start_btn = "nul" -input_player7_start_axis = "nul" -input_player7_up = "nul" -input_player7_up_btn = "nul" -input_player7_up_axis = "nul" -input_player7_down = "nul" -input_player7_down_btn = "nul" -input_player7_down_axis = "nul" -input_player7_left = "nul" -input_player7_left_btn = "nul" -input_player7_left_axis = "nul" -input_player7_right = "nul" -input_player7_right_btn = "nul" -input_player7_right_axis = "nul" -input_player7_a = "nul" -input_player7_a_btn = "nul" -input_player7_a_axis = "nul" -input_player7_x = "nul" -input_player7_x_btn = "nul" -input_player7_x_axis = "nul" -input_player7_l = "nul" -input_player7_l_btn = "nul" -input_player7_l_axis = "nul" -input_player7_r = "nul" -input_player7_r_btn = "nul" -input_player7_r_axis = "nul" -input_player7_l2 = "nul" -input_player7_l2_btn = "nul" -input_player7_l2_axis = "nul" -input_player7_r2 = "nul" -input_player7_r2_btn = "nul" -input_player7_r2_axis = "nul" -input_player7_l3 = "nul" -input_player7_l3_btn = "nul" -input_player7_l3_axis = "nul" -input_player7_r3 = "nul" -input_player7_r3_btn = "nul" -input_player7_r3_axis = "nul" -input_player7_l_x_plus = "nul" -input_player7_l_x_plus_btn = "nul" -input_player7_l_x_plus_axis = "nul" -input_player7_l_x_minus = "nul" -input_player7_l_x_minus_btn = "nul" -input_player7_l_x_minus_axis = "nul" -input_player7_l_y_plus = "nul" -input_player7_l_y_plus_btn = "nul" -input_player7_l_y_plus_axis = "nul" -input_player7_l_y_minus = "nul" -input_player7_l_y_minus_btn = "nul" -input_player7_l_y_minus_axis = "nul" -input_player7_r_x_plus = "nul" -input_player7_r_x_plus_btn = "nul" -input_player7_r_x_plus_axis = "nul" -input_player7_r_x_minus = "nul" -input_player7_r_x_minus_btn = "nul" -input_player7_r_x_minus_axis = "nul" -input_player7_r_y_plus = "nul" -input_player7_r_y_plus_btn = "nul" -input_player7_r_y_plus_axis = "nul" -input_player7_r_y_minus = "nul" -input_player7_r_y_minus_btn = "nul" -input_player7_r_y_minus_axis = "nul" -input_player7_turbo = "nul" -input_player7_turbo_btn = "nul" -input_player7_turbo_axis = "nul" -input_player8_b = "nul" -input_player8_b_btn = "nul" -input_player8_b_axis = "nul" -input_player8_y = "nul" -input_player8_y_btn = "nul" -input_player8_y_axis = "nul" -input_player8_select = "nul" -input_player8_select_btn = "nul" -input_player8_select_axis = "nul" -input_player8_start = "nul" -input_player8_start_btn = "nul" -input_player8_start_axis = "nul" -input_player8_up = "nul" -input_player8_up_btn = "nul" -input_player8_up_axis = "nul" -input_player8_down = "nul" -input_player8_down_btn = "nul" -input_player8_down_axis = "nul" -input_player8_left = "nul" -input_player8_left_btn = "nul" -input_player8_left_axis = "nul" -input_player8_right = "nul" -input_player8_right_btn = "nul" -input_player8_right_axis = "nul" -input_player8_a = "nul" -input_player8_a_btn = "nul" -input_player8_a_axis = "nul" -input_player8_x = "nul" -input_player8_x_btn = "nul" -input_player8_x_axis = "nul" -input_player8_l = "nul" -input_player8_l_btn = "nul" -input_player8_l_axis = "nul" -input_player8_r = "nul" -input_player8_r_btn = "nul" -input_player8_r_axis = "nul" -input_player8_l2 = "nul" -input_player8_l2_btn = "nul" -input_player8_l2_axis = "nul" -input_player8_r2 = "nul" -input_player8_r2_btn = "nul" -input_player8_r2_axis = "nul" -input_player8_l3 = "nul" -input_player8_l3_btn = "nul" -input_player8_l3_axis = "nul" -input_player8_r3 = "nul" -input_player8_r3_btn = "nul" -input_player8_r3_axis = "nul" -input_player8_l_x_plus = "nul" -input_player8_l_x_plus_btn = "nul" -input_player8_l_x_plus_axis = "nul" -input_player8_l_x_minus = "nul" -input_player8_l_x_minus_btn = "nul" -input_player8_l_x_minus_axis = "nul" -input_player8_l_y_plus = "nul" -input_player8_l_y_plus_btn = "nul" -input_player8_l_y_plus_axis = "nul" -input_player8_l_y_minus = "nul" -input_player8_l_y_minus_btn = "nul" -input_player8_l_y_minus_axis = "nul" -input_player8_r_x_plus = "nul" -input_player8_r_x_plus_btn = "nul" -input_player8_r_x_plus_axis = "nul" -input_player8_r_x_minus = "nul" -input_player8_r_x_minus_btn = "nul" -input_player8_r_x_minus_axis = "nul" -input_player8_r_y_plus = "nul" -input_player8_r_y_plus_btn = "nul" -input_player8_r_y_plus_axis = "nul" -input_player8_r_y_minus = "nul" -input_player8_r_y_minus_btn = "nul" -input_player8_r_y_minus_axis = "nul" -input_player8_turbo = "nul" -input_player8_turbo_btn = "nul" -input_player8_turbo_axis = "nul" -input_player9_b = "nul" -input_player9_b_btn = "nul" -input_player9_b_axis = "nul" -input_player9_y = "nul" -input_player9_y_btn = "nul" -input_player9_y_axis = "nul" -input_player9_select = "nul" -input_player9_select_btn = "nul" -input_player9_select_axis = "nul" -input_player9_start = "nul" -input_player9_start_btn = "nul" -input_player9_start_axis = "nul" -input_player9_up = "nul" -input_player9_up_btn = "nul" -input_player9_up_axis = "nul" -input_player9_down = "nul" -input_player9_down_btn = "nul" -input_player9_down_axis = "nul" -input_player9_left = "nul" -input_player9_left_btn = "nul" -input_player9_left_axis = "nul" -input_player9_right = "nul" -input_player9_right_btn = "nul" -input_player9_right_axis = "nul" -input_player9_a = "nul" -input_player9_a_btn = "nul" -input_player9_a_axis = "nul" -input_player9_x = "nul" -input_player9_x_btn = "nul" -input_player9_x_axis = "nul" -input_player9_l = "nul" -input_player9_l_btn = "nul" -input_player9_l_axis = "nul" -input_player9_r = "nul" -input_player9_r_btn = "nul" -input_player9_r_axis = "nul" -input_player9_l2 = "nul" -input_player9_l2_btn = "nul" -input_player9_l2_axis = "nul" -input_player9_r2 = "nul" -input_player9_r2_btn = "nul" -input_player9_r2_axis = "nul" -input_player9_l3 = "nul" -input_player9_l3_btn = "nul" -input_player9_l3_axis = "nul" -input_player9_r3 = "nul" -input_player9_r3_btn = "nul" -input_player9_r3_axis = "nul" -input_player9_l_x_plus = "nul" -input_player9_l_x_plus_btn = "nul" -input_player9_l_x_plus_axis = "nul" -input_player9_l_x_minus = "nul" -input_player9_l_x_minus_btn = "nul" -input_player9_l_x_minus_axis = "nul" -input_player9_l_y_plus = "nul" -input_player9_l_y_plus_btn = "nul" -input_player9_l_y_plus_axis = "nul" -input_player9_l_y_minus = "nul" -input_player9_l_y_minus_btn = "nul" -input_player9_l_y_minus_axis = "nul" -input_player9_r_x_plus = "nul" -input_player9_r_x_plus_btn = "nul" -input_player9_r_x_plus_axis = "nul" -input_player9_r_x_minus = "nul" -input_player9_r_x_minus_btn = "nul" -input_player9_r_x_minus_axis = "nul" -input_player9_r_y_plus = "nul" -input_player9_r_y_plus_btn = "nul" -input_player9_r_y_plus_axis = "nul" -input_player9_r_y_minus = "nul" -input_player9_r_y_minus_btn = "nul" -input_player9_r_y_minus_axis = "nul" -input_player9_turbo = "nul" -input_player9_turbo_btn = "nul" -input_player9_turbo_axis = "nul" -input_player10_b = "nul" -input_player10_b_btn = "nul" -input_player10_b_axis = "nul" -input_player10_y = "nul" -input_player10_y_btn = "nul" -input_player10_y_axis = "nul" -input_player10_select = "nul" -input_player10_select_btn = "nul" -input_player10_select_axis = "nul" -input_player10_start = "nul" -input_player10_start_btn = "nul" -input_player10_start_axis = "nul" -input_player10_up = "nul" -input_player10_up_btn = "nul" -input_player10_up_axis = "nul" -input_player10_down = "nul" -input_player10_down_btn = "nul" -input_player10_down_axis = "nul" -input_player10_left = "nul" -input_player10_left_btn = "nul" -input_player10_left_axis = "nul" -input_player10_right = "nul" -input_player10_right_btn = "nul" -input_player10_right_axis = "nul" -input_player10_a = "nul" -input_player10_a_btn = "nul" -input_player10_a_axis = "nul" -input_player10_x = "nul" -input_player10_x_btn = "nul" -input_player10_x_axis = "nul" -input_player10_l = "nul" -input_player10_l_btn = "nul" -input_player10_l_axis = "nul" -input_player10_r = "nul" -input_player10_r_btn = "nul" -input_player10_r_axis = "nul" -input_player10_l2 = "nul" -input_player10_l2_btn = "nul" -input_player10_l2_axis = "nul" -input_player10_r2 = "nul" -input_player10_r2_btn = "nul" -input_player10_r2_axis = "nul" -input_player10_l3 = "nul" -input_player10_l3_btn = "nul" -input_player10_l3_axis = "nul" -input_player10_r3 = "nul" -input_player10_r3_btn = "nul" -input_player10_r3_axis = "nul" -input_player10_l_x_plus = "nul" -input_player10_l_x_plus_btn = "nul" -input_player10_l_x_plus_axis = "nul" -input_player10_l_x_minus = "nul" -input_player10_l_x_minus_btn = "nul" -input_player10_l_x_minus_axis = "nul" -input_player10_l_y_plus = "nul" -input_player10_l_y_plus_btn = "nul" -input_player10_l_y_plus_axis = "nul" -input_player10_l_y_minus = "nul" -input_player10_l_y_minus_btn = "nul" -input_player10_l_y_minus_axis = "nul" -input_player10_r_x_plus = "nul" -input_player10_r_x_plus_btn = "nul" -input_player10_r_x_plus_axis = "nul" -input_player10_r_x_minus = "nul" -input_player10_r_x_minus_btn = "nul" -input_player10_r_x_minus_axis = "nul" -input_player10_r_y_plus = "nul" -input_player10_r_y_plus_btn = "nul" -input_player10_r_y_plus_axis = "nul" -input_player10_r_y_minus = "nul" -input_player10_r_y_minus_btn = "nul" -input_player10_r_y_minus_axis = "nul" -input_player10_turbo = "nul" -input_player10_turbo_btn = "nul" -input_player10_turbo_axis = "nul" -input_player11_b = "nul" -input_player11_b_btn = "nul" -input_player11_b_axis = "nul" -input_player11_y = "nul" -input_player11_y_btn = "nul" -input_player11_y_axis = "nul" -input_player11_select = "nul" -input_player11_select_btn = "nul" -input_player11_select_axis = "nul" -input_player11_start = "nul" -input_player11_start_btn = "nul" -input_player11_start_axis = "nul" -input_player11_up = "nul" -input_player11_up_btn = "nul" -input_player11_up_axis = "nul" -input_player11_down = "nul" -input_player11_down_btn = "nul" -input_player11_down_axis = "nul" -input_player11_left = "nul" -input_player11_left_btn = "nul" -input_player11_left_axis = "nul" -input_player11_right = "nul" -input_player11_right_btn = "nul" -input_player11_right_axis = "nul" -input_player11_a = "nul" -input_player11_a_btn = "nul" -input_player11_a_axis = "nul" -input_player11_x = "nul" -input_player11_x_btn = "nul" -input_player11_x_axis = "nul" -input_player11_l = "nul" -input_player11_l_btn = "nul" -input_player11_l_axis = "nul" -input_player11_r = "nul" -input_player11_r_btn = "nul" -input_player11_r_axis = "nul" -input_player11_l2 = "nul" -input_player11_l2_btn = "nul" -input_player11_l2_axis = "nul" -input_player11_r2 = "nul" -input_player11_r2_btn = "nul" -input_player11_r2_axis = "nul" -input_player11_l3 = "nul" -input_player11_l3_btn = "nul" -input_player11_l3_axis = "nul" -input_player11_r3 = "nul" -input_player11_r3_btn = "nul" -input_player11_r3_axis = "nul" -input_player11_l_x_plus = "nul" -input_player11_l_x_plus_btn = "nul" -input_player11_l_x_plus_axis = "nul" -input_player11_l_x_minus = "nul" -input_player11_l_x_minus_btn = "nul" -input_player11_l_x_minus_axis = "nul" -input_player11_l_y_plus = "nul" -input_player11_l_y_plus_btn = "nul" -input_player11_l_y_plus_axis = "nul" -input_player11_l_y_minus = "nul" -input_player11_l_y_minus_btn = "nul" -input_player11_l_y_minus_axis = "nul" -input_player11_r_x_plus = "nul" -input_player11_r_x_plus_btn = "nul" -input_player11_r_x_plus_axis = "nul" -input_player11_r_x_minus = "nul" -input_player11_r_x_minus_btn = "nul" -input_player11_r_x_minus_axis = "nul" -input_player11_r_y_plus = "nul" -input_player11_r_y_plus_btn = "nul" -input_player11_r_y_plus_axis = "nul" -input_player11_r_y_minus = "nul" -input_player11_r_y_minus_btn = "nul" -input_player11_r_y_minus_axis = "nul" -input_player11_turbo = "nul" -input_player11_turbo_btn = "nul" -input_player11_turbo_axis = "nul" -input_player12_b = "nul" -input_player12_b_btn = "nul" -input_player12_b_axis = "nul" -input_player12_y = "nul" -input_player12_y_btn = "nul" -input_player12_y_axis = "nul" -input_player12_select = "nul" -input_player12_select_btn = "nul" -input_player12_select_axis = "nul" -input_player12_start = "nul" -input_player12_start_btn = "nul" -input_player12_start_axis = "nul" -input_player12_up = "nul" -input_player12_up_btn = "nul" -input_player12_up_axis = "nul" -input_player12_down = "nul" -input_player12_down_btn = "nul" -input_player12_down_axis = "nul" -input_player12_left = "nul" -input_player12_left_btn = "nul" -input_player12_left_axis = "nul" -input_player12_right = "nul" -input_player12_right_btn = "nul" -input_player12_right_axis = "nul" -input_player12_a = "nul" -input_player12_a_btn = "nul" -input_player12_a_axis = "nul" -input_player12_x = "nul" -input_player12_x_btn = "nul" -input_player12_x_axis = "nul" -input_player12_l = "nul" -input_player12_l_btn = "nul" -input_player12_l_axis = "nul" -input_player12_r = "nul" -input_player12_r_btn = "nul" -input_player12_r_axis = "nul" -input_player12_l2 = "nul" -input_player12_l2_btn = "nul" -input_player12_l2_axis = "nul" -input_player12_r2 = "nul" -input_player12_r2_btn = "nul" -input_player12_r2_axis = "nul" -input_player12_l3 = "nul" -input_player12_l3_btn = "nul" -input_player12_l3_axis = "nul" -input_player12_r3 = "nul" -input_player12_r3_btn = "nul" -input_player12_r3_axis = "nul" -input_player12_l_x_plus = "nul" -input_player12_l_x_plus_btn = "nul" -input_player12_l_x_plus_axis = "nul" -input_player12_l_x_minus = "nul" -input_player12_l_x_minus_btn = "nul" -input_player12_l_x_minus_axis = "nul" -input_player12_l_y_plus = "nul" -input_player12_l_y_plus_btn = "nul" -input_player12_l_y_plus_axis = "nul" -input_player12_l_y_minus = "nul" -input_player12_l_y_minus_btn = "nul" -input_player12_l_y_minus_axis = "nul" -input_player12_r_x_plus = "nul" -input_player12_r_x_plus_btn = "nul" -input_player12_r_x_plus_axis = "nul" -input_player12_r_x_minus = "nul" -input_player12_r_x_minus_btn = "nul" -input_player12_r_x_minus_axis = "nul" -input_player12_r_y_plus = "nul" -input_player12_r_y_plus_btn = "nul" -input_player12_r_y_plus_axis = "nul" -input_player12_r_y_minus = "nul" -input_player12_r_y_minus_btn = "nul" -input_player12_r_y_minus_axis = "nul" -input_player12_turbo = "nul" -input_player12_turbo_btn = "nul" -input_player12_turbo_axis = "nul" -input_player13_b = "nul" -input_player13_b_btn = "nul" -input_player13_b_axis = "nul" -input_player13_y = "nul" -input_player13_y_btn = "nul" -input_player13_y_axis = "nul" -input_player13_select = "nul" -input_player13_select_btn = "nul" -input_player13_select_axis = "nul" -input_player13_start = "nul" -input_player13_start_btn = "nul" -input_player13_start_axis = "nul" -input_player13_up = "nul" -input_player13_up_btn = "nul" -input_player13_up_axis = "nul" -input_player13_down = "nul" -input_player13_down_btn = "nul" -input_player13_down_axis = "nul" -input_player13_left = "nul" -input_player13_left_btn = "nul" -input_player13_left_axis = "nul" -input_player13_right = "nul" -input_player13_right_btn = "nul" -input_player13_right_axis = "nul" -input_player13_a = "nul" -input_player13_a_btn = "nul" -input_player13_a_axis = "nul" -input_player13_x = "nul" -input_player13_x_btn = "nul" -input_player13_x_axis = "nul" -input_player13_l = "nul" -input_player13_l_btn = "nul" -input_player13_l_axis = "nul" -input_player13_r = "nul" -input_player13_r_btn = "nul" -input_player13_r_axis = "nul" -input_player13_l2 = "nul" -input_player13_l2_btn = "nul" -input_player13_l2_axis = "nul" -input_player13_r2 = "nul" -input_player13_r2_btn = "nul" -input_player13_r2_axis = "nul" -input_player13_l3 = "nul" -input_player13_l3_btn = "nul" -input_player13_l3_axis = "nul" -input_player13_r3 = "nul" -input_player13_r3_btn = "nul" -input_player13_r3_axis = "nul" -input_player13_l_x_plus = "nul" -input_player13_l_x_plus_btn = "nul" -input_player13_l_x_plus_axis = "nul" -input_player13_l_x_minus = "nul" -input_player13_l_x_minus_btn = "nul" -input_player13_l_x_minus_axis = "nul" -input_player13_l_y_plus = "nul" -input_player13_l_y_plus_btn = "nul" -input_player13_l_y_plus_axis = "nul" -input_player13_l_y_minus = "nul" -input_player13_l_y_minus_btn = "nul" -input_player13_l_y_minus_axis = "nul" -input_player13_r_x_plus = "nul" -input_player13_r_x_plus_btn = "nul" -input_player13_r_x_plus_axis = "nul" -input_player13_r_x_minus = "nul" -input_player13_r_x_minus_btn = "nul" -input_player13_r_x_minus_axis = "nul" -input_player13_r_y_plus = "nul" -input_player13_r_y_plus_btn = "nul" -input_player13_r_y_plus_axis = "nul" -input_player13_r_y_minus = "nul" -input_player13_r_y_minus_btn = "nul" -input_player13_r_y_minus_axis = "nul" -input_player13_turbo = "nul" -input_player13_turbo_btn = "nul" -input_player13_turbo_axis = "nul" -input_player14_b = "nul" -input_player14_b_btn = "nul" -input_player14_b_axis = "nul" -input_player14_y = "nul" -input_player14_y_btn = "nul" -input_player14_y_axis = "nul" -input_player14_select = "nul" -input_player14_select_btn = "nul" -input_player14_select_axis = "nul" -input_player14_start = "nul" -input_player14_start_btn = "nul" -input_player14_start_axis = "nul" -input_player14_up = "nul" -input_player14_up_btn = "nul" -input_player14_up_axis = "nul" -input_player14_down = "nul" -input_player14_down_btn = "nul" -input_player14_down_axis = "nul" -input_player14_left = "nul" -input_player14_left_btn = "nul" -input_player14_left_axis = "nul" -input_player14_right = "nul" -input_player14_right_btn = "nul" -input_player14_right_axis = "nul" -input_player14_a = "nul" -input_player14_a_btn = "nul" -input_player14_a_axis = "nul" -input_player14_x = "nul" -input_player14_x_btn = "nul" -input_player14_x_axis = "nul" -input_player14_l = "nul" -input_player14_l_btn = "nul" -input_player14_l_axis = "nul" -input_player14_r = "nul" -input_player14_r_btn = "nul" -input_player14_r_axis = "nul" -input_player14_l2 = "nul" -input_player14_l2_btn = "nul" -input_player14_l2_axis = "nul" -input_player14_r2 = "nul" -input_player14_r2_btn = "nul" -input_player14_r2_axis = "nul" -input_player14_l3 = "nul" -input_player14_l3_btn = "nul" -input_player14_l3_axis = "nul" -input_player14_r3 = "nul" -input_player14_r3_btn = "nul" -input_player14_r3_axis = "nul" -input_player14_l_x_plus = "nul" -input_player14_l_x_plus_btn = "nul" -input_player14_l_x_plus_axis = "nul" -input_player14_l_x_minus = "nul" -input_player14_l_x_minus_btn = "nul" -input_player14_l_x_minus_axis = "nul" -input_player14_l_y_plus = "nul" -input_player14_l_y_plus_btn = "nul" -input_player14_l_y_plus_axis = "nul" -input_player14_l_y_minus = "nul" -input_player14_l_y_minus_btn = "nul" -input_player14_l_y_minus_axis = "nul" -input_player14_r_x_plus = "nul" -input_player14_r_x_plus_btn = "nul" -input_player14_r_x_plus_axis = "nul" -input_player14_r_x_minus = "nul" -input_player14_r_x_minus_btn = "nul" -input_player14_r_x_minus_axis = "nul" -input_player14_r_y_plus = "nul" -input_player14_r_y_plus_btn = "nul" -input_player14_r_y_plus_axis = "nul" -input_player14_r_y_minus = "nul" -input_player14_r_y_minus_btn = "nul" -input_player14_r_y_minus_axis = "nul" -input_player14_turbo = "nul" -input_player14_turbo_btn = "nul" -input_player14_turbo_axis = "nul" -input_player15_b = "nul" -input_player15_b_btn = "nul" -input_player15_b_axis = "nul" -input_player15_y = "nul" -input_player15_y_btn = "nul" -input_player15_y_axis = "nul" -input_player15_select = "nul" -input_player15_select_btn = "nul" -input_player15_select_axis = "nul" -input_player15_start = "nul" -input_player15_start_btn = "nul" -input_player15_start_axis = "nul" -input_player15_up = "nul" -input_player15_up_btn = "nul" -input_player15_up_axis = "nul" -input_player15_down = "nul" -input_player15_down_btn = "nul" -input_player15_down_axis = "nul" -input_player15_left = "nul" -input_player15_left_btn = "nul" -input_player15_left_axis = "nul" -input_player15_right = "nul" -input_player15_right_btn = "nul" -input_player15_right_axis = "nul" -input_player15_a = "nul" -input_player15_a_btn = "nul" -input_player15_a_axis = "nul" -input_player15_x = "nul" -input_player15_x_btn = "nul" -input_player15_x_axis = "nul" -input_player15_l = "nul" -input_player15_l_btn = "nul" -input_player15_l_axis = "nul" -input_player15_r = "nul" -input_player15_r_btn = "nul" -input_player15_r_axis = "nul" -input_player15_l2 = "nul" -input_player15_l2_btn = "nul" -input_player15_l2_axis = "nul" -input_player15_r2 = "nul" -input_player15_r2_btn = "nul" -input_player15_r2_axis = "nul" -input_player15_l3 = "nul" -input_player15_l3_btn = "nul" -input_player15_l3_axis = "nul" -input_player15_r3 = "nul" -input_player15_r3_btn = "nul" -input_player15_r3_axis = "nul" -input_player15_l_x_plus = "nul" -input_player15_l_x_plus_btn = "nul" -input_player15_l_x_plus_axis = "nul" -input_player15_l_x_minus = "nul" -input_player15_l_x_minus_btn = "nul" -input_player15_l_x_minus_axis = "nul" -input_player15_l_y_plus = "nul" -input_player15_l_y_plus_btn = "nul" -input_player15_l_y_plus_axis = "nul" -input_player15_l_y_minus = "nul" -input_player15_l_y_minus_btn = "nul" -input_player15_l_y_minus_axis = "nul" -input_player15_r_x_plus = "nul" -input_player15_r_x_plus_btn = "nul" -input_player15_r_x_plus_axis = "nul" -input_player15_r_x_minus = "nul" -input_player15_r_x_minus_btn = "nul" -input_player15_r_x_minus_axis = "nul" -input_player15_r_y_plus = "nul" -input_player15_r_y_plus_btn = "nul" -input_player15_r_y_plus_axis = "nul" -input_player15_r_y_minus = "nul" -input_player15_r_y_minus_btn = "nul" -input_player15_r_y_minus_axis = "nul" -input_player15_turbo = "nul" -input_player15_turbo_btn = "nul" -input_player15_turbo_axis = "nul" -input_player16_b = "nul" -input_player16_b_btn = "nul" -input_player16_b_axis = "nul" -input_player16_y = "nul" -input_player16_y_btn = "nul" -input_player16_y_axis = "nul" -input_player16_select = "nul" -input_player16_select_btn = "nul" -input_player16_select_axis = "nul" -input_player16_start = "nul" -input_player16_start_btn = "nul" -input_player16_start_axis = "nul" -input_player16_up = "nul" -input_player16_up_btn = "nul" -input_player16_up_axis = "nul" -input_player16_down = "nul" -input_player16_down_btn = "nul" -input_player16_down_axis = "nul" -input_player16_left = "nul" -input_player16_left_btn = "nul" -input_player16_left_axis = "nul" -input_player16_right = "nul" -input_player16_right_btn = "nul" -input_player16_right_axis = "nul" -input_player16_a = "nul" -input_player16_a_btn = "nul" -input_player16_a_axis = "nul" -input_player16_x = "nul" -input_player16_x_btn = "nul" -input_player16_x_axis = "nul" -input_player16_l = "nul" -input_player16_l_btn = "nul" -input_player16_l_axis = "nul" -input_player16_r = "nul" -input_player16_r_btn = "nul" -input_player16_r_axis = "nul" -input_player16_l2 = "nul" -input_player16_l2_btn = "nul" -input_player16_l2_axis = "nul" -input_player16_r2 = "nul" -input_player16_r2_btn = "nul" -input_player16_r2_axis = "nul" -input_player16_l3 = "nul" -input_player16_l3_btn = "nul" -input_player16_l3_axis = "nul" -input_player16_r3 = "nul" -input_player16_r3_btn = "nul" -input_player16_r3_axis = "nul" -input_player16_l_x_plus = "nul" -input_player16_l_x_plus_btn = "nul" -input_player16_l_x_plus_axis = "nul" -input_player16_l_x_minus = "nul" -input_player16_l_x_minus_btn = "nul" -input_player16_l_x_minus_axis = "nul" -input_player16_l_y_plus = "nul" -input_player16_l_y_plus_btn = "nul" -input_player16_l_y_plus_axis = "nul" -input_player16_l_y_minus = "nul" -input_player16_l_y_minus_btn = "nul" -input_player16_l_y_minus_axis = "nul" -input_player16_r_x_plus = "nul" -input_player16_r_x_plus_btn = "nul" -input_player16_r_x_plus_axis = "nul" -input_player16_r_x_minus = "nul" -input_player16_r_x_minus_btn = "nul" -input_player16_r_x_minus_axis = "nul" -input_player16_r_y_plus = "nul" -input_player16_r_y_plus_btn = "nul" -input_player16_r_y_plus_axis = "nul" -input_player16_r_y_minus = "nul" -input_player16_r_y_minus_btn = "nul" -input_player16_r_y_minus_axis = "nul" -input_player16_turbo = "nul" -input_player16_turbo_btn = "nul" -input_player16_turbo_axis = "nul" -xmb_font = "" -netplay_nickname = "" -video_filter = "" -audio_dsp_plugin = "" -netplay_ip_address = "" -netplay_password = "" -netplay_spectate_password = "" -core_options_path = "" -video_shader = "" -menu_wallpaper = "" -input_overlay = "" -video_font_path = "" -content_history_dir = "" -cache_directory = "" -resampler_directory = "" -recording_output_directory = "" -recording_config_directory = "" -xmb_font = "" -playlist_names = "" -playlist_cores = "" -audio_device = "" -camera_device = "" -cheevos_username = "" -cheevos_password = "" -video_context_driver = "" -input_keyboard_layout = "" -bundle_assets_src_path = "" -bundle_assets_dst_path = "" -bundle_assets_dst_path_subdir = "" +## Skeleton config file for RetroArch + +# Save all save files (*.srm) to this directory. This includes related files like .bsv, .rtc, .psrm, etc ... +# This will be overridden by explicit command line options. +# savefile_directory = + +# Save all save states (*.state) to this directory. +# This will be overridden by explicit command line options. +# savestate_directory = + +# If set to a directory, content which is temporarily extracted +# will be extracted to this directory. +# cache_directory = + +# Save all downloaded files to this directory. +# core_assets_directory = + +# Save all remapped controls to this directory. +# input_remapping_directory = + +# Save all playlists/collections to this directory. +# playlist_directory = + +# If set to a directory, the content history playlist will be saved +# to this directory. +# content_history_dir = + +# Saved queries are stored to this directory. +# cursor_directory = + +# Automatically saves a savestate at the end of RetroArch's lifetime. +# The path is $SRAM_PATH.auto. +# RetroArch will automatically load any savestate with this path on startup if savestate_auto_load is set. +# savestate_auto_save = false +# savestate_auto_load = true + +# Load libretro from a dynamic location for dynamically built RetroArch. +# This option is mandatory. + +# Path to a libretro implementation. +# libretro_path = "/path/to/libretro.so" + +# A directory for where to search for libretro core implementations. +# libretro_directory = + +# A directory for where to search for libretro core information. +# libretro_info_path = + +# Sets log level for libretro cores (GET_LOG_INTERFACE). +# If a log level issued by a libretro core is below libretro_log_level, it is ignored. +# DEBUG logs are always ignored unless verbose mode is activated (--verbose). +# DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3. +# libretro_log_level = 0 + +# Enable or disable verbosity level of frontend. +# log_verbosity = false + +# If this option is enabled, every content file loaded in RetroArch will be +# automatically added to a history list. +# history_list_enable = true + +# Enable performance counters +# perfcnt_enable = false + +# Path to core options config file. +# This config file is used to expose core-specific options. +# It will be written to by RetroArch. +# A default path will be assigned if not set. +# core_options_path = + +# Path to content history file. +# RetroArch keeps track of all content loaded in the menu and from CLI directly for convenient quick loading. +# A default path will be assigned if not set. +# content_history_path = + +# Path to music content history file (optional). +# RetroArch keeps track of all music content loaded in the menu and from CLI directly for convenient quick loading. +# A default path will be assigned if not set. +# content_music_history_path = + +# Path to image content history file (optional). +# RetroArch keeps track of all image content loaded in the menu and from CLI directly for convenient quick loading. +# A default path will be assigned if not set. +# content_image_history_path = + +# Path to video content history file (optional). +# RetroArch keeps track of all video content loaded in the menu and from CLI directly for convenient quick loading. +# A default path will be assigned if not set. +# content_video_history_path = + +# Number of entries that will be kept in content history file. +# content_history_size = 100 + +# Sets the "system" directory. +# Implementations can query for this directory to load BIOSes, system-specific configs, etc. +# system_directory = + +# Sets start directory for menu file browser. +# rgui_browser_directory = + +# Content directory. Interacts with RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY. +# Usually set by developers who bundle libretro/RetroArch apps to point to assets. +# content_directory = + +# Assets directory. This location is queried by default when menu interfaces try to look for +# loadable assets, etc. +# assets_directory = + +# Dynamic wallpapers directory. The place to store the wallpapers dynamically +# loaded by the menu depending on context. +# dynamic_wallpapers_directory = + +# Thumbnails directory. To store thumbnail files. +# thumbnails_directory = + +# Sets start directory for menu config browser. +# rgui_config_directory = + +# Show startup screen in menu. +# Is automatically set to false when seen for the first time. +# This is only updated in config if config_save_on_exit is set to true, however. +# rgui_show_start_screen = true + +# Flushes config to disk on exit. Useful for menu as settings can be modified. +# Overwrites the config. #include's and comments are not preserved. +# config_save_on_exit = true + +# Shows hidden files and folders in directory listings. +# show_hidden_files = true + +#### Video + +# Video driver to use. "gl", "xvideo", "sdl", "d3d" +# video_driver = "gl" + +# Which context implementation to use. +# Possible ones for desktop are: glx, x-egl, kms-egl, sdl-gl, wgl. +# By default, tries to use first suitable driver. +# video_context_driver = + +# Windowed x resolution scale and y resolution scale +# (Real x res: base_size * xscale * aspect_ratio, real y res: base_size * yscale) +# video_scale = 3.0 + +# Fullscreen resolution. Resolution of 0 uses the resolution of the desktop. +# video_fullscreen_x = 0 +# video_fullscreen_y = 0 + +# Start in fullscreen. Can be changed at runtime. +# video_fullscreen = false + +# If fullscreen, prefer using a windowed fullscreen mode. +# video_windowed_fullscreen = true + +# Which monitor to prefer. 0 (default) means no particular monitor is preferred, 1 and up (1 being first monitor), +# suggests RetroArch to use that particular monitor. +# video_monitor_index = 0 + +# Forcibly disable composition. Only works in Windows Vista/7 for now. +# video_disable_composition = false + +# Video vsync. +# video_vsync = true + +# Interval at which a Vsync swap is performed. +# 1 is normal, 2 is doubled frames, 3 is tripled frames, etc. +# video_swap_interval = 1 + +# Max amount of swapchain images. +# Single buffering = 1, Double buffering = 2, 3 = Triple buffering +# video_max_swapchain_images = 3 + +# Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows +# have video problems with sRGB FBO support enabled. +# video_force_srgb_disable = false + +# Attempts to hard-synchronize CPU and GPU. Can reduce latency at cost of performance. +# video_hard_sync = false + +# Sets how many frames CPU can run ahead of GPU when using video_hard_sync. +# Maximum is 3. +# video_hard_sync_frames = 0 + +# Sets how many milliseconds to delay after VSync before running the core. +# Can reduce latency at cost of higher risk of stuttering. +# Maximum is 15. +# video_frame_delay = 0 + +# Inserts a black frame inbetween frames. +# Useful for 120 Hz monitors who want to play 60 Hz material with eliminated ghosting. +# video_refresh_rate should still be configured as if it is a 60 Hz monitor (divide refresh rate by 2). +# video_black_frame_insertion = false + +# Use threaded video driver. Using this might improve performance at possible cost of latency and more video stuttering. +# video_threaded = false + +# Use a shared context for HW rendered libretro cores. +# Avoids having to assume HW state changes inbetween frames. +# video_shared_context = false + +# Smoothens picture with bilinear filtering. Should be disabled if using pixel shaders. +# video_smooth = true + +# Forces rendering area to stay equal to content aspect ratio or as defined in video_aspect_ratio. +# video_force_aspect = true + +# Only scales video in integer steps. +# The base size depends on system-reported geometry and aspect ratio. +# If video_force_aspect is not set, X/Y will be integer scaled independently. +# video_scale_integer = false + +# Index of the aspect ratio selection in the menu. +# 19 = Config, 20 = 1:1 PAR, 21 = Core Provided, 22 = Custom Aspect Ratio +# aspect_ratio_index = 19 + +# A floating point value for video aspect ratio (width / height). +# If this is not set, aspect ratio is assumed to be automatic. +# Behavior then is defined by video_aspect_ratio_auto. +# video_aspect_ratio = + +# If this is true and video_aspect_ratio is not set, +# aspect ratio is decided by libretro implementation. +# If this is false, 1:1 PAR will always be assumed if video_aspect_ratio is not set. +# video_aspect_ratio_auto = false + +# Forces cropping of overscanned frames. +# Exact behavior of this option is implementation specific. +# video_crop_overscan = true + +# Path to shader. Shader can be either Cg, CGP (Cg preset) or GLSL, GLSLP (GLSL preset) +# video_shader = "/path/to/shader.{cg,cgp,glsl,glslp}" + +# Load video_shader on startup. +# Other shaders can still be loaded later in runtime. +# video_shader_enable = false + +# Defines a directory where shaders (Cg, CGP, GLSL) are kept for easy access. +# video_shader_dir = + +# CPU-based video filter. Path to a dynamic library. +# video_filter = + +# Defines a directory where CPU-based video filters are kept. +# video_filter_dir = + +# Path to a font used for rendering messages. This path must be defined to enable fonts. +# Do note that the _full_ path of the font is necessary! +# video_font_path = + +# Size of the font rendered in points. +# video_font_size = 32 + +# Enable usage of OSD messages. +# video_font_enable = true + +# Offset for where messages will be placed on screen. Values are in range 0.0 to 1.0 for both x and y values. +# [0.0, 0.0] maps to the lower left corner of the screen. +# video_message_pos_x = 0.05 +# video_message_pos_y = 0.05 + +# Color for message. The value is treated as a hexadecimal value. +# It is a regular RGB hex number, i.e. red is "ff0000". +# video_message_color = ffffff + +# Video refresh rate of your monitor. +# Used to calculate a suitable audio input rate. +# video_refresh_rate = 59.94 + +# Allows libretro cores to set rotation modes. +# Setting this to false will honor, but ignore this request. +# This is useful for vertically oriented content where one manually rotates the monitor. +# video_allow_rotate = true + +# Forces a certain rotation of the screen. +# The rotation is added to rotations which the libretro core sets (see video_allow_rotate). +# The angle is * 90 degrees counter-clockwise. +# video_rotation = 0 + +#### Audio + +# Enable audio. +# audio_enable = true + +# Mutes audio. +# audio_mute_enable = false + +# Audio output samplerate. +# audio_out_rate = 48000 + +# Audio resampler backend. Which audio resampler to use. +# Default will use "sinc". +# audio_resampler = + +# Audio driver backend. Depending on configuration possible candidates are: alsa, pulse, oss, jack, rsound, roar, openal, sdl, xaudio. +# audio_driver = + +# Override the default audio device the audio_driver uses. This is driver dependant. E.g. ALSA wants a PCM device, OSS wants a path (e.g. /dev/dsp), Jack wants portnames (e.g. system:playback1,system:playback_2), and so on ... +# audio_device = + +# Audio DSP plugin that processes audio before it's sent to the driver. Path to a dynamic library. +# audio_dsp_plugin = + +# Directory where DSP plugins are kept. +# audio_filter_dir = + +# Will sync (block) on audio. Recommended. +# audio_sync = true + +# Desired audio latency in milliseconds. Might not be honored if driver can't provide given latency. +# audio_latency = 64 + +# Enable audio rate control. +# audio_rate_control = true + +# Controls audio rate control delta. Defines how much input rate can be adjusted dynamically. +# Input rate = in_rate * (1.0 +/- audio_rate_control_delta) +# audio_rate_control_delta = 0.005 + +# Controls maximum audio timing skew. Defines the maximum change in input rate. +# Input rate = in_rate * (1.0 +/- max_timing_skew) +# audio_max_timing_skew = 0.05 + +# Audio volume. Volume is expressed in dB. +# 0 dB is normal volume. No gain will be applied. +# Gain can be controlled in runtime with input_volume_up/input_volume_down. +# audio_volume = 0.0 + +#### Overlay + +# Defines a directory where overlays are kept for easy access. +# overlay_directory = + +# Enable the overlay. +# input_overlay_enable = true + +# Hide the current overlay from appearing inside the menu. +# input_overlay_hide_in_menu = true + +# Path to input overlay. +# input_overlay = + +# Opacity of all the UI elements of the overlay. +# input_overlay_opacity = 1.0 + +# Scale of all UI elements of the overlay. +# input_overlay_scale = 1.0 + +#### Input + +# Input driver. Depending on video driver, it might force a different input driver. +# input_driver = sdl + +# Joypad driver. (Valid: linuxraw, sdl, dinput) +# input_joypad_driver = + +# Path to input remapping file. +# input_remapping_path = + +# Input bind timer timeout. +# Amount of seconds to wait until proceeding to the next bind. Default: 5, minimum: 1 +# input_bind_timeout = 1 + +# If enabled, overrides the input binds with the remapped binds set for the current core. +# input_remap_binds_enable = true + +# Maximum amount of users supported by RetroArch. +# input_max_users = 16 + +# Keyboard layout for input driver if applicable (udev/evdev for now). +# Syntax is either just layout (e.g. "no"), or a layout and variant separated with colon ("no:nodeadkeys"). +# input_keyboard_layout = + +# Defines axis threshold. Possible values are [0.0, 1.0] +# input_axis_threshold = 0.5 + +# Enable input auto-detection. Will attempt to autoconfigure +# joypads, Plug-and-Play style. +# input_autodetect_enable = true + +# Show the input descriptors set by the core instead of the +# default ones. +# input_descriptor_label_show = true + +# Hide input descriptors that were not set by the core. +# input_descriptor_hide_unbound = false + +# Influence how input polling is done inside RetroArch. +# 0 : Early - Input polling is performed before call to retro_run. +# 1 : Normal - Input polling is performed when retro_input_poll is +# requested. +# 2 : Late - Input polling is performed on first call to retro_input_state +# per frame +# +# Setting it to 0 or 2 can result in less latency depending on +# your configuration. +# +# When netplay is enabled, the default polling behavior (1) will +# be used regardless of the value set here. +# input_poll_type_behavior = 1 + +# Directory for joypad autoconfigs. +# If a joypad is plugged in, that joypad will be autoconfigured if a config file +# corresponding to that joypad is present in joypad_autoconfig_dir. +# Input binds which are made explicit (input_playerN_*_btn/axis) will take priority over autoconfigs. +# Autoconfigs can be created with retroarch-joyconfig, manually, or with a frontend. +# Requires input_autodetect_enable to be enabled. +# joypad_autoconfig_dir = + +# Sets which libretro device is used for a user. +# Devices are indentified with a number. +# This is normally saved by the menu. +# Device IDs are found in libretro.h. +# These settings are overridden by explicit command-line arguments which refer to input devices. +# None: 0 +# Joypad (RetroPad): 1 +# Mouse: 2 +# Keyboard: 3 +# Generic Lightgun: 4 +# Joypad w/ Analog (RetroPad + Analog sticks): 5 +# Multitap (SNES specific): 257 +# Super Scope (SNES specific): 260 +# Justifier (SNES specific): 516 +# Justifiers (SNES specific): 772 + +# input_libretro_device_p1 = +# input_libretro_device_p2 = +# input_libretro_device_p3 = +# input_libretro_device_p4 = +# input_libretro_device_p5 = +# input_libretro_device_p6 = +# input_libretro_device_p7 = +# input_libretro_device_p8 = + +# Keyboard input. Will recognize letters ("a" to "z") and the following special keys (where "kp_" +# is for keypad keys): +# +# left, right, up, down, enter, kp_enter, tab, insert, del, end, home, +# rshift, shift, ctrl, alt, space, escape, add, subtract, kp_plus, kp_minus, +# f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, +# num0, num1, num2, num3, num4, num5, num6, num7, num8, num9, pageup, pagedown, +# keypad0, keypad1, keypad2, keypad3, keypad4, keypad5, keypad6, keypad7, keypad8, keypad9, +# period, capslock, numlock, backspace, multiply, divide, print_screen, scroll_lock, +# tilde, backquote, pause, quote, comma, minus, slash, semicolon, equals, leftbracket, +# backslash, rightbracket, kp_period, kp_equals, rctrl, ralt +# +# Keyboard input, Joypad and Joyaxis will all obey the "nul" bind, which disables the bind completely, +# rather than relying on a default. +# input_player1_a = "x" +# input_player1_b = "z" +# input_player1_y = "a" +# input_player1_x = "s" +# input_player1_start = "enter" +# input_player1_select = "rshift" +# input_player1_l = "q" +# input_player1_r = "w" +# input_player1_left = "left" +# input_player1_right = "right" +# input_player1_up = "up" +# input_player1_down = "down" +# input_player1_l2 = +# input_player1_r2 = +# input_player1_l3 = +# input_player1_r3 = + +# Two analog sticks (DualShock-esque). +# Bound as usual, however, if a real analog axis is bound, +# it can be read as a true analog. +# Positive X axis is right, Positive Y axis is down. +# input_player1_l_x_plus = +# input_player1_l_x_minus = +# input_player1_l_y_plus = +# input_player1_l_y_minus = +# input_player1_r_x_plus = +# input_player1_r_x_minus = +# input_player1_r_y_plus = +# input_player1_r_y_minus = + +# If desired, it is possible to override which joypads are being used for user 1 through 8. +# First joypad available is 0. +# input_player1_joypad_index = 0 +# input_player2_joypad_index = 1 +# input_player3_joypad_index = 2 +# input_player4_joypad_index = 3 +# input_player5_joypad_index = 4 +# input_player6_joypad_index = 5 +# input_player7_joypad_index = 6 +# input_player8_joypad_index = 7 + +# Input device buttons. +# Figure these out by using RetroArch-Phoenix or retroarch-joyconfig. +# You can use joypad hats with hnxx, where n is the hat, and xx is a string representing direction. +# E.g. "h0up" +# input_player1_a_btn = +# input_player1_b_btn = +# input_player1_y_btn = +# input_player1_x_btn = +# input_player1_start_btn = +# input_player1_select_btn = +# input_player1_l_btn = +# input_player1_r_btn = +# input_player1_left_btn = +# input_player1_right_btn = +# input_player1_up_btn = +# input_player1_down_btn = +# input_player1_l2_btn = +# input_player1_r2_btn = +# input_player1_l3_btn = +# input_player1_r3_btn = + +# Menu buttons. +# menu_search_btn = +# menu_info_btn = +# menu_default_btn = +# menu_scroll_down_btn = +# menu_scroll_up_btn = + +# Swap buttons for OK/Cancel +# menu_swap_ok_cancel_buttons = false + +# Axis for RetroArch D-Pad. +# Needs to be either '+' or '-' in the first character signaling either positive or negative direction of the axis, then the axis number. +# Do note that every other input option has the corresponding _btn and _axis binds as well; they are omitted here for clarity. +# input_player1_left_axis = +# input_player1_right_axis = +# input_player1_up_axis = +# input_player1_down_axis = + +# Holding the turbo while pressing another button will let the button enter a turbo mode +# where the button state is modulated with a periodic signal. +# The modulation stops when the button itself (not turbo button) is released. +# input_player1_turbo = + +# Describes the period and how long of that period a turbo-enabled button should behave. +# Numbers are described in frames. +# input_turbo_period = 6 +# input_turbo_duty_cycle = 3 + +# This goes all the way to user 8 (*_player2_*, *_player3_*, etc), but omitted for clarity. +# All input binds have corresponding binds for keyboard (none), joykeys (_btn) and joyaxes (_axis) as well. + +# Toggles fullscreen. +# input_toggle_fullscreen = f + +# Saves state. +# input_save_state = f2 +# Loads state. +# input_load_state = f4 + +# State slots. With slot set to 0, save state name is *.state (or whatever defined on commandline). +# When slot is != 0, path will be $path%d, where %d is slot number. +# input_state_slot_increase = f7 +# input_state_slot_decrease = f6 + +# Toggles between fast-forwarding and normal speed. +# input_toggle_fast_forward = space + +# Hold for fast-forward. Releasing button disables fast-forward. +# input_hold_fast_forward = l + +# Key to exit RetroArch cleanly. +# Killing it in any hard way (SIGKILL, etc) will terminate RetroArch without saving RAM, etc. +# On Unix-likes, SIGINT/SIGTERM allows a clean deinitialization. +# input_exit_emulator = escape + + +# Applies next and previous shader in directory. +# input_shader_next = m +# input_shader_prev = n + +# Hold button down to rewind. Rewinding must be enabled. +# input_rewind = r + +# Toggle between recording and not. +# input_movie_record_toggle = o + +# Toggle between paused and non-paused state +# input_pause_toggle = p + +# Frame advance when content is paused +# input_frame_advance = k + +# Reset the content. +# input_reset = h + +# Cheats. +# input_cheat_index_plus = y +# input_cheat_index_minus = t +# input_cheat_toggle = u + +# Mute/unmute audio +# input_audio_mute = f9 + +# Take screenshot +# input_screenshot = f8 + +# Netplay flip users. +# input_netplay_flip_players = i + +# Hold for slowmotion. +# input_slowmotion = e + +# Enable other hotkeys. +# If this hotkey is bound to either keyboard, joybutton or joyaxis, +# all other hotkeys will be disabled unless this hotkey is also held at the same time. +# This is useful for RETRO_KEYBOARD centric implementations +# which query a large area of the keyboard, where it is not desirable +# that hotkeys get in the way. + +# Alternatively, all hotkeys for keyboard could be disabled by the user. +# input_enable_hotkey_btn = + +# Increases audio volume. +# input_volume_up = kp_plus +# Decreases audio volume. +# input_volume_down = kp_minus + +# Toggles to next overlay. Wraps around. +# input_overlay_next = + +# Toggles eject for disks. Used for multiple-disk content. +# input_disk_eject_toggle = + +# Cycles through disk images. Use after ejecting. +# Complete by toggling eject again. +# input_disk_next = + +# Toggles menu. +# input_menu_toggle = f1 + +# RetroPad button combination to toggle menu +# 0 = none, 1 = L + R + Y + D-Pad Down, 2 = L3 + R3, 3 = Start + Select +# input_menu_toggle_gamepad_combo = 0 + +# allow any RetroPad to control the menu +# all_users_control_menu = false + +# Toggles mouse grab. When mouse is grabbed, RetroArch hides the mouse, +# and keeps the mouse pointer inside the window to allow relative mouse input +# to work better. +# input_grab_mouse_toggle = f11 + +#### Menu + +# Menu driver to use. "rgui", "lakka", etc. +# menu_driver = "rgui" + +# If disabled, the libretro core will keep running in the background when we +# are in the menu. +# menu_pause_libretro = false + +# If disabled, we use separate controls for menu operation. +# menu_unified_controls = false + +# Enable mouse controls inside the menu. +# menu_mouse_enable = false + +# Enable touch controls inside the menu. +# menu_pointer_enable = false + +# Shows current date and/or time inside menu. +# menu_timedate_enable = true + +# Shows current battery level inside menu. +# menu_battery_level_enable = true + +# Shows current core inside menu. +# menu_core_enable = true + +# Path to an image to set as menu wallpaper. +# menu_wallpaper = + +# Dynamically load a new wallpaper depending on context. +# menu_dynamic_wallpaper_enable = false + +# Type of thumbnail to display. 0 = none, 1 = snaps, 2 = titles, 3 = boxarts +# menu_thumbnails = 0 + +# Wrap-around to beginning and/or end if boundary of list is reached horizontally or vertically. +# menu_navigation_wraparound_enable = false + +# Filter files being shown in filebrowser by supported extensions. +# menu_navigation_browser_filter_supported_extensions_enable = true + +# Collapse subgroup settings into main group to create one big listing of settings +# per category. +# menu_collapse_subgroups_enable = false + +#### Core +# +# Prevent libretro cores from closing RetroArch on exit by loading a dummy core. +# load_dummy_on_core_shutdown = "true" + +# Check for firmware requirement(s) before loading a content. +# check_firmware_before_loading = "false" + +#### UI + +# Suspends the screensaver if set to true. Is a hint that does not necessarily have to be honored +# by video driver. +# suspend_screensaver_enable = true + +# Start UI companion driver's interface on boot (if available). +# ui_companion_start_on_boot = true + +#### Camera + +# Override the default camera device the camera driver uses. This is driver dependant. +# camera_device = + +# Override the default privacy permission for cores that want to access camera services. Is "false" by default. +# camera_allow = false + +#### Location + +# Override the default privacy permission for cores that want to access location services. Is "false" by default. +# location_allow = false + +#### Core Updater + +# URL to core update directory on buildbot. +# core_updater_buildbot_url = "http://buildbot.libretro.com" + +# URL to assets update directory on buildbot. +# core_updater_buildbot_assets_url = "http://buildbot.libretro.com/assets/" + +# After downloading, automatically extract archives that the downloads are contained inside. +# core_updater_auto_extract_archive = true + +#### Network + +# When being client over netplay, use keybinds for user 1. +# netplay_client_swap_input = false + +# The username of the person running RetroArch. This will be used for playing online, for instance. +# netplay_nickname = + +# The amount of delay frames to use for netplay. Increasing this value will increase +# performance, but introduce more latency. +# netplay_delay_frames = 0 + +# Netplay mode for the current user. +# false is Server, true is Client. +# netplay_mode = false + +# Enable or disable spectator mode for the user during netplay. +# netplay_spectator_mode_enable = false + +# The IP Address of the host to connect to. +# netplay_ip_address = + +# The port of the host IP Address. Can be either a TCP or UDP port. +# netplay_ip_port = 55435 + +#### Misc + +# Enable rewinding. This will take a performance hit when playing, so it is disabled by default. +# rewind_enable = false + +# Rewinding buffer size in megabytes. Bigger rewinding buffer means you can rewind longer. +# The buffer should be approx. 20MB per minute of buffer time. +# rewind_buffer_size = 20 + +# Rewind granularity. When rewinding defined number of frames, you can rewind several frames at a time, increasing the rewinding speed. +# rewind_granularity = 1 + +# Pause gameplay when window focus is lost. +# pause_nonactive = true + +# Autosaves the non-volatile SRAM at a regular interval. This is disabled by default unless set otherwise. +# The interval is measured in seconds. A value of 0 disables autosave. +# autosave_interval = + +# Path to content database directory. +# content_database_path = + +# Path to cheat database directory. +# cheat_database_path = + +# Directory to dump screenshots to. +# screenshot_directory = + +# Records video after CPU video filter. +# video_post_filter_record = false + +# Records output of GPU shaded material if available. +# video_gpu_record = false + +# Screenshots output of GPU shaded material if available. +# video_gpu_screenshot = true + +# Block SRAM from being overwritten when loading save states. +# Might potentially lead to buggy games. +# block_sram_overwrite = false + +# When saving a savestate, save state index is automatically increased before +# it is saved. +# Also, when loading content, the index will be set to the highest existing index. +# There is no upper bound on the index. +# savestate_auto_index = false + +# Slowmotion ratio. When slowmotion, content will slow down by factor. +# slowmotion_ratio = 3.0 + +# The maximum rate at which content will be run when using fast forward. (E.g. 5.0 for 60 fps content => 300 fps cap). +# RetroArch will go to sleep to ensure that the maximum rate will not be exceeded. +# Do not rely on this cap to be perfectly accurate. +# If this is set at 0, then fastforward ratio is unlimited (no FPS cap) +# fastforward_ratio = 0.0 + +# Enable stdin/network command interface. +# network_cmd_enable = false +# network_cmd_port = 55355 +# stdin_cmd_enable = false From 0ef09a0ed46d87c137f8b18c3cc278e2e46479d4 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 4 Feb 2017 16:24:14 -0600 Subject: [PATCH 12/90] win32 scond_wait_timeout: refine 0 timeout logic --- libretro-common/rthreads/rthreads.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 32a306cfb1..c61ca1096a 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -547,7 +547,6 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds /* If any other wakenings are pending, go ahead and set it up */ /* There may actually be no waiters. That's OK. The first waiter will come in, find it's his turn, and immediately get the signaled event */ - printf("%d\n",cond->wakens); cond->wakens--; if (cond->wakens > 0) { @@ -663,11 +662,18 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) { #ifdef USE_WIN32_THREADS /* How to convert a us timeout to ms? */ - /* Someone asking for a 0 timeout clearly wants no timeout. */ + /* Someone asking for a 0 timeout clearly wants immediate timeout. */ /* Someone asking for a 1 timeout clearly wants an actual timeout of the minimum length */ /* Someone asking for 1000 or 1001 timeout shouldn't accidentally get 2ms. */ DWORD dwMilliseconds = timeout_us/1000; - if(timeout_us < 1000) dwMilliseconds = 1; + if(timeout_us == 0) { + /* The implementation of a 0 timeout here with pthreads is sketchy. */ + /* It isn't clear what happens if pthread_cond_timedwait is called with NOW. */ + /* Moreover, it is possible that this thread gets pre-empted after the clock_gettime but before the pthread_cond_timedwait. */ + /* In order to help smoke out problems caused by this strange usage, let's treat a 0 timeout as always timing out. */ + return false; + } + else if(timeout_us < 1000) dwMilliseconds = 1; return _scond_wait_win32(cond,lock,dwMilliseconds); #else int ret; From df962d589802a18111d75f22aac886f91937c2ee Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 05:45:08 +0100 Subject: [PATCH 13/90] Silence warnings --- libretro-common/rthreads/rthreads.c | 117 ++++++++++++++++------------ 1 file changed, 68 insertions(+), 49 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 84a66a8b42..a37fe078e4 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -383,7 +383,7 @@ scond_t *scond_new(void) cond->head = NULL; #else - if(pthread_cond_init(&cond->cond, NULL) != 0) + if (pthread_cond_init(&cond->cond, NULL) != 0) goto error; #endif @@ -431,7 +431,7 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds EnterCriticalSection(&cond->cs); /* since this library is meant for realtime game software I have no problem setting this to 1 and forgetting about it. */ - if(!beginPeriod) + if (!beginPeriod) { beginPeriod = true; timeBeginPeriod(1); @@ -439,47 +439,56 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds /* Now we can take a good timestamp for use in faking the timeout ourselves. */ /* But don't bother unless we need to (to save a little time) */ - if(dwMilliseconds != INFINITE) + if (dwMilliseconds != INFINITE) tsBegin = timeGetTime(); /* add ourselves to a queue of waiting threads */ ptr = &cond->head; - while(*ptr) /* walk to the end of the linked list */ + + /* walk to the end of the linked list */ + while (*ptr) ptr = &((*ptr)->next); + *ptr = &myentry; myentry.next = NULL; cond->waiters++; - /* now the conceptual lock release and condition block are supposed to be atomic. */ - /* we can't do that in windows, but we can simulate the effects by using the queue, by the following analysis: */ - /* What happens if they aren't atomic? */ - /* 1. a signaller can rush in and signal, expecting a waiter to get it; but the waiter wouldn't, because he isn't blocked yet */ - /* solution: win32 events make this easy. the event will sit there enabled */ - /* 2. a signaller can rush in and signal, and then turn right around and wait */ - /* solution: the signaller will get queued behind the waiter, who's enqueued before he releases the mutex */ + /* now the conceptual lock release and condition block are supposed to be atomic. + * we can't do that in Windows, but we can simulate the effects by using + * the queue, by the following analysis: + * What happens if they aren't atomic? + * + * 1. a signaller can rush in and signal, expecting a waiter to get it; + * but the waiter wouldn't, because he isn't blocked yet. + * Solution: Win32 events make this easy. The event will sit there enabled + * + * 2. a signaller can rush in and signal, and then turn right around and wait. + * Solution: the signaller will get queued behind the waiter, who's + * enqueued before he releases the mutex. */ - /* It's my turn if I'm the head of the queue. Check to see if it's my turn. */ + /* It's my turn if I'm the head of the queue. + * Check to see if it's my turn. */ while (cond->head != &myentry) { /* It isn't my turn: */ - DWORD timeout = INFINITE; - /* As long as someone is even going to be able to wake up when they receive the potato, keep it going round */ + /* As long as someone is even going to be able to wake up + * when they receive the potato, keep it going round. */ if (cond->wakens > 0) SetEvent(cond->hot_potato); /* Assess the remaining timeout time */ - if(dwMilliseconds != INFINITE) + if (dwMilliseconds != INFINITE) { - DWORD now = timeGetTime(); + DWORD now = timeGetTime(); DWORD elapsed = now - tsBegin; - if(elapsed > dwMilliseconds) - { - /* Try one last time with a zero timeout (keeps the code simpler) */ + + /* Try one last time with a zero timeout (keeps the code simpler) */ + if (elapsed > dwMilliseconds) elapsed = dwMilliseconds; - } + timeout = dwMilliseconds - elapsed; } @@ -487,7 +496,8 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds LeaveCriticalSection(&lock->lock); LeaveCriticalSection(&cond->cs); - /* Wait a while to catch the hot potato.. someone else should get a chance to go */ + /* Wait a while to catch the hot potato.. + * someone else should get a chance to go */ /* After all, it isn't my turn (and it must be someone else's) */ Sleep(0); waitResult = WaitForSingleObject(cond->hot_potato, timeout); @@ -496,23 +506,27 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds EnterCriticalSection(&lock->lock); EnterCriticalSection(&cond->cs); - if(waitResult == WAIT_TIMEOUT) + if (waitResult == WAIT_TIMEOUT) { - /* Out of time! Now, let's think about this. I do have the potato now--maybe it's my turn, and I have the event? */ - /* If that's the case, I could proceed right now without aborting due to timeout. */ - /* However.. I DID wait a real long time. The caller was willing to wait that long. */ - /* I choose to give him one last chance with a zero timeout in the next step */ - if(cond->head == &myentry) + /* Out of time! Now, let's think about this. I do have the potato now-- + * maybe it's my turn, and I have the event? + * If that's the case, I could proceed right now without aborting due to timeout. + * However.. I DID wait a real long time. The caller was willing to wait that long. + * I choose to give him one last chance with a zero timeout in the next step + */ + if (cond->head == &myentry) { dwFinalTimeout = 0; break; } else { - /* It's not our turn and we're out of time. Give up. */ - /* Remove ourself from the queue and bail. */ + /* It's not our turn and we're out of time. Give up. + * Remove ourself from the queue and bail. */ struct QueueEntry* curr = cond->head; - while(curr->next != &myentry) curr = curr->next; + + while (curr->next != &myentry) + curr = curr->next; curr->next = myentry.next; cond->waiters--; LeaveCriticalSection(&cond->cs); @@ -541,7 +555,7 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds cond->head = myentry.next; cond->waiters--; - if(waitResult == WAIT_TIMEOUT) + if (waitResult == WAIT_TIMEOUT) { /* Oops! ran out of time in the final wait. Just bail. */ LeaveCriticalSection(&cond->cs); @@ -590,12 +604,13 @@ void scond_wait(scond_t *cond, slock_t *lock) int scond_broadcast(scond_t *cond) { #ifdef USE_WIN32_THREADS - /* remember: we currently have mutex */ - if(cond->waiters == 0) return 0; + if (cond->waiters == 0) + return 0; /* awaken everything which is currently queued up */ - if(cond->wakens == 0) SetEvent(cond->event); + if (cond->wakens == 0) + SetEvent(cond->event); cond->wakens = cond->waiters; /* Since there is now at least one pending waken, the potato must be in play */ @@ -623,22 +638,24 @@ void scond_signal(scond_t *cond) EnterCriticalSection(&cond->cs); /* remember: we currently have mutex */ - if(cond->waiters == 0) + if (cond->waiters == 0) { LeaveCriticalSection(&cond->cs); return; } /* wake up the next thing in the queue */ - if(cond->wakens == 0) SetEvent(cond->event); + if (cond->wakens == 0) + SetEvent(cond->event); + cond->wakens++; - /* The data structure is done being modified.. I think we can leave the CS now. */ - /* This would prevent some other thread from receiving the hot potato and then - /* immediately stalling for the critical section. */ - /* But remember, we were trying to replicate a semantic where this entire scond_signal call - /* was controlled (by the user) by a lock. */ - /* So in case there's trouble with this, we can move it after SetEvent() */ + /* The data structure is done being modified.. I think we can leave the CS now. + * This would prevent some other thread from receiving the hot potato and then + * immediately stalling for the critical section. + * But remember, we were trying to replicate a semantic where this entire scond_signal call + * was controlled (by the user) by a lock. + * So in case there's trouble with this, we can move it after SetEvent() */ LeaveCriticalSection(&cond->cs); /* Since there is now at least one pending waken, the potato must be in play */ @@ -669,14 +686,16 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) /* Someone asking for a 1 timeout clearly wants an actual timeout of the minimum length */ /* Someone asking for 1000 or 1001 timeout shouldn't accidentally get 2ms. */ DWORD dwMilliseconds = timeout_us/1000; - if(timeout_us == 0) { - /* The implementation of a 0 timeout here with pthreads is sketchy. */ - /* It isn't clear what happens if pthread_cond_timedwait is called with NOW. */ - /* Moreover, it is possible that this thread gets pre-empted after the clock_gettime but before the pthread_cond_timedwait. */ - /* In order to help smoke out problems caused by this strange usage, let's treat a 0 timeout as always timing out. */ + + /* The implementation of a 0 timeout here with pthreads is sketchy. */ + /* It isn't clear what happens if pthread_cond_timedwait is called with NOW. */ + /* Moreover, it is possible that this thread gets pre-empted after the clock_gettime but before the pthread_cond_timedwait. */ + /* In order to help smoke out problems caused by this strange usage, let's treat a 0 timeout as always timing out. */ + if (timeout_us == 0) return false; - } - else if(timeout_us < 1000) dwMilliseconds = 1; + else if (timeout_us < 1000) + dwMilliseconds = 1; + return _scond_wait_win32(cond,lock,dwMilliseconds); #else int ret; From e99ba9a06a84f2380deb83175b1e1f297499e832 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 05:47:15 +0100 Subject: [PATCH 14/90] Cleanups --- libretro-common/rthreads/rthreads.c | 45 +++++++++++++++++++---------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index a37fe078e4..4d627214db 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -544,10 +544,12 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds LeaveCriticalSection(&cond->cs); /* Wait for someone to actually signal this condition */ - /* We're the only waiter waiting on the event right now -- everyone else is waiting on something different */ + /* We're the only waiter waiting on the event right now -- everyone else + * is waiting on something different */ waitResult = WaitForSingleObject(cond->event, dwFinalTimeout); - /* Take the main lock so we can do work. Nobody else waits on this lock for very long, so even though it's GO TIME we won't have to wait long */ + /* Take the main lock so we can do work. Nobody else waits on this lock + * for very long, so even though it's GO TIME we won't have to wait long */ EnterCriticalSection(&lock->lock); EnterCriticalSection(&cond->cs); @@ -563,13 +565,15 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds } /* If any other wakenings are pending, go ahead and set it up */ - /* There may actually be no waiters. That's OK. The first waiter will come in, find it's his turn, and immediately get the signaled event */ + /* There may actually be no waiters. That's OK. The first waiter will come in, + * find it's his turn, and immediately get the signaled event */ cond->wakens--; if (cond->wakens > 0) { SetEvent(cond->event); - /* Progress the queue: Put the hot potato back into play. It'll be tossed around until next in line gets it */ + /* Progress the queue: Put the hot potato back into play. It'll be + * tossed around until next in line gets it */ SetEvent(cond->hot_potato); } @@ -633,8 +637,10 @@ void scond_signal(scond_t *cond) { #ifdef USE_WIN32_THREADS - /* Unfortunately, pthread_cond_signal does not require that the lock be held in advance */ - /* To avoid stomping on the condvar from other threads, we need to control access to it with this */ + /* Unfortunately, pthread_cond_signal does not require that the + * lock be held in advance */ + /* To avoid stomping on the condvar from other threads, we need + * to control access to it with this */ EnterCriticalSection(&cond->cs); /* remember: we currently have mutex */ @@ -653,8 +659,8 @@ void scond_signal(scond_t *cond) /* The data structure is done being modified.. I think we can leave the CS now. * This would prevent some other thread from receiving the hot potato and then * immediately stalling for the critical section. - * But remember, we were trying to replicate a semantic where this entire scond_signal call - * was controlled (by the user) by a lock. + * But remember, we were trying to replicate a semantic where this entire + * scond_signal call was controlled (by the user) by a lock. * So in case there's trouble with this, we can move it after SetEvent() */ LeaveCriticalSection(&cond->cs); @@ -681,16 +687,23 @@ void scond_signal(scond_t *cond) bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us) { #ifdef USE_WIN32_THREADS - /* How to convert a us timeout to ms? */ - /* Someone asking for a 0 timeout clearly wants immediate timeout. */ - /* Someone asking for a 1 timeout clearly wants an actual timeout of the minimum length */ - /* Someone asking for 1000 or 1001 timeout shouldn't accidentally get 2ms. */ + /* How to convert a microsecond (us) timeout to millisecond (ms)? + * + * Someone asking for a 0 timeout clearly wants immediate timeout. + * Someone asking for a 1 timeout clearly wants an actual timeout + * of the minimum length */ + + /* Someone asking for 1000 or 1001 timeout shouldn't + * accidentally get 2ms. */ DWORD dwMilliseconds = timeout_us/1000; - /* The implementation of a 0 timeout here with pthreads is sketchy. */ - /* It isn't clear what happens if pthread_cond_timedwait is called with NOW. */ - /* Moreover, it is possible that this thread gets pre-empted after the clock_gettime but before the pthread_cond_timedwait. */ - /* In order to help smoke out problems caused by this strange usage, let's treat a 0 timeout as always timing out. */ + /* The implementation of a 0 timeout here with pthreads is sketchy. + * It isn't clear what happens if pthread_cond_timedwait is called with NOW. + * Moreover, it is possible that this thread gets pre-empted after the + * clock_gettime but before the pthread_cond_timedwait. + * In order to help smoke out problems caused by this strange usage, + * let's treat a 0 timeout as always timing out. + */ if (timeout_us == 0) return false; else if (timeout_us < 1000) From e95f797307c57086ebe32069e34b152df0441a85 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 06:01:22 +0100 Subject: [PATCH 15/90] Try to stay under max. 80-char width limit --- libretro-common/rthreads/rthreads.c | 67 ++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/libretro-common/rthreads/rthreads.c b/libretro-common/rthreads/rthreads.c index 4d627214db..c381427d6c 100644 --- a/libretro-common/rthreads/rthreads.c +++ b/libretro-common/rthreads/rthreads.c @@ -100,10 +100,13 @@ struct QueueEntry struct scond { #ifdef USE_WIN32_THREADS - /* With this implementation of scond, we don't have any way of waking (or even identifying) specific threads */ - /* But we need to wake them in the order indicated by the queue. */ - /* This potato token will get get passed around every waiter. The bearer can test whether he's next, and hold onto the potato if he is. */ - /* When he's done he can then put it back into play to progress the queue further */ + /* With this implementation of scond, we don't have any way of waking + * (or even identifying) specific threads + * But we need to wake them in the order indicated by the queue. + * This potato token will get get passed around every waiter. + * The bearer can test whether he's next, and hold onto the potato if he is. + * When he's done he can then put it back into play to progress + * the queue further */ HANDLE hot_potato; /* The primary signalled event. Hot potatoes are passed until this is set. */ @@ -115,7 +118,8 @@ struct scond /* equivalent to the queue length */ int waiters; - /* how many waiters in the queue have been conceptually wakened by signals (even if we haven't managed to actually wake them yet) */ + /* how many waiters in the queue have been conceptually wakened by signals + * (even if we haven't managed to actually wake them yet) */ int wakens; /* used to control access to this scond, in case the user fails */ @@ -359,16 +363,31 @@ scond_t *scond_new(void) #ifdef USE_WIN32_THREADS - /* This is very complex because recreating condition variable semantics with win32 parts is not easy */ - /* The main problem is that a condition variable can't be used to "pre-wake" a thread (it will get wakened only after it's waited) */ - /* whereas a win32 event can pre-wake a thread (the event will be set in advance, so a 'waiter' won't even have to wait on it) */ - /* Keep in mind a condition variable can apparently pre-wake a thread, insofar as spurious wakeups are always possible, */ - /* but nobody will be expecting this and it does not need to be simulated. */ - /* Moreover, we won't be doing this, because it counts as a spurious wakeup -- someone else with a genuine claim must get wakened, in any case. */ - /* Therefore we choose to wake only one of the correct waiting threads. */ - /* So at the very least, we need to do something clever. But there's bigger problems. */ - /* We don't even have a straightforward way in win32 to satisfy pthread_cond_wait's atomicity requirement. The bulk of this algorithm is solving that. */ - /* Note: We might could simplify this using vista+ condition variables, but we wanted an XP compatible solution. */ + /* This is very complex because recreating condition variable semantics + * with Win32 parts is not easy. + * + * The main problem is that a condition variable can't be used to + * "pre-wake" a thread (it will get wakened only after it's waited). + * + * Whereas a win32 event can pre-wake a thread (the event will be set + * in advance, so a 'waiter' won't even have to wait on it). + * + * Keep in mind a condition variable can apparently pre-wake a thread, + * insofar as spurious wakeups are always possible, + * but nobody will be expecting this and it does not need to be simulated. + * + * Moreover, we won't be doing this, because it counts as a spurious wakeup + * -- someone else with a genuine claim must get wakened, in any case. + * + * Therefore we choose to wake only one of the correct waiting threads. + * So at the very least, we need to do something clever. But there's + * bigger problems. + * We don't even have a straightforward way in win32 to satisfy + * pthread_cond_wait's atomicity requirement. The bulk of this + * algorithm is solving that. + * + * Note: We might could simplify this using vista+ condition variables, + * but we wanted an XP compatible solution. */ cond->event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!cond->event) goto error; cond->hot_potato = CreateEvent(NULL, FALSE, FALSE, NULL); @@ -423,14 +442,17 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds struct QueueEntry myentry; struct QueueEntry **ptr; DWORD tsBegin; - DWORD dwFinalTimeout = dwMilliseconds; /* Careful! in case we begin in the head, we don't do the hot potato stuff, so this timeout needs presetting */ DWORD waitResult; + DWORD dwFinalTimeout = dwMilliseconds; /* Careful! in case we begin in the head, + we don't do the hot potato stuff, + so this timeout needs presetting. */ /* Reminder: `lock` is held before this is called. */ /* however, someone else may have called scond_signal without the lock. soo... */ EnterCriticalSection(&cond->cs); - /* since this library is meant for realtime game software I have no problem setting this to 1 and forgetting about it. */ + /* since this library is meant for realtime game software + * I have no problem setting this to 1 and forgetting about it. */ if (!beginPeriod) { beginPeriod = true; @@ -510,9 +532,14 @@ static bool _scond_wait_win32(scond_t *cond, slock_t *lock, DWORD dwMilliseconds { /* Out of time! Now, let's think about this. I do have the potato now-- * maybe it's my turn, and I have the event? - * If that's the case, I could proceed right now without aborting due to timeout. - * However.. I DID wait a real long time. The caller was willing to wait that long. - * I choose to give him one last chance with a zero timeout in the next step + * If that's the case, I could proceed right now without aborting + * due to timeout. + * + * However.. I DID wait a real long time. The caller was willing + * to wait that long. + * + * I choose to give him one last chance with a zero timeout + * in the next step */ if (cond->head == &myentry) { From c1e08c1138f0d4f09bcb642c2c7a01bef413907a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 06:59:23 +0100 Subject: [PATCH 16/90] Don't make AUDIO_DEVICE an 'advanced' option --- menu/menu_setting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 428c725bf7..ed2d7ccefb 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3848,7 +3848,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT | SD_FLAG_ADVANCED); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); (*list)[list_info->index - 1].action_left = &setting_string_action_left_audio_device; (*list)[list_info->index - 1].action_right = &setting_string_action_right_audio_device; #endif From e6102fed3534e2b8b20cecb0ff3030c25a752b5d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 11:05:05 +0100 Subject: [PATCH 17/90] Revert "Don't make AUDIO_DEVICE an 'advanced' option" This reverts commit c1e08c1138f0d4f09bcb642c2c7a01bef413907a. --- menu/menu_setting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ed2d7ccefb..428c725bf7 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -3848,7 +3848,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT | SD_FLAG_ADVANCED); (*list)[list_info->index - 1].action_left = &setting_string_action_left_audio_device; (*list)[list_info->index - 1].action_right = &setting_string_action_right_audio_device; #endif From 4e0ed3d3d6dd751830ca07a4cea5870cbfc0a074 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 11:05:55 +0100 Subject: [PATCH 18/90] Revert "Merge lakka patch for DRM" This reverts commit 207ebe5e59637b88c148dc26d22da373098a6ea1. --- gfx/drivers_context/drm_ctx.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index ae61ccb819..01e835068a 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -289,10 +289,7 @@ static void free_drm_resources(gfx_ctx_drm_data_t *drm) if (drm->drm) if (g_drm_fd >= 0) - { - drmDropMaster(g_drm_fd); filestream_close(drm->drm); - } g_gbm_surface = NULL; g_gbm_dev = NULL; @@ -384,8 +381,6 @@ nextgpu: drm->fb_width = g_drm_connector->modes[0].hdisplay; drm->fb_height = g_drm_connector->modes[0].vdisplay; - drmSetMaster(g_drm_fd); - g_gbm_dev = gbm_create_device(fd); if (!g_gbm_dev) From 0383d20465581d85bad32cc1ab0bebdcb66b9a77 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 5 Feb 2017 11:06:51 +0100 Subject: [PATCH 19/90] Revert "Revert "Merge lakka patch for DRM"" This reverts commit 4e0ed3d3d6dd751830ca07a4cea5870cbfc0a074. --- gfx/drivers_context/drm_ctx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index 01e835068a..ae61ccb819 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -289,7 +289,10 @@ static void free_drm_resources(gfx_ctx_drm_data_t *drm) if (drm->drm) if (g_drm_fd >= 0) + { + drmDropMaster(g_drm_fd); filestream_close(drm->drm); + } g_gbm_surface = NULL; g_gbm_dev = NULL; @@ -381,6 +384,8 @@ nextgpu: drm->fb_width = g_drm_connector->modes[0].hdisplay; drm->fb_height = g_drm_connector->modes[0].vdisplay; + drmSetMaster(g_drm_fd); + g_gbm_dev = gbm_create_device(fd); if (!g_gbm_dev) From fa341f03a0b08ee72491c725cea6effe62c11829 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Sun, 5 Feb 2017 14:13:30 +0100 Subject: [PATCH 20/90] Thing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 15cb1d3254..c1b418d90d 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ ifneq ($(findstring DOS,$(OS)),) endif ifneq ($(findstring Win32,$(OS)),) - LDFLAGS += -static-libgcc + LDFLAGS += -static-libgcc -lwinmm endif include Makefile.common From a56a825dfb1afe4b4288a28dc8ecd2a9f839521d Mon Sep 17 00:00:00 2001 From: rootfather Date: Sun, 5 Feb 2017 16:12:06 +0100 Subject: [PATCH 21/90] Rewrite German translation (part 1) --- intl/msg_hash_de.c | 1955 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 1686 insertions(+), 269 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 81e039f3ee..97eab0ce87 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -14,40 +14,689 @@ */ #include -#include +#include #include #include #include "../msg_hash.h" #include "../configuration.h" +#include "../verbosity.h" -#ifdef __clang__ -#pragma clang diagnostic ignored "-Winvalid-source-encoding" -#endif +// Is this still needed in current RetroArch versions or is +// this an old left-over? +// #ifdef __clang__ +// #pragma clang diagnostic ignored "-Winvalid-source-encoding" +// #endif int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) { uint32_t driver_hash = 0; settings_t *settings = config_get_ptr(); + if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && + msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) + { + unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; + + switch (idx) + { + case RARCH_FAST_FORWARD_KEY: + snprintf(s, len, + "Schaltet zwischen schnellem Vorlauf und \n" + "normaler Spielgeschwindigkeit um." + ); + break; + case RARCH_FAST_FORWARD_HOLD_KEY: + snprintf(s, len, + "Halte den Taste gedrückt, um vorzuspulen.\n" + " \n" + "Beim Loslassen wird der schnelle Vorlauf beendet." + ); + break; + case RARCH_PAUSE_TOGGLE: + snprintf(s, len, + "Inhalt pausieren und wieder fortsetzen."); + break; + case RARCH_FRAMEADVANCE: + snprintf(s, len, + "Einzelbildwiedergabe, wenn der Inhalt pausiert ist."); + break; + case RARCH_SHADER_NEXT: + snprintf(s, len, + "Wendet nächsten Shader im Verzeichnis an."); + break; + case RARCH_SHADER_PREV: + snprintf(s, len, + "Wendet vorherigen Shader im Verzeichnis an."); + break; + case RARCH_CHEAT_INDEX_PLUS: + case RARCH_CHEAT_INDEX_MINUS: + case RARCH_CHEAT_TOGGLE: + snprintf(s, len, + "Cheats."); + break; + case RARCH_RESET: + snprintf(s, len, + "Setzt den Inhalt zurück."); + break; + case RARCH_SCREENSHOT: + snprintf(s, len, + "Bildschirmfoto anfertigen."); + break; + case RARCH_MUTE: + snprintf(s, len, + "Tonwiedergabe stummschalten bzw. Stummschaltung aufheben."); + break; + case RARCH_OSK: + snprintf(s, len, + "Bildschirmtastatur ein-/ausschalten."); + break; + case RARCH_NETPLAY_FLIP: + snprintf(s, len, + "Netplay-Spieler tauschen."); + break; + case RARCH_SLOWMOTION: + snprintf(s, len, + "Halte den Taste gedrückt, um die Zeitlupe einzuschalten."); + break; + case RARCH_ENABLE_HOTKEY: + snprintf(s, len, + "Andere Hotkeys aktivieren. \n" + " \n" + "Wenn dieser Hotkey entweder einer\n" + "Tastatur, einer Joypad-Taste oder \n" + "Joypad-Achse zugeordnet ist, werden alle \n" + "anderen Hotkeys nur aktiviert, wenn dieser \n" + "Hotkey zur gleichen Zeit gehalten wird. \n" + " \n" + "Dies ist hilfreich für Implementierungen, die auf \n" + "RETRO_KEYBOARD ausgelegt sind und eine große \n" + "Fläche auf der Tastatur benötigen, wo es nicht \n" + "gewünscht ist, dass es zu Kollisionen mit Hotkeys kommt. \n" + " \n" + "Alternativ können auch alle Tastatur-Hotkeys durch \n" + "den Benutzer deaktiviert werden."); + break; + case RARCH_VOLUME_UP: + snprintf(s, len, + "Erhöht die Lautstärke."); + break; + case RARCH_VOLUME_DOWN: + snprintf(s, len, + "Verringert die Lautstärke."); + break; + case RARCH_OVERLAY_NEXT: + snprintf(s, len, + "Wechselt zum nächsten Overlay."); + break; + case RARCH_DISK_EJECT_TOGGLE: + snprintf(s, len, + "Datenträger einbinden/auswerfen. \n" + " \n" + "Verwendet für Inhalt, der auf mehreren Datenträgern ausgeliefert wird. "); + break; + case RARCH_DISK_NEXT: + case RARCH_DISK_PREV: + snprintf(s, len, + "Wechselt durch Datenträger-Abbilder. Nach dem Auswerfen verwenden. \n" + " \n" + "Zum Abschließen, Datenträger erneut einbinden."); + break; + case RARCH_GRAB_MOUSE_TOGGLE: + snprintf(s, len, + "Maus einfangen/freilassen. \n" + " \n" + "Wenn die Maus eingefangen ist, versteckt RetroArch \n" + "die Maus und hält den Mauszeiger im RetroArch-Fenster, \n" + "um die Eingabe der Maus zu verbessern."); + break; + case RARCH_GAME_FOCUS_TOGGLE: + snprintf(s, len, + "Spiel-Fokus umschalten.\n" + " \n" + "Wenn ein Spiel fokussiert ist, wird RetroArch die Hotkeys\n" + "deaktivieren und den Mauszeiger im RetroArch-Fenster halten."); + break; + case RARCH_MENU_TOGGLE: + snprintf(s, len, "Menü aufrufen."); + break; + case RARCH_LOAD_STATE_KEY: + snprintf(s, len, + "Spielstand laden."); + break; + case RARCH_FULLSCREEN_TOGGLE_KEY: + snprintf(s, len, + "Vollbildmodus umschalten"); + break; + case RARCH_QUIT_KEY: + snprintf(s, len, + "Taste zum Beenden von RetroArch. \n" + " \n" + "Wenn Du RetroArch unsanft beendest (SIGKILL, etc.) wird \n" + "RetroArch beendet, ohne Arbeitsspeicher oder ähnliches zu speichern." +#ifdef __unix__ + "\nAuf unixoiden Systemen erlaubt SIGINT/SIGTERM ein sauberes \n" + "Beenden von RetroArch." +#endif + ""); + break; + case RARCH_STATE_SLOT_PLUS: + case RARCH_STATE_SLOT_MINUS: + snprintf(s, len, + "Speicherplätze. \n" + " \n" + "Wenn der Speicherplatz auf 0 gesetzt wird, ist der Name des Spielstands \n" + "*.state (oder was entsprechend auf der Kommandozeile definiert wurde). \n" + " \n" + "Wenn der Speicherplatz nicht auf 0 gesetzt wird, wird das Verzeichnis \n" + "gewählt, wobei die Nummer des Speicherplatzes ist."); + break; + case RARCH_SAVE_STATE_KEY: + snprintf(s, len, + "Spielstand abspeichern."); + break; + case RARCH_REWIND: + snprintf(s, len, + "Haltee die Taste zum Zurückspulen gedrückt. \n" + " \n" + "Die Zurückspulfunktion muss eingeschaltet sein."); + break; + case RARCH_MOVIE_RECORD_TOGGLE: + snprintf(s, len, + "Aufnahme starten/beenden"); + break; + default: + if (string_is_empty(s)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); + break; + } + + return 0; + } + switch (msg) { + case MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS: + snprintf(s, len, "Anmelde-Daten für Ihr \n" + "Retro Achievements-Konto. \n" + " \n" + "Besuche retroachievements.org und eröffne \n" + "ein kostenloses Konto. \n" + " \n" + "Nach der Registrierung musst Du deinen \n" + "Benutzernamen und dein Passwort in RetroArch \n" + "angeben."); + break; + case MENU_ENUM_LABEL_CHEEVOS_USERNAME: + snprintf(s, len, "Benutzernahme für dein Retro Achievements-Konto."); + break; + case MENU_ENUM_LABEL_CHEEVOS_PASSWORD: + snprintf(s, len, "Passwort für dein Retro Achievements-Konto."); + break; + case MENU_ENUM_LABEL_USER_LANGUAGE: + snprintf(s, len, "Übersetzt das Menü und alle Bildschirm-Meldungen \n" + "in die Sprache, die Du hier ausgewählt hast. \n" + " \n" + "Ein Neustart wird benötigt, um die geänderten \n" + "Einstellungen zu aktivieren. \n" + " \n" + "Hinweis: möglicherweise sind nicht alle Sprachen \n" + "implementiert. \n" + " \n" + "Wenn die gewählte Sprache nicht implementiert ist, \n" + "wird Englisch als Sprache ausgewählt."); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_PATH: + snprintf(s, len, "Wählt die Schriftart, \n" + "die für Bildschirm-Meldungen verwendet wird."); + break; + case MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS: + snprintf(s, len, "Inhaltsspezifische Core-Einstellungen automatisch laden."); + break; + case MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE: + snprintf(s, len, "Überschreibende Konfigurationen automatisch laden."); + break; + case MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE: + snprintf(s, len, "Eingabebelegungsdateien automatisch laden."); + break; + case MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE: + snprintf(s, len, "Speichert Savestate-Dateien in Ordnern, \n" + "die nach dem verwendeten libretro-Core benannt sind."); + break; + case MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE: + snprintf(s, len, "Speichert Speicherdaten in Ordnern, \n" + "die nach dem verwendeten libretro-Core benannt sind."); + break; + case MENU_ENUM_LABEL_RESUME_CONTENT: + snprintf(s, len, "Verlässt das Menü und kehrt \n" + "zum Inhalt zurück."); + break; + case MENU_ENUM_LABEL_RESTART_CONTENT: + snprintf(s, len, "Startet den Inhalt vom Beginn an neu."); + break; + case MENU_ENUM_LABEL_CLOSE_CONTENT: + snprintf(s, len, "Schließt den Inhalt und entlädt ihn aus dem \n" + "Speicher."); + break; + case MENU_ENUM_LABEL_UNDO_LOAD_STATE: + snprintf(s, len, "Wenn ein Savestate geladen war, wird der Inhalt \n" + "zum Status vor dem Laden des Savestates zurückkehren."); + break; + case MENU_ENUM_LABEL_UNDO_SAVE_STATE: + snprintf(s, len, "Wenn ein Savestate überschrieben wurde, wird \n" + "der Inhalt zum vorherigen Savestates zurückkehren."); + break; + case MENU_ENUM_LABEL_TAKE_SCREENSHOT: + snprintf(s, len, "Fertigt ein Bildschirmfoto an. \n" + " \n" + "Das Bildschirmfoto wird im Bildschirmfoto-Verzeichnis \n" + "gespeichert."); + break; + case MENU_ENUM_LABEL_RUN: + snprintf(s, len, "Startet den Inhalt."); + break; + case MENU_ENUM_LABEL_INFORMATION: + snprintf(s, len, "Zeige zusätzliche Metadaten \n" + "über den Inhalt an."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CONFIG: + snprintf(s, len, "Konfigurations-Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE: + snprintf(s, len, "Komprimierte Archivdatei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_RECORD_CONFIG: + snprintf(s, len, "Aufzeichnungs-Konfigurationsdatei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CURSOR: + snprintf(s, len, "Datenbank-Zeiger-Datei."); + break; + case MENU_ENUM_LABEL_FILE_CONFIG: + snprintf(s, len, "Konfigurationsdatei."); + break; + case MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY: + snprintf(s, len, + "Auswählen, um das gewählte Verzeichnis nach Inhalten \n" + "zu durchsuchen."); + break; + case MENU_ENUM_LABEL_USE_THIS_DIRECTORY: + snprintf(s, len, + "Auswählen, um dies als Verzeichnis festzulegen."); + break; + case MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY: + snprintf(s, len, + "Verzeichnis für Inhalte-Datenbank. \n" + " \n" + "Pfad zum Verzeichnis für die \n" + "Inhalte-Datenbank."); + break; + case MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY: + snprintf(s, len, + "Vorschaubild-Verzeichnis. \n" + " \n" + "Zum Speichern von Vorschaubildern."); + break; + case MENU_ENUM_LABEL_LIBRETRO_INFO_PATH: + snprintf(s, len, + "Core-Info-Verzeichnis. \n" + " \n" + "Ein Verzeichnis, in dem nach \n" + "libretro-Core-Informationen gesucht wird."); + break; + case MENU_ENUM_LABEL_PLAYLIST_DIRECTORY: + snprintf(s, len, + "Wiedergabelisten-Verzeichnis. \n" + " \n" + "Speichere alle Wiedergabelisten in diesem \n" + "Verzeichnis."); + break; + case MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN: + snprintf(s, len, + "Einige Cores haben eine \n" + "Abschalt-Funktion. \n" + " \n" + "Wenn diese Option deaktiviert bleibt, \n" + "wird RetroArch beendet, wenn die Abschalt-Funktion \n" + "ausgewählt wird. \n" + " \n" + "Wenn diese Option aktiviert ist, wird stattdessen \n" + "ein 'leerer' Core geladen, sodass wir im Menü bleiben \n" + "und RetroArch nicht beendet wird."); + break; + case MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE: + snprintf(s, len, + "Einige Cores benötigen spezielle \n" + "Firmware- oder BIOS-Dateien. \n" + " \n" + "Wenn diese Option deaktiviert ist, \n" + "wird versucht, den Core auch zu laden, \n" + "wenn die Firmware fehlt. \n"); + break; + case MENU_ENUM_LABEL_PARENT_DIRECTORY: + snprintf(s, len, + "Kehre zum übergeordneten Verzeichnis zurück."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_SHADER_PRESET: + snprintf(s, len, + "Datei mit Shader-Voreinstellungen."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_SHADER: + snprintf(s, len, + "Shader-Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_REMAP: + snprintf(s, len, + "Eingabebelegungsdatei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CHEAT: + snprintf(s, len, + "Cheat-Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY: + snprintf(s, len, + "Overlay-Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_RDB: + snprintf(s, len, + "Datenbankdatei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_FONT: + snprintf(s, len, + "TrueType-Schriftartendatei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE: + snprintf(s, len, + "Einfache Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN: + snprintf(s, len, + "Video. \n" + " \n" + "Auswählen, um diese Datei mit dem \n" + "Video-Player abzuspielen."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN: + snprintf(s, len, + "Musik. \n" + " \n" + "Auswählen, um diese Datei mit dem \n" + "Musik-Player abzuspielen."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE: + snprintf(s, len, + "Bild-Datei."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER: + snprintf(s, len, + "Bild. \n" + " \n" + "Auswählen, um diese Datei mit dem \n" + "Bildbetrachter zu öffnen."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION: + snprintf(s, len, + "Libretro-Core. \n" + " \n" + "Auswählen, um diesen Core dem Spiel zuzuordnen."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CORE: + snprintf(s, len, + "Libretro-Core. \n" + " \n" + "Auswählen, um diesen Core in RetroArch zu laden."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY: + snprintf(s, len, + "Verzeichnis. \n" + " \n" + "Auswählen, um dieses Verzeichnis zu öffnen."); + break; + case MENU_ENUM_LABEL_CACHE_DIRECTORY: + snprintf(s, len, + "Zwischenspeicher-Verzeichnis. \n" + " \n" + "Von RetroArch entpackter Inhalt wird \n" + "temporär in diesem Verzeichnis gespeichert."); + break; + case MENU_ENUM_LABEL_HISTORY_LIST_ENABLE: + snprintf(s, len, + "Wenn aktiviert, wird jeder Inhalt, der in RetroArch \n" + "geöffnet wird, automatisch in \n" + "die Verlaufsliste aufgenommen."); + break; + case MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY: + snprintf(s, len, + "Dateibrowser-Verzeichnis. \n" + " \n" + "Legt das Verzeichnis fest, in dem der Dateibrowser startet."); + break; + case MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR: + snprintf(s, len, + "Beeinflusst, wie die Eingabe-Abfrage in \n" + "RetroArch gehandhabt wird. \n" + " \n" + "Früh - Eingabe wird abgefragt, bevor \n" + "das aktuelle Frame verarbeitet wird. \n" + "Normal - Eingabe wird abgefragt, wenn \n" + "eine Abfrage angefordert wird. \n" + "Late - Eingabe wird abgefragt, wenn \n" + "die erste Eingabe-Abfrage im Frame angefordert wird.\n" + " \n" + "Diese Option auf 'Früh' oder 'Spät' zu setzen kann \n" + "eine verringerte Latenz bewirken, \n" + "abhängig von deiner Konfiguration.\n\n" + "Wenn Netplay aktiviert ist, wird das Standard-Abfrageverhalten \n" + "(Normal) verwendet. Dieser Wert wird dann nicht berücksichtigt." + ); + break; + case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_HIDE_UNBOUND: + snprintf(s, len, + "Verstecke Eingabe-Beschreibungen, die nicht vom \n" + "Core festgelegt werden."); + break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE: + snprintf(s, len, + "Bildwiederholrate deines Bildschirms. \n" + "Wird verwendet, um eine geeignete Audio-Eingaberate zu finden."); + break; + case MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE: + snprintf(s, len, + "Unterstützung für sRGB FBO zwangsweise deaktivieren. Einige Intel \n" + "OpenGL-Treiber unter Windows haben Bildprobleme bei aktivierter \n" + "sRGB FBO-Unterstützung."); + break; + case MENU_ENUM_LABEL_AUDIO_ENABLE: + snprintf(s, len, + "Tonausgabe aktivieren."); + break; + case MENU_ENUM_LABEL_AUDIO_SYNC: + snprintf(s, len, + "Ton synchronisieren (empfohlen)."); + break; + case MENU_ENUM_LABEL_AUDIO_LATENCY: + snprintf(s, len, + "Gewünschte Ton-Latenz in Millisekunden. \n" + "Wird evtl. nicht berücksichtigt, wenn der Audiotreiber \n" + "die Latenz nicht zurückmelden kann."); + break; + case MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE: + snprintf(s, len, + "Erlaube Core, die Drehung festzulegen. Wenn deaktiviert, \n" + "werden Dreh-Anfragen angenommen, aber ignoriert. \n\n" + "Wird in Setups verwendet, in denen der Benutzer den \n" + "Monitor manuell dreht."); + break; + case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_LABEL_SHOW: + snprintf(s, len, + "Zeige vom Core festgelegte Eingabe-Beschreibungen anstelle \n" + "der standardmäßigen an."); + break; + case MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE: + snprintf(s, len, + "Anzahl der Elemente, die in der \n" + "Verlaufsliste gespeichert werden."); + break; + case MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN: + snprintf(s, len, + "Legt fest, ob der Fenstermodus verwendet wird oder nicht, \n" + "wenn das Bild in Vollbild angezeigt werden soll."); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_SIZE: + snprintf(s, len, + "Schriftgröße für Bildschirm-Meldungen."); + break; + case MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX: + snprintf(s, len, + "Erhöht den Speicherplatz-Index bei jedem Speichervorgang, \n" + "sodass mehrere Savestate-Dateien erzeugt werden. \n" + "Wenn der Inhalt geladen ist, wird der Speicherplatz-Index \n" + "auf den höchsten existierenden Wert gesetzt (neuester Savestate)."); + break; + case MENU_ENUM_LABEL_FPS_SHOW: + snprintf(s, len, + "Aktiviert die Anzeige der aktuellen Bilder \n" + "pro Sekunde."); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_ENABLE: + snprintf(s, len, + "Zeige und/oder verstecke Bildschirm-Meldungen."); + break; + case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X: + case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y: + snprintf(s, len, + "Legt den Versatz für die Anzeige von Bildschirm-Meldungen \n" + "fest. Gültige Werte liegen im Bereich [0.0 bis 1.0]."); + break; + case MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE: + snprintf(s, len, + "Aktiviert oder deaktiviert das aktuelle Overlay."); + break; + case MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU: + snprintf(s, len, + "Verhindert, dass das aktuelle Overlay im \n" + "Menü angezeigt wird."); + break; + case MENU_ENUM_LABEL_OVERLAY_PRESET: + snprintf(s, len, + "Pfad zum Eingabe-Overlay."); + break; + case MENU_ENUM_LABEL_OVERLAY_OPACITY: + snprintf(s, len, + "Overlay-Deckkraft"); + break; + case MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT: + snprintf(s, len, + "Zeitlimit für Eingabe-Belegungen (in Sekunden). \n" + "Anzahl der Sekunden, die gewartet werden soll, \n" + "bis zur nächsten Belegung gewechselt wird."); + break; + case MENU_ENUM_LABEL_OVERLAY_SCALE: + snprintf(s, len, + "Overlay-Skalierung."); + break; + case MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE: + snprintf(s, len, + "Audio-Abtastrate."); + break; + case MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT: + snprintf(s, len, + "Aktivieren, wenn Hardware-beschleunigte Cores \n" + "ihren eigenen privaten Kontext bekommen sollen. \n" + "Dies verhindert, dass Änderungen des Geräte-Status \n" + "zwischen den Einzelbildern geschätzt werden müssen." + ); + break; case MENU_ENUM_LABEL_CORE_LIST: snprintf(s, len, "Lade Core. \n" " \n" - "Suche nach einer Libretro-Core- \n" - "Implementierung. In welchem Verzeichnis der \n" - "Browser startet, hängt vom deinem Core-Verzeichnis \n" - "ab. Falls du es nicht eingestellt hast, wird er \n" - "im Root-Verzeichnis starten. \n" + "Suche nach einer libretro-Core-Implementierung. \n" + "In welchem Verzeichnis der Browser beginnt, \n" + "hängt von deinem Core-Verzeichnispfad \n" + "ab. Ist dieser nicht eingestellt, wird im Wurzelverzeichnis begonnen. \n" " \n" - "Ist das Core-Verzeichnis ein Ordner, wird das \n" - "Menü diesen als Startverzeichnis nutzen. Ist \n" - "das Core-Verzeichnis ein Pfad zu einer Datei, \n" - "wird es in dem Verzeichnis starten, in dem \n" - "sich die Datei befindet."); + "Ist als Core-Verzeichnis ein Ordner ausgewählt, wird \n" + "das Menü diesen als Startverzeichnis nutzen. \n" + "Ist das Core-Verzeichnis ein vollständiger Pfad, wird \n" + "es in dem Ordner beginnen, in welchem sich die Datei befindet."); + break; + case MENU_ENUM_LABEL_VALUE_MENU_ENUM_CONTROLS_PROLOG: + snprintf(s, len, + "Du kannst folgende Steuerelemente mit\n" + "deinem Controller oder deiner Tastatur verwenden\n" + "um durch das Menü zu navigieren: \n" + " \n" + ); + break; + case MENU_ENUM_LABEL_WELCOME_TO_RETROARCH: + snprintf(s, len, + "Willkommen bei RetroArch\n" + ); + break; + case MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING_DESC: + { + /* Work around C89 limitations */ + char u[501]; + const char * t = + "RetroArch verwendet eine einzigartige Form der\n" + "Audio/Video-Synchronisierung. Diese muss\n" + "an die Bildwiederholrate deines Bildschirms angepasst werden,\n" + "um die bestmögliche Leistung zu erhalten.\n" + " \n" + "Treten Probleme wie eine knackende Ton-Wiedergabe oder\n" + "eine unregelmäßige Bildwiedergabe auf, bedeutet dies in der Regel,\n" + "dass Du die Einstellungen kalibrieren musst. Du hast folgende Möglichkeiten:\n" + " \n"; + snprintf(u, sizeof(u), /* can't inline this due to the printf arguments */ + "a) Gehe zu '%s' -> '%s', und aktiviere\n" + "'Threaded Video'. Die Bildwiederholrate wird in diesem\n" + "Modus nicht berücksichtigt. Die Bildwiederholrate wird höher,\n" + "aber die Video-Darstellung wird eventuell weniger flüssig.\n" + "b) Gehe zu '%s' -> '%s', und schaue nach\n" + "'%s'. Lass' es für \n" + "2048 Frames laufen, dann drücke auf 'OK'.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO)); + strlcpy(s, t, len); + strlcat(s, u, len); + } + break; + case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: + snprintf(s, len, + "Um nach Inhalten zu suchen, gehee zu '%s' und\n" + "wähle '%s' oder %s'.\n" + " \n" + "Die Dateien werden werden mit einer Datenbank abgeglichen.\n" + "Bei einem Treffer wird die Datei zu einer Sammlung\n" + "hinzugefügt.\n" + " \n" + "Du kannst diese Inhalte einfach aufrufen, indem Du\n" + "zu'%s' ->\n" + "'%s'\n gehst," + "anstatt jedes Mal den Dateibrowser\n" + "verwenden zu müssen.\n" + " \n" + "HINWEIS: Inhalte für einige Cores können möglicherweise\n" + "noch nicht durchsucht werden." + , + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + ); + break; + case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: + snprintf(s, len, + "Willkommen bei RetroArch \n" + "\n" + "Extrahiere Assets, bitte warten.\n" + "Dies kann eine Weile dauern...\n" + ); break; case MENU_ENUM_LABEL_INPUT_DRIVER: if (settings) @@ -56,31 +705,26 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) switch (driver_hash) { case MENU_LABEL_INPUT_DRIVER_UDEV: - { - /* Work around C89 limitations */ - const char * t = - "udev-Eingabetreiber. \n" - " \n" - "Dieser Treiber kann ohne X ausgeführt werden. \n" - " \n" - "Er verwende die neue evdev-Joypad-API \n" - "für die Joystick-Unterstützung und unterstützt \n" - "auch Hotplugging und Force-Feedback (wenn das \n" - "Gerät dies unterstützt). \n" - " \n"; - const char * u = - "Der Treiber liest evdev-Ereignisse für die Tastatur- \n" - "Unterstützung und kann auch mit Tastatur-Callbacks, \n" - "Mäusen und Touchpads umgehen. \n" - " \n" - "Standardmäßig sind die /dev/input-Dateien in den \n" - "meisten Linux-Distribution nur vom Root- \n" - "Benutzer lesbar (mode 600). Du kannst eine udev- \n" - "Regel erstellen, die auch den Zugriff für andere \n" - "Benutzer erlaubt."; - strlcpy(s, t, len); - strlcat(s, u, len); - } + snprintf(s, len, + "udev-Eingabetreiber. \n" + " \n" + "Dieser Treiber kann ohne X ausgeführt werden. \n" + " \n" + "Er verwende die neue evdev-Joypad-API \n" + "für die Joystick-Unterstützung und unterstützt \n" + "auch Hotplugging und Force-Feedback (wenn das \n" + "Gerät dies unterstützt). \n" + " \n" + "Der Treiber liest evdev-Ereignisse für die Tastatur- \n" + "Unterstützung und kann auch mit Tastatur-Callbacks, \n" + "Mäusen und Touchpads umgehen. \n" + " \n" + "Standardmäßig sind die /dev/input-Dateien in den \n" + "meisten Linux-Distribution nur vom Root- \n" + "Benutzer lesbar (mode 600). Sie können eine udev- \n" + "Regel erstellen, die auch den Zugriff für andere \n" + "Benutzer erlaubt." + ); break; case MENU_LABEL_INPUT_DRIVER_LINUXRAW: snprintf(s, len, @@ -89,7 +733,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Dieser Treiber erfordert eine aktive TTY-Schnittstelle. \n" "Tastatur-Ereignisse werden direkt von der TTY gelesen, \n" "was es einfacher, aber weniger flexibel als udev macht. \n" - "Mäuse, etc, werden nicht unterstützt. \n" + "Mäuse und ähnliche Geräte werden nicht unterstützt. \n" " \n" "Dieser Treiber verwendet die alte Joystick-API \n" "(/dev/input/js*)."); @@ -103,11 +747,29 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; } break; + case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: + snprintf(s, len, + "Lade Inhalt. \n" + "Suche nach Inhalten. \n" + " \n" + "Um Inhalte zu laden benötigst Du den passenden \n" + "Libretro-Core und die Inhalts-Datei. \n" + " \n" + "Um einzustellen, welcher Ordner standardmäßig \n" + "geöffnet wird, um nach Inhalten zu suchen, solltest \n" + "Du das Inhalts-Verzeichnis setzen. Wenn es nicht \n" + "gesetzt ist, wird es im Hauptverzeichen starten. \n" + " \n" + "Der Browser wird nur Dateierweiterungen des \n" + "zuletzt geladenen Cores zeigen und diesen Core \n" + "nutzen, wenn Inhalt geladen wird." + ); + break; case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY: snprintf(s, len, - "Lade Content aus dem Verlauf. \n" + "Lade Inhalt aus dem Verlauf. \n" " \n" - "Wenn Content geladen wird, wird der Content \n" + "Wenn Inhalt geladen wird, wird der Inhalt \n" "sowie der dazugehörige Core im Verlauf gespeichert. \n" " \n" "Der Verlauf wird im selben Verzeichnis wie die \n" @@ -117,31 +779,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "im Hauptmenü angezeigt." ); break; - case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: - snprintf(s, len, - "Lade Inhalt. \n" - "Suche nach Inhalt. \n" - " \n" - "Um Inhalte zu laden brauchst du\n" - "einen 'Core'. \n" - " \n" - "Um einzustellen wo das Verzeichnis beginnt, \n" - "setze das \n" - "'%s'. \n" - "Falls diese nicht gesetzt ist, startet \n" - "die Suche beim obersten Verzeichnis.\n" - " \n" - "Beim Durchsuchen werden Inhalte gefiltert. \n" - "Nur Inhalte mit der Dateiendung, welche \n" - "mit den ausgewählten Core funktionieren \n" - "werden angezeigt. \n" - "Dieser Core wird dann auch für den Inhalt verwendet.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY) - ); - break; case MENU_ENUM_LABEL_VIDEO_DRIVER: snprintf(s, len, - "Momentaner Grafiktreiber."); + "Aktueller Grafiktreiber"); if (string_is_equal(settings->video.driver, "gl")) { @@ -175,13 +815,13 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Dies ist ein SDL1.2-Grafiktreiber \n" "mit Software-Rendering." " \n" - "Die Leistung ist suboptimal und du \n" - "solltest ihn nur als letzte \n" + "Die Leistung ist suboptimal und Du \n" + "solltest diesen Treiber nur als letzte \n" "Möglichkeit verwenden."); } else if (string_is_equal(settings->video.driver, "d3d")) { - snprintf(s, len, + snprintf(s, len, "Direct3D-Grafiktreiber. \n" " \n" "Die Leistung bei software-gerenderten \n" @@ -194,12 +834,21 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Exynos-G2D-Grafiktreiber. \n" " \n" "Dies ist ein Low-Level-Exynos-Grafiktreiber. \n" - "Er verwendet den G2D-Block in Samsung-Exynos-SoCs. \n" + "Er verwendet den G2D-Block in Samsung-Exynos-SoCs \n" "für Blitting-Operationen. \n" " \n" "Die Leistung bei software-gerendeten Cores sollte \n" "optimal sein."); } + else if (string_is_equal(settings->video.driver, "drm")) + { + snprintf(s, len, + "DRM-Grafiktreiber \n" + " \n" + "Dies ist ein Low-Level DRM-Grafiktreiber.\n" + "Er verwendet libdrm für Hardware-Skalierung und \n" + "GPU-Overlays."); + } else if (string_is_equal(settings->video.driver, "sunxi")) { snprintf(s, len, @@ -230,36 +879,23 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Convoluted-Kosinus-Implementierung."); break; + default: + if (string_is_empty(s)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); + break; } break; case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET: snprintf(s, len, "Lade Shader-Voreinstellung. \n" " \n" - " Lade eine " -#ifdef HAVE_CG - "Cg" -#endif -#ifdef HAVE_GLSL -#ifdef HAVE_CG - "/" -#endif - "GLSL" -#endif -#ifdef HAVE_HLSL -#if defined(HAVE_CG) || defined(HAVE_HLSL) - "/" -#endif - "HLSL" -#endif - "-Voreinstellung. \n" - "Das Menüshader-Menü wird entsprechend \n" - "aktualisiert." + " Lade eine Shader-Voreinstellung direkt. \n" + "Das Shader-Menü wird entsprechend angepasst. \n" " \n" - "Wenn der CGP komplexe Methoden verwendet, \n" - "(also andere als Quellskalierung mit dem \n" - "selben Faktor für X/Y) kann der im Menü \n" - "angezeigte Skalierungsfaktor inkorrekt sein." + "Wenn der CGP Skalierungsmethoden verwendet, die nicht \n" + "einfach sind, (z.B. Quellen-Skalierung, gleicher \n" + "Skalierungsfaktor für X/Y), ist der angezeigte Skalierungsfaktor \n" + "im Menü möglicherweise nicht korrekt." ); break; case MENU_ENUM_LABEL_VIDEO_SHADER_SCALE_PASS: @@ -276,8 +912,8 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "mit dem als 'Standardfilter' eingestellten \n" "Filter auf die Bildschirmgröße gestreckt. \n" " \n" - "Wenn 'Mir egal' eingestellt ist, wird \n" - "entweder einfache Skalierung or Vollbild- \n" + "Wenn 'Ignorieren' eingestellt ist, wird \n" + "entweder einfache Skalierung oder Vollbild- \n" "Streckung verwendet - abhängig davon, ob \n" "es der letzte Durchgang ist oder nicht." ); @@ -286,13 +922,13 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Shader-Durchgänge. \n" " \n" - "RetroArch erlaubt es dir, verschiedene Shader \n" + "RetroArch erlaubt es, verschiedene Shader \n" "in verschiedenen Durchgängen miteinander zu \n" "kombinieren. \n" " \n" "Diese Option legt die Anzahl der Shader- \n" - "Durchgänge fest. Wenn du die Anzahl auf 0 setzt, \n" - "verwendest du einen 'leeren' Shader." + "Durchgänge fest. Wenn Du die Anzahl auf 0 setzt, \n" + "verwendest Du einen 'leeren' Shader." " \n" "Die 'Standardfilter'-Option beeinflusst den \n" "Streckungsfilter"); @@ -312,100 +948,933 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "im Menü aktiv ist." ); break; - /* - * FIXME: Some stuff still missing here. - */ + case MENU_ENUM_LABEL_VIDEO_SHADER_PASS: + snprintf(s, len, + "Pfad zum Shader. \n" + " \n" + "Alle Shader mmüssen vom selben Typ sein \n" + "(z.B. CG, GLSL oder HLSL). \n" + " \n" + "Durch das Setzen des Shader-Verzeichnisses \n" + "legst Du fest, in welchem Verzeichnis der Browser \n" + "nach Shadern sucht." + ); + break; + case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: + snprintf(s, len, + "Speichert die Konfiguration beim Beenden. \n" + "Hilfreich für das Menü, da Einstellungen geändert \n" + "werden können. Überschreibt die Konfiguration. \n" + " \n" + "#include-Einträge und Kommentare bleiben nicht erhalten. \n" + " \n" + "Die Konfigurationsdatei sollte als 'unantastbar' \n" + "angesehen werden, da es wahrscheinlich ist, \n" + "dass der Benutzer Änderungen vornimmt \n" + "und diese nicht ohne Wissen des \n" + "Benutzers überschrieben werden sollten." +#if defined(RARCH_CONSOLE) || defined(RARCH_MOBILE) + "\nDies gilt nicht für \n" + "Konsolen, bei denen eine manuelle \n" + "Konfiguration keine sinnvolle Option ist. \n" +#endif + ); + break; + case MENU_ENUM_LABEL_CONFIRM_ON_EXIT: + snprintf(s, len, "Bist Du sicher, dass Du RetroArch verlassen möchtest?"); + break; + case MENU_ENUM_LABEL_SHOW_HIDDEN_FILES: + snprintf(s, len, "Zeige versteckte Dateien \n" + "und Ordner."); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_FILTER_PASS: + snprintf(s, len, + "Hardware-Filter für diesen Durchgang. \n" + " \n" + "Wenn 'Ignorieren' gewählt ist, wird der \n" + "Standard-Filter verwendet." + ); + break; + case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL: + snprintf(s, len, + "Speichert den nichtflüchtigen SRAM-Speicher \n" + "in regelmäßigen Abständen.\n" + " \n" + "Sofern nicht anders festgelegt, ist das automatische \n" + "Speichern standardmäßig deaktiviert. Das Intervall wird \n" + "in Sekunden angegeben. \n" + " \n" + "Ein Wert von 0 deaktiviert das automatische Speichern."); + break; + case MENU_ENUM_LABEL_INPUT_BIND_DEVICE_TYPE: + snprintf(s, len, + "Typ des Eingabe-Gerätes. \n" + " \n" + "Wählt aus, welcher Eingabe-Gerätetyp verwendet wird. \n" + "Dies ist für den libretro-Core selbst relevat." + ); + break; + case MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL: + snprintf(s, len, + "Legt das Log-Level für das \n" + "(GET_LOG_INTERFACE) der Cores fest. \n" + " \n" + " Wenn ein libretro-Core ein Log-Level unterhalb \n" + " des eingestellten Log-Levels ausgibt, wird \n" + " dies ignoriert.\n" + " \n" + " DEBUG-Logs werden immer ignoriert, außer der \n" + " ausführliche Ausgabemodus (--verbose) ist aktiviert.\n" + " \n" + " DEBUG = 0\n" + " INFO = 1\n" + " WARN = 2\n" + " ERROR = 3" + ); + break; + case MENU_ENUM_LABEL_STATE_SLOT_INCREASE: + case MENU_ENUM_LABEL_STATE_SLOT_DECREASE: + snprintf(s, len, + "Speicherplätze. \n" + " \n" + "Wenn der Speicherplatz auf 0 gesetzt wird, ist der Name des Spielstands \n" + "*.state (oder was auf der Kommandozeile definiert wurde). \n" + " \n" + "Wenn der Speicherplatz nicht auf 0 gesetzt wird, wird das Verzeichnis , \n" + "gewählt, wobei die Nummer des Speicherplatzes ist."); + break; + case MENU_ENUM_LABEL_SHADER_APPLY_CHANGES: + snprintf(s, len, + "Shader-Einstellungen übernehmen. \n" + " \n" + "Verwende diese Option, um Änderungen an den \n" + "Shader-Einstellungen zu übernehmen. \n" + " \n" + "Da das Ändern der Shader-Optionen \n" + "einiges an Rechenleistung erfordert, \n" + "musst Du die Option manuell auslösen. \n" + " \n" + "Wenn Du Shader anwendest, werden die Menüeinstellungen \n" + "in einer temporären Datei gespeichert (entweder \n" + "menu.cgp oder menu.glslp) und geladen. Die Datei \n" + "bleibt nach dem Beenden von RetroArch bestehen. Die Datei \n" + "wird im Shader-Verzeichnis gespeichert." + ); + break; + case MENU_ENUM_LABEL_MENU_TOGGLE: + snprintf(s, len, + "Menü aufrufen."); + break; + case MENU_ENUM_LABEL_GRAB_MOUSE_TOGGLE: + snprintf(s, len, + "Maus einfangen/freilassen. \n" + " \n" + "Wenn die Maus eingefangen ist, versteckt RetroArch \n" + "die Maus und hält den Mauszeiger im RetroArch-Fenster, \n" + "um die Eingabe der Maus zu verbessern."); + break; + case MENU_ENUM_LABEL_GAME_FOCUS_TOGGLE: + snprintf(s, len, + "Spiel-Fokus umschalten.\n" + " \n" + "Wenn ein Spiel fokussiert ist, wird RetroArch die Hotkeys\n" + "deaktivieren and und den Mauszeiger im RetroArch-Fenster halten."); + break; + case MENU_ENUM_LABEL_DISK_NEXT: + snprintf(s, len, + "Wechselt durch Datenträger-Abbilder. Nach dem Auswerfen verwenden. \n" + " \n" + "Zum Abschließen, Datenträger erneut einbinden."); + break; + case MENU_ENUM_LABEL_VIDEO_FILTER: +#ifdef HAVE_FILTERS_BUILTIN + snprintf(s, len, + "CPU-basierte Grafikfilter."); +#else + snprintf(s, len, + "CPU-basierte Grafikfilter.\n" + " \n" + "Pfad zu einer dynamischen Bibliothek."); +#endif + break; + case MENU_ENUM_LABEL_AUDIO_DEVICE: + snprintf(s, len, + "Überschreibt das Standard-Audiogerät, welches \n" + "der Audiotreiber verwendet.\n" + "Dies ist treiberabhängig. z.B.\n" +#ifdef HAVE_ALSA + " \n" + "benötigt ALSA ein PCM-Gerät." +#endif +#ifdef HAVE_OSS + " \n" + "benötigt OSS einen Pfad (z.B. /dev/dsp)." +#endif +#ifdef HAVE_JACK + " \n" + "benötigt JACK Portnamen (z.B. system:playback1\n" + ",system:playback_2)." +#endif +#ifdef HAVE_RSOUND + " \n" + "benötigt RSound eine IP-Adresse zu einem RSound-Server \n" + " \n" +#endif + ); + break; + case MENU_ENUM_LABEL_DISK_EJECT_TOGGLE: + snprintf(s, len, + "Datenträger einbinden/auswerfen. \n" + " \n" + "Verwendet für Inhalt, der auf mehreren Datenträgern ausgeliefert wird. "); + break; + case MENU_ENUM_LABEL_ENABLE_HOTKEY: + snprintf(s, len, + "Andere Hotkeys aktivieren. \n" + " \n" + "Wenn dieser Hotkey entweder einer\n" + "Tastatur, einem Joypad-Taste oder \n" + "Joypad-Achse zugeordnet ist, werden alle \n" + "anderen Hotkeys nur aktiviert, wenn dieser \n" + "Hotkey zur gleichen Zeit gehalten wird. \n" + " \n" + "Dies ist hilfreich für Implementierungen, die auf \n" + "RETRO_KEYBOARD ausgelegt sind und eine große \n" + "Fläche auf der Tastatur benötigen, wo es nicht \n" + "gewünscht ist, dass es zu Kollisionen mit Hotkeys kommt \n." + " \n" + "Alternativ können auch alle Tastatur-Hotkeys durch \n" + "den Benutzer deaktiviert werden."); + break; + case MENU_ENUM_LABEL_REWIND_ENABLE: + snprintf(s, len, + "Zurückspulen aktivieren.\n" + " \n" + "Dies wird die Leistung negativ beeinflussen, \n" + "weshalb es standardmäßig deaktiviert ist."); + break; + case MENU_ENUM_LABEL_LIBRETRO_DIR_PATH: + snprintf(s, len, + "Core-Verzeichnis. \n" + " \n" + "Ein Verzeichnis, in welchem nach \n" + "libretro-Core-Implementierungen gesucht wird."); + break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: + snprintf(s, len, + "Bildwiederholrate.\n" + " \n" + "Die genaue Bildwiederholrate Deines Bildschirms (Hz).\n" + "Diese wird verwendet, um die Audio-Eingaberate mithilfe \n" + "der folgenden Formel zu berechnen: \n" + " \n" + "audio_input_rate = Spiel-Eingaberate * Bildschirm- \n" + "Wiederholrate / Spiel-Wiederholrate\n" + " \n" + "Wenn die Implementierung keinen Wert liefert, \n" + "werden aus Kompatiblitätsgründen die Werte für NTSC \n" + "angenommen.\n" + " \n" + "Dieser Wert sollte nahe 60Hz liegen, um Tonsprünge zu vermeiden. \n" + "Wenn Dein Bildschirm nicht auf 60Hz oder einem ähnlichen Wert läuft, \n" + "deaktiviere VSync und lasse diese Einstellung unverändert. \n"); + break; + case MENU_ENUM_LABEL_VIDEO_ROTATION: + snprintf(s, len, + "Erzwinge eine bestimmte \n" + "Bildschirm-Rotation.\n" + " \n" + "Diese Drehung wird zu den Drehungen hinzugefügt, \n" + "die durch den libretro-Core festgelegt werden. (siehe 'Erlaube \n" + "Bild-Drehung')."); + break; + case MENU_ENUM_LABEL_VIDEO_SCALE: + snprintf(s, len, + "Vollbild-Auflösung.\n" + " \n" + "Auflösung von 0 verwendet die \n" + "Auflösung der Umgebung. \n"); + break; + case MENU_ENUM_LABEL_FASTFORWARD_RATIO: + snprintf(s, len, + "Vorspul-Verhältnis." + " \n" + "Die maximale Geschwindigkeit, mit der Inhalt \n" + "wiedergegeben wird, wenn der schnelle Vorlauf aktiviert ist.\n" + " \n" + " (z.B. 5.0 für Inhalt mit 60 FPS => auf 300 FPS \n" + "begrenzt).\n" + " \n" + "RetroArch wird pausieren, um sicherzustellen, \n" + "dass die maximale Geschwindigkeit nicht überschritten wird.\n" + "Verlasse dich nicht darauf, dass diese Begrenzung \n" + "vollkommen zuverlässig ist."); + break; + case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: + snprintf(s, len, + "Legt fest, welcher Bildschirm bevorzugt wird.\n" + " \n" + "0 (Standard) bedeutet, dass kein bestimmter Bildschirm \n" + "bevorzugt wird, 1 und größer (1 stellt den ersten \n" + "Bildschirm dar), bewirkt, dass RetroArch diesen \n" + "bestimmten Bildschirm verwenden."); + break; + case MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN: + snprintf(s, len, + "Erzwingt das Beschneiden von übertasteten \n" + "Frames.\n" + " \n" + "Das exakte Verhalten dieser Option ist von der \n" + "Core-Implementierung abhängig."); + break; + case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: + snprintf(s, len, + "Skaliere die Bildwiedergabe nur in ganzzahligen \n" + "Schritten.\n" + " \n" + "Die Basis-Größe hängt von der vom System gemeldeten \n" + "Geometrie und Seitenverhältnis ab.\n" + " \n" + "Wenn 'Seitenverhältnis erzwingen' nicht aktiv ist, wird X/Y \n" + "unabhängig voneinander ganzzahlig skaliert."); + break; + case MENU_ENUM_LABEL_AUDIO_VOLUME: + snprintf(s, len, + "Audio-Lautstärke, ausgedrückt in dB.\n" + " \n" + " 0 dB ist die normale Lautstärke. Keine Verstärkung wird angewendet.\n" + "Die Verstärkung kann zur Laufzeit mit 'Lautstärke erhöhen' \n" + "und 'Lautstärke verringern' angepasst werden."); + break; + case MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA: + snprintf(s, len, + "Audioratenkontrolle.\n" + " \n" + "Ist dieser Wert 0, wird Ratenkontrolle deaktiviert.\n" + "Jeder andere Wert steuert die Änderung der \n" + "Audiorate.\n" + " \n" + "Beschreibt, wie weit die Audiorate dynamisch \n" + "verändert werden kann.\n" + " \n" + " Eingaberate ist definiert als: \n" + " Eingaberate * (1.0 +/- (Ratenkontroll-Wert))"); + break; + case MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW: + snprintf(s, len, + "Maximaler Audioversatz.\n" + " \n" + "Definiert die maximale Änderung der Eingaberate.\n" + "Aktivieren Sie diese Option, wenn Sie \n" + "umfangreiche Änderungen im Timing wünschen, zum Beispiel\n" + "um PAL-Cores auf NTSC-Bildschirmen zu spielen.\n" + "Die Tonhöhe ist dann nicht korrekt.\n" + " \n" + " Eingaberate ist definiert als: \n" + " Eingaberate * (1.0 +/- (Max. Audioversatz))"); + break; + case MENU_ENUM_LABEL_OVERLAY_NEXT: + snprintf(s, len, + "Wechselt zum nächsten Overlay.\n" + " \n" + // Translation unclear, disabled for now. Some context would be really helpful. + // "Wraps around." + ); + break; + case MENU_ENUM_LABEL_LOG_VERBOSITY: + snprintf(s, len, + "Aktiviert oder deaktiviert ausführliche Ausgabe \n" + "des Frontends."); + break; + case MENU_ENUM_LABEL_VOLUME_UP: + snprintf(s, len, + "Erhöht die Lautstärke."); + break; + case MENU_ENUM_LABEL_VOLUME_DOWN: + snprintf(s, len, + "Verringert die Lautstärke."); + break; + case MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION: + snprintf(s, len, + "Abschaltung der Desktop-Gestaltung erzwingen.\n" + "Nur gültig für Windows Vista/7."); + break; + case MENU_ENUM_LABEL_PERFCNT_ENABLE: + snprintf(s, len, + "Leistungs-Zähler im Frontend aktivieren \n" + "und deaktivieren."); + break; + case MENU_ENUM_LABEL_SYSTEM_DIRECTORY: + snprintf(s, len, + "Systemverzeichnis. \n" + " \n" + "Bestimmt das 'system'-Verzeichnis. \n" + "Cores können dieses Verzeichnis verwenden, \n" + "um BIOS-Dateien, systemspezifische \n" + "Konfigurationen etc. zu laden. "); + break; + case MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE: + case MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD: + snprintf(s, len, + "Erstellt einen Savestate automatisch, \n" + "wenn RetroArch beendet wird .\n" + " \n" + "RetroArch wird Savestates in diesem Pfad automatisch \n" + "nach dem Starten laden, wenn 'Savestate automatisch laden' \n" + "aktiviert ist."); + break; + case MENU_ENUM_LABEL_VIDEO_THREADED: + snprintf(s, len, + "Video-Treiber in separatem Thread ausführen.\n" + " \n" + "Diese Option kann die Leistung verbessern, \n" + "verursacht jedoch möglicherweise eine erhöhte Latenz \n" + "und eine weniger flüssige Video-Ausgabe."); + break; + case MENU_ENUM_LABEL_VIDEO_VSYNC: + snprintf(s, len, + "Vertikale Synchronisation (VSync).\n"); + break; + case MENU_ENUM_LABEL_VIDEO_HARD_SYNC: + snprintf(s, len, + "Versucht, die CPU und GPU \n" + "'hart' zu synchronisieren.\n" + " \n" + "Dies kann die Latenz verringern, \n" + "reduziert jedoch möglicherweise die Leistung."); + break; + case MENU_ENUM_LABEL_REWIND_GRANULARITY: + snprintf(s, len, + "Rückspul-Genauigkeit.\n" + " \n" + "Wenn eine festgelegte Anzahl von Frames zurückgespult \n" + "wird, kannst Du mehrere Frames auf einmal \n" + "zurückspulen, was die Rückspul-Geschwindigkeit \n" + "erhöht."); + break; + case MENU_ENUM_LABEL_SCREENSHOT: + snprintf(s, len, + "Bildschirmfoto anfertigen."); + break; + case MENU_ENUM_LABEL_VIDEO_FRAME_DELAY: + snprintf(s, len, + "Legt fest, wie viele Millisekunden nach \n" + "VSync gewartet wird, bevor der Core gestartet wird.\n" + "\n" + "Dies kann die Latenz verringern, birgt jedoch\n" + "ein erhöhtes Risiko für stotternde Videoausgabe.\n" + " \n" + "Maximum ist 15."); + break; + case MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES: + snprintf(s, len, + "Legt fest, wie viele Frames die CPU \n" + "vor der GPU bearbeitet, wenn 'GPU-Hardsync' \n" + "aktiviert ist.\n" + " \n" + "Maximum ist 3.\n" + " \n" + " 0: Synchronisiert direkt mit der GPU.\n" + " 1: Synchronisiert zum vorherigen Frame.\n" + " 2: Etc ..."); + break; + case MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION: + snprintf(s, len, + "Fügt ein schwarzes Bild zwischen den einzelnen \n" + "Frames ein.\n" + " \n" + "Hilfreich für 120 Hz-Monitore, wenn \n" + "60 Hz-Material ohne Ghosting dargestellt \n" + "werden soll.\n" + " \n" + "Die Bildwiederholrate sollte so eingestellt \n" + "werden, dass sie einem 60 Hz-Monitor entspricht. \n" + "(Bildwiederholrate durch 2 teilen)."); + break; + case MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN: + snprintf(s, len, + "Startbildschirm im Menü anzeigen.\n" + "Wird automatisch deaktiviert, wenn er zum\n" + "ersten Mal dargestellt wurde.\n" + " \n" + "Dies wird nur in die Konfiguration übernommen, wenn\n" + "'Konfiguration beim Beenden speichern' aktiviert ist.\n"); + break; + case MENU_ENUM_LABEL_VIDEO_FULLSCREEN: + snprintf(s, len, "Vollbildmodus umschalten"); + break; + case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: + snprintf(s, len, + "Verhindert, dass SRAM überschrieben wird, \n" + "wenn Savestates geladen werden.\n" + " \n" + "Kann zu fehlerhaften Spielen führen."); + break; + case MENU_ENUM_LABEL_PAUSE_NONACTIVE: + snprintf(s, len, + "Spiel pausieren, wenn Fenster-Fokus \n" + "verloren ist."); + break; + case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT: + snprintf(s, len, + "Sofern verfügbar, werden Screenshots \n" + "aus Bildmaterial nach Shader-Durchgängen erzeugt."); + break; + case MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY: + snprintf(s, len, + "Bildschirmfoto-Verzeichnis. \n" + " \n" + "Verzeichnis, in welchem Bildschirmfotos abgelegt werden." + ); + break; + case MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL: + snprintf(s, len, + "Benutzerdefiniertes VSync-Intervall.\n" + " \n" + "Verwendet ein benutzerdefiniertes Intervall für VSync. \n" + "Aktiviert halbiert diese Einstellung die Bildwiederholrate."); + break; + case MENU_ENUM_LABEL_SAVEFILE_DIRECTORY: + snprintf(s, len, + "Verzeichnis für Speicherdaten. \n" + " \n" + "Speichert alle Speicherdaten (*.srm) in diesem \n" + "Verzeichnis. Dies beinhaltet verwandte Dateitypen wie \n" + ".bsv, .rt, .psrm, etc...\n" + " \n" + "Explizite Optionen über die Kommandozeile überschreiben \n" + "diese Einstellung."); + break; + case MENU_ENUM_LABEL_SAVESTATE_DIRECTORY: + snprintf(s, len, + "Verzeichnis für Savestates. \n" + " \n" + "Speichert alle Savestates (*.state) in diesem \n" + "Verzeichnis.\n" + " \n" + "Explizite Optionen über die Kommandozeile überschreiben \n" + "diese Einstellung."); + break; + case MENU_ENUM_LABEL_ASSETS_DIRECTORY: + snprintf(s, len, + "Assets-Verzeichnis. \n" + " \n" + "Dieses Verzeichnis wird standardmäßig vom Menü \n" + "verwendet, um dort nach ladbaren Inhalten wie Assets \n" + "etc. zu suchen."); + break; + case MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY: + snprintf(s, len, + "Verzeichnis für dynamische Hintergrundbilder. \n" + " \n" + "In diesem Verzeichnis werden Hintergrundbilder \n" + "abgelegt, die vom Menü dynamisch abhängig vom \n" + "Kontext geladen werden."); + break; + case MENU_ENUM_LABEL_SLOWMOTION_RATIO: + snprintf(s, len, + "Verhältnis für Zeitlupe. \n" + " \n" + "Ist die Zeitlupe eingeschaltet, wird das Spiel \n" + "um diesen Faktor verlangsamt."); + break; + case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: + snprintf(s, len, + "Definiert Achsen-Grenzwert.\n" + " \n" + "Wie weit eine Achse bewegt werden muss, um einen \n" + "Tastendruck auszulösen .\n" + "Mögliche Werte liegen im Bereich [0.0, 1.0]."); + break; + case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: + snprintf(s, len, + "Turbo-Frequenz.\n" + " \n" + "Beschreibt, wie oft Tasten, für die der Turbo \n" + "aktiviert ist, ausgelöst werden.\n" + " \n" + "Dieser Wert wird in der Anzahl der Einzelbilder angegeben." + ); + break; + case MENU_ENUM_LABEL_INPUT_DUTY_CYCLE: + snprintf(s, len, + "Turbo-Dauer.\n" + " \n" + "Beschreibt, wie lange Tasten, für die der Turbo \n" + "aktiviert ist, gehalten werden sollen.\n" + " \n" + "Dieser Wert wird in der Anzahl der Einzelbilder angegeben." + ); + break; + case MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE: + snprintf(s, len, "Touch-Unterstützung aktivieren."); + break; + case MENU_ENUM_LABEL_INPUT_PREFER_FRONT_TOUCH: + snprintf(s, len, "Touch-Eingabe auf der Vorderseite bevorzugen."); + break; + case MENU_ENUM_LABEL_MOUSE_ENABLE: + snprintf(s, len, "Maussteuerung im Menü aktivieren."); + break; + case MENU_ENUM_LABEL_POINTER_ENABLE: + snprintf(s, len, "Touch-Steuerung im Menü aktivieren."); + break; + case MENU_ENUM_LABEL_MENU_WALLPAPER: + snprintf(s, len, "Pfad zu einem Bild, welches als Hintergrundbild verwendet werden soll."); + break; + case MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND: + snprintf(s, len, + "Am Anfang und/oder dem Ende einer Liste umbrechen, \n" + "wenn die Grenzen der Liste horizontal und/oder \n" + "vertikal erreicht werden."); + break; + case MENU_ENUM_LABEL_PAUSE_LIBRETRO: + snprintf(s, len, + "Wenn deaktiviert wird der libretro-Core im \n" + "Hintergrund weiter laufen, wenn wir uns \n" + "im Menü befinden."); + break; + case MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE: + snprintf(s, len, + "Deaktiviert den Bildschirmschoner. Diese Einstellung \n" + "wird möglicherweise vom Video-Treiber nicht \n" + "berücksichtigt."); + break; + case MENU_ENUM_LABEL_NETPLAY_MODE: + snprintf(s, len, + "Netplay-Client-Modus für den aktuellen Benutzer. \n" + "Wird zu 'Server'-Modus, wenn deaktiviert."); + break; + case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES: + snprintf(s, len, + "Anzahl der Verzögerungs-Frames für Netplay. \n" + " \n" + "Wird dieser Wert erhöht, verbessert sich \n" + "die Leistung, die Latenz erhöht sich jedoch."); + case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: + snprintf(s, len, + "Legt fest, ob Netplay in einem Modus laufen soll, der keine\n" + "Savestates benötigt. \n" + " \n" + "Wenn diese Option eingeschaltet wird, wird ein sehr \n" + "schnelles Netzwerk benötigt. Da kein Rücklauf benötigt wird, \n" + "tritt keine Netplay-Verzögerung auf.\n"); + break; + break; + case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: + snprintf(s, len, + "Die Frequenz in Einzelbildern, mit der Netplay \n" + "sicherstellen wird, dass Host und Clients \n" + "synchronisiert sind. \n" + " \n" + "Bei den meisten Cores wird diese Einstellungen \n" + "keine sichtbaren Auswirkungen haben und kann ignoriert werden. \n" + "Bei nichtdeterministischen Cores legt dieser Wert fest, \n" + "wie oft die Netplay-Mitglieder miteinander synchronisiert \n" + "werden. Bei fehlerhaften Cores wird ein \n" + "anderer Wert als 0 für diese Einstellung erhebliche \n" + "Leistungsprobleme verursachen. Auf 0 setzen, um keine \n" + "Überprüfungen durchzuführen. Diese Einstellung wird nur \n" + "auf dem Netplay-Host verwendet. \n"); + break; + case MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN: + snprintf(s, len, + "Legt die Eingabeverzögerung in Einzelbildern fest, \n" + "die Netplay verwendet, um die Netzwerklatenz zu verstecken. \n" + " \n" + "In einem Multiplayer-Spiel verzögert diese Option die lokale \n" + "Eingabe, sodass das aktuelle Einzelbild \n" + "näher an dem Einzelbild liegt, welches vom Netzwerk \n" + "empfangen wird. Dies verbessert die Netplay-Performance \n" + "und benötigt weniger CPU-Leistung, verursacht \n" + "jedoch eine spürbare Eingabe-Verzögerung. \n"); + break; + case MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE: + snprintf(s, len, + "Legt den Bereich in Einzelbildern fest, die von \n" + "Netplay für die Eingabeverzögerung verwendet werden, \n" + "um die Netzwerklatenz zu verstecken. \n" + "\n" + "Wenn aktiviert, wird Netplay die Eingabeverzögerung \n" + "in Einzelbildern dynamisch anpassen, um \n" + "die CPU-Zeit, Eingabeverzögerung und \n" + "Netzwerklatenz auszubalancieren. Dies verbessert \n" + "die Netplay-Performance und benötigt weniger CPU-Leistung, \n" + "verursacht jedoch eine Eingabe-Verzögerung, die nicht vorhergesagt werden kann. \n"); + break; + case MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL: + snprintf(s, len, + "Versuche, beim Hosten eines Spiels auf eingehende \n" + "Verbindungen aus dem öffentlichen Internet zu hören. \n" + "Dabei werden UPnP oder ähnliche Techniken verwendet, \n" + "um das eigene LAN zu verlassen. \n"); + break; + case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: + snprintf(s, len, + "Maximale Zahl von Zwischenbildern. Diese Einstellung \n" + "kann dem Video-Treiber vorschreiben, einen bestimmten \n" + "Videopuffer-Modus zu verwenden. \n" + " \n" + "Einfache Pufferung - 1\n" + "Doppelte Pufferung - 2\n" + "Dreifache Pufferung - 3\n" + " \n" + "Den richtigen Puffer-Modus auzuwählen \n" + "kann einen großen Einfluss auf die Leistung nehmen."); + break; + case MENU_ENUM_LABEL_VIDEO_SMOOTH: + snprintf(s, len, + "Bild mit bilinearer Filterung glätten. \n" + "Sollte deaktiviert werden, wenn Shader verwendet werden."); + break; + case MENU_ENUM_LABEL_TIMEDATE_ENABLE: + snprintf(s, len, + "Zeigt das aktuelle Datum/die aktuelle Zeit im Menü an."); + break; + case MENU_ENUM_LABEL_BATTERY_LEVEL_ENABLE: + snprintf(s, len, + "Zeigt den aktuellen Ladezustand des Akkus im Menü an."); + break; + case MENU_ENUM_LABEL_CORE_ENABLE: + snprintf(s, len, + "Zeigt den aktuellen Core im Menü an."); + break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST: + snprintf(s, len, + "Aktiviert Netplay im Host-(Server)-Modus."); + break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT: + snprintf(s, len, + "Aktiviert Netplay im Client-Modus."); + break; + case MENU_ENUM_LABEL_NETPLAY_DISCONNECT: + snprintf(s, len, + "Bestehende Netplay-Verbindung beenden."); + break; + case MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS: + snprintf(s, len, + "Suche nach einem Netplay-Host im lokalen Netzwerk und stelle eine Verbindung zu diesem her."); + break; + case MENU_ENUM_LABEL_NETPLAY_SETTINGS: + snprintf(s, len, + "Netplay-bezogene Einstellungen."); + break; + case MENU_ENUM_LABEL_DYNAMIC_WALLPAPER: + snprintf(s, len, + "Lade ein neues Hintergrundbild dynamisch, \n" + "abhängig vom aktuellen Kontext."); + break; + case MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL: + snprintf(s, len, + "URL zum Core-Verzeichnis auf dem \n" + "Libretro-Server."); + break; + case MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL: + snprintf(s, len, + "URL zum Assets-Verzeichnis auf dem \n" + "Libretro-Server."); + break; + case MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE: + snprintf(s, len, + "Wenn aktiviert, werden die aktuellen Tastenbelegungen \n" + "mit den neu zugewiesenen Belegungen für den \n" + "aktuellen Core überschrieben."); + break; + case MENU_ENUM_LABEL_OVERLAY_DIRECTORY: + snprintf(s, len, + "Overlay-Verzeichnis. \n" + " \n" + "Definiert ein Verzeichnis, in dem alle Overlays \n" + "aufbewahrt werden."); + break; + case MENU_ENUM_LABEL_INPUT_MAX_USERS: + snprintf(s, len, + "Maximale Anzahl von Benutzern, die in \n" + "RetroArch unterstützt werden."); + break; + case MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE: + snprintf(s, len, + "Entpacke Archive, die heruntergeladenen Inhalt \n" + "enthalten, nach dem Herunterladen \n" + "automatisch."); + break; + case MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE: + snprintf(s, len, + "Filtere die angezeigten Dateien nach \n" + "unterstützten Dateierweiterungen."); + break; + case MENU_ENUM_LABEL_NETPLAY_NICKNAME: + snprintf(s, len, + "Der Benutzername der Person, die RetroArch verwendet. \n" + "Wird in Online-Spielen verwendet."); + break; + case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT: + snprintf(s, len, + "Verwende Tastenbelegung für Spieler 1, \n" + "wenn Du Teilnehmer an einem Netplay-Spiel bist."); + break; + case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT: + snprintf(s, len, + "Der Port der Host-IP-Adresse. \n" + "Kann entweder ein TCP- oder ein UDP-Port sein."); + break; + case MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE: + snprintf(s, len, + "Aktiviere oder deaktiviere Beobachter-Modus\n" + "für den Benutzer im Netplay-Spiel."); + break; + case MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS: + snprintf(s, len, + "Die Addresse des Hosts, zu dem verbunden werden soll."); + break; + case MENU_ENUM_LABEL_NETPLAY_PASSWORD: + snprintf(s, len, + "Das Passwort, welches für die Verbindung mit dem Netplay-Host \n" + "verwendet wird. Wird nur im Host-Modus verwendet."); + break; + case MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD: + snprintf(s, len, + "Das Passwort, welches für die Verbindung mit dem Netplay-Host \n" + "und ausschließlich mit Beobachter-Privilegien verwendet wird. \n" + "Wird nur im Host-Modus verwendet."); + break; + case MENU_ENUM_LABEL_STDIN_CMD_ENABLE: + snprintf(s, len, + "Aktiviere stdin-Kommandozeile."); + break; + case MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT: + snprintf(s, len, + "Starte begleitenden Treiber für Benutzeroberfläche \n" + "während des Bootens (wenn verfügbar)."); + break; + case MENU_ENUM_LABEL_MENU_DRIVER: + snprintf(s, len, "Menü-Treiber, der verwendet werden soll."); + break; + case MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO: + snprintf(s, len, + "Gamepad-Tastenkombination, um Menü aufzurufen. \n" + " \n" + "0 - Keine \n" + "1 - Drücke L + R + Y + D-Pad nach unten \n" + "gleichzeitig. \n" + "2 - Drücke L3 + R3 gleichzeitig. \n" + "3 - Drücke Start + Select gleichzeitig."); + break; + case MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU: + snprintf(s, len, "Erlaubt jedem Benutzer, das Menü zu steuern. \n" + " \n" + "Wenn deaktiviert, kann nur Benutzer 1 das Menü steuern."); + break; + case MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE: + snprintf(s, len, + "Aktiviere automatische Eingabe-Erkennung.\n" + " \n" + "Wird versuchen, Joypads automatisch zu konfigurieren. \n" + "(Plug-and-Play)."); + break; + case MENU_ENUM_LABEL_CAMERA_ALLOW: + snprintf(s, len, + "Erlaubt oder verbietet den Cores Zugriff auf \n" + "die Kamera."); + break; + case MENU_ENUM_LABEL_LOCATION_ALLOW: + snprintf(s, len, + "Erlaubt oder verbietet den Cores Zugriff \n" + "auf Ortungsdienste."); + break; + case MENU_ENUM_LABEL_TURBO: + snprintf(s, len, + "Aktiviert den Turbo.\n" + " \n" + "Wird die Turbo-Taste gedrückt, während eine andere Taste \n" + "gedrückt wird, wird für diese Taste der Turbo-Modus aktiviert. \n" + "Im Turbo-Modus wird die Taste innerhalb der Emulation \n" + "automatisch wiederholt gedrückt und wieder losgelassen. \n" + " \n" + "Der Turbo-Modus wird beendet, wenn die Taste \n" + "selbst (nicht die Turbo-Taste) losgelassen wird."); + break; case MENU_ENUM_LABEL_OSK_ENABLE: snprintf(s, len, - "(De-)Aktiviere die Bildschirmtastatur."); + "Bildschirmtastatur ein/ausschalten."); break; case MENU_ENUM_LABEL_AUDIO_MUTE: snprintf(s, len, - "Audio stummschalten."); + "Ton stumm/lautschalten."); break; case MENU_ENUM_LABEL_REWIND: snprintf(s, len, - "Halte die Taste zum Zurückspulen gedrückt.\n" + "Taste zum Zurückspulen gedrückt halten.\n" " \n" - "Die Zurückspulfunktion muss eingeschaltet \n" - "sein."); + "Die Rücklauf-Funktion muss aktiviert sein."); break; - case MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY: - snprintf(s, len, - "%s. \n" - " \n" - "Setzt das Startverzeichnis des Dateibrowsers.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY) - ); - break; case MENU_ENUM_LABEL_EXIT_EMULATOR: snprintf(s, len, - "Taste zum Beenden von RetroArch." + "Taste zum sauberen Beenden von RetroArch." #if !defined(RARCH_MOBILE) && !defined(RARCH_CONSOLE) - "\nWenn du es stattdessen mittels SIGKILL \n" - "beendest, wird RetroArch nicht den RAM \n" - "sichern. Bei unixoiden Betriebssystemen \n" - "erlaubt SIGINT/SIGTERM ein sauberes \n" + "\nWenn Du RetroArch 'unsanft' beendest (SIGKILL, \n" + "etc), werden RAM-Speicher etc. nicht gespeichert.\n" + "Auf Unix-ähnlichen Systemen erlaubt\n" + "SIGINT/SIGTERM ein sauberes\n" "Beenden." #endif ); break; case MENU_ENUM_LABEL_LOAD_STATE: snprintf(s, len, - "Lädt einen Savestate."); + "Lädt Save-State."); break; case MENU_ENUM_LABEL_SAVE_STATE: snprintf(s, len, - "Speichert einen Savestate."); + "Speichert Save-State."); break; case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS: snprintf(s, len, - "Netplay-Spieler tauschen."); + "Netplay-Benutzer vertauschen."); break; case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS: snprintf(s, len, - "Erhöht den Cheat-Index.\n"); + "Cheat-Index erhöhen.\n"); break; case MENU_ENUM_LABEL_CHEAT_INDEX_MINUS: snprintf(s, len, - "Verringert den Cheat-Index.\n"); + "Cheat-Index verringern.\n"); break; case MENU_ENUM_LABEL_SHADER_PREV: snprintf(s, len, - "Wendet vorherigen Shader im Verzeichnis an."); + "Wendet den vorherigen Shader im Verzeichnis an."); break; case MENU_ENUM_LABEL_SHADER_NEXT: snprintf(s, len, - "Wendet nächsten Shader im Verzeichnis an."); + "Wendet den nächsten Shader im Verzeichnis an."); break; case MENU_ENUM_LABEL_RESET: snprintf(s, len, - "Setzt den Content zurück.\n"); + "Inhalt zurücksetzen.\n"); break; case MENU_ENUM_LABEL_PAUSE_TOGGLE: snprintf(s, len, - "Pausiert den Content und setzt ihn wieder fort."); + "Inhalt pausieren und wieder fortsetzen."); break; case MENU_ENUM_LABEL_CHEAT_TOGGLE: snprintf(s, len, - "Schaltet den Cheat-Index ein und aus.\n"); + "Cheat-Index ein-/ausschalten.\n"); break; case MENU_ENUM_LABEL_HOLD_FAST_FORWARD: snprintf(s, len, - "Halte den Knopf gedrückt, um vorzuspulen. Beim Loslassen \n" - "wird das Vorspulen beendet."); + "Zum Vorspulen gedrückt halten. Wird die Taste \n" + "losgelassen, wird der schnelle Vorlauf beendet."); break; case MENU_ENUM_LABEL_SLOWMOTION: snprintf(s, len, - "Halte den Knopf gedrückt, um die Zeitlupe einzuschalten."); + "Gedrückt halten für Zeitlupe."); break; case MENU_ENUM_LABEL_FRAME_ADVANCE: snprintf(s, len, - "Frame-Advance, wenn der Content pausiert ist."); + "Einzelbild-Vorlauf, wenn Inhalt pausiert ist."); break; case MENU_ENUM_LABEL_MOVIE_RECORD_TOGGLE: snprintf(s, len, - "Aufnahme ein- und ausschalten."); + "Aufnahme starten/beenden."); break; case MENU_ENUM_LABEL_L_X_PLUS: case MENU_ENUM_LABEL_L_X_MINUS: @@ -425,145 +1894,54 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Positive X-Achse ist rechts. \n" "Positive Y-Achse ist unten."); break; - case MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST: - snprintf(s, len, "Erfolgsliste"); - break; - case MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE: - snprintf(s, len, "Erfolgsliste (Hardcore)"); - break; - case MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING_DESC: - { - /* Work around C89 limitations */ - char u[501]; - const char * t = - "RetroArch verwendet eine einzigartige\n" - "Art der Synchronisation von Audio/Video.\n" - "Diese wird durch die Bildwiederholrate\n" - "des Monitors kalibriert.\n" - "\n" - "Falls du irgenwelches Knistern oder Risse\n" - "feststellst, kannst du folgende Möglichkeiten:\n" - "\n"; - snprintf(u, sizeof(u), - "a) Gehe zu '%s' -> '%s' und aktiviere\n" - "'%s'. Die Bildwiederholungsrate spielt\n" - "in diesem Modus keine Rolle. \n" - "Die Bildwiederholungsrate wird höher sein,\n" - "allerdings läuft das Video weniger flüssig.\n" - "b) Gehe zu '%s' -> '%s' und beachte\n" - "'%s'. Lass es bis 2048 Frames laufen und\n" - "bestätige mit 'OK'.\n", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO) - ); - strlcpy(s, t, len); - strlcat(s, u, len); - } - break; - case MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD_DESC: - snprintf(s, len, - "Du kannst das virtuelle Gamepad-Overlay\n" - "unter '%s' -> '%s' ändern." - " \n" - "Darin kannst du die Grösse, die Transparenz\n" - "und vieles mehr anpassen.\n" - " \n" - "WICHTIG: Standartmässig, ist das virtuelle\n" - "Gamepad-Overlay im Menü nicht ersichtlich.\n" - "Wenn du dies ändern möchtest,\n" - "kannst du '%s' auf Nein stellen.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU) - ); - break; - case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: - snprintf(s, len, - "Um Inhalte zu suchen, gehe zu '%s' und\n" - "wähle entweder '%s' oder '%s'.\n" - " \n" - "Die Dateien werden mit Einträgen in der\n" - "Datenbank verglichen.\n" - "Wenn es einen Treffer gibt, wird der Inhalt\n" - "zur Sammlung hinzugefügt.\n" - " \n" - "Danach kannst du einfach den Inhalt unter\n" - "'%s' -> '%s' laden,\n" - "anstatt jedesmal die Datei neu zu suchen.\n" - " \n" - "WICHTIG: Inhalte für einige Cores sind zum\n" - "Teil noch nicht scannbar.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) - ); - break; - case MENU_ENUM_LABEL_VALUE_MENU_ENUM_CONTROLS_PROLOG: - snprintf(s, len, - "Du kannst folgende Steuerelemente mit\n" - "deinem Controller oder deiner Tastatur verwenden\n" - "um durch das Menü zu navigieren: \n" - " \n" - ); - break; - case MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY: - snprintf(s, len, "Übergeordnetes Verzeichnis"); - break; - case MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE: - snprintf(s, len, "SAMBA aktivieren"); - break; - case MENU_ENUM_LABEL_VALUE_SHUTDOWN: - snprintf(s, len, "Herunterfahren"); - break; - case MENU_ENUM_LABEL_VALUE_SSH_ENABLE: - snprintf(s, len, "SSH aktivieren"); - break; - case MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST: - snprintf(s, len, "Vorschaubilder aktualisieren"); - break; - case MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA: - snprintf(s, len, "Lakka aktualisieren"); - break; case MENU_ENUM_LABEL_VALUE_WHAT_IS_A_CORE_DESC: - snprintf(s, len, - "RetroArch alleine macht nichts. \n" - " \n" - "Damit es etwas tut, musst du \n" - "ein Programm darin laden. \n" - "\n" - "Wir nennen so ein Programm 'Libretro core', \n" - "oder 'core' als Abkürzung. \n" - " \n" - "Um einen Core zu laden, wählen Sie einen \n" - "unter '%s' aus.\n" - " \n" + snprintf(s, len, + "RetroArch selbst tut nichts. \n" + " \n" + "Damit RetroArch etwas tut, musst \n" + "Du ein Programm hineinladen. \n" + "\n" + "Wir nennen diese Programme 'Libretro-Core', \n" + "oder einfach nur 'Core'. \n" + " \n" + "Um einen Core zu laden, verwende \n" + "'Core laden'.\n" + " \n" #ifdef HAVE_NETWORKING - "Du erhälst Cores durch verschiedene Wege: \n" - "* Herunterladen unter\n" - "'%s' -> '%s'.\n" - "* Manuelles hinzufügen nach\n" - "'%s'.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) + "Du kannst die Cores auf mehreren Wegen beziehen: \n" + "* Herunterladen, indem Du\n" + "'%s' -> '%s' verwendest. \n" + "* Manuell ins Verzeichnis \n" + "'%s' kopieren.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) #else - "Du erhälst Cores wenn du diese \n" - "manuell hinzufügst unter\n" - "'%s'.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) + "Du kannst die Cores beziehen, indem\n" + "du sie manuell ins Verzeichnis \n" + "'%s' kopierst.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) #endif - ); - break; - case MSG_UNKNOWN: + ); + break; + case MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD_DESC: + snprintf(s, len, + "Du kannst das virtuelle Gamepad-Overlay ändern, indem Du \n" + "zu '%s' -> '%s' gehst." + " \n" + "Hier kannst du das Overlay ändern,\n" + "die Größe und Transparenz der Tasten verändern, etc.\n" + " \n" + "HINWEIS: Standardmäßig werden virtuelle Gamepad-Overlays \n" + "versteckt, wenn Du dich im Menü befindest.\n" + "Wenn Du dieses Verhalten ändern möchtest,\n" + "kannst Du '%s' auf 'aus' setzen.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU) + ); + break; default: - /* TODO/FIXME - translate */ if (string_is_empty(s)) strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); return -1; @@ -572,12 +1950,51 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) return 0; } -const char *msg_hash_to_str_de(enum msg_hash_enums msg) +#ifdef HAVE_MENU +static const char *menu_hash_to_str_de_label_enum(enum msg_hash_enums msg) { + if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && + msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) + { + static char hotkey_lbl[128] = {0}; + unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; + snprintf(hotkey_lbl, sizeof(hotkey_lbl), "input_hotkey_binds_%d", idx); + return hotkey_lbl; + } + switch (msg) { - #include "msg_hash_de.h" + #include "msg_hash_lbl.h" default: +#if 0 + RARCH_LOG("Unimplemented: [%d]\n", msg); +#endif + break; + } + + return "null"; +} +#endif + +const char *msg_hash_to_str_de(enum msg_hash_enums msg) +{ +#ifdef HAVE_MENU + const char *ret = menu_hash_to_str_de_label_enum(msg); + + if (ret && !string_is_equal(ret, "null")) + return ret; +#endif + + switch (msg) + { + #include "msg_hash_de.h" + default: +#if 0 + RARCH_LOG("Unimplemented: [%d]\n", msg); + { + RARCH_LOG("[%d] : %s\n", msg - 1, msg_hash_to_str(((enum msg_hash_enums)(msg - 1)))); + } +#endif break; } From c866a3f1a8c6b26b863a866854c5c07d84ebb79f Mon Sep 17 00:00:00 2001 From: rootfather Date: Sun, 5 Feb 2017 16:49:09 +0100 Subject: [PATCH 22/90] Remove leftover pragma --- intl/msg_hash_de.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 97eab0ce87..87a2270323 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -23,12 +23,6 @@ #include "../configuration.h" #include "../verbosity.h" -// Is this still needed in current RetroArch versions or is -// this an old left-over? -// #ifdef __clang__ -// #pragma clang diagnostic ignored "-Winvalid-source-encoding" -// #endif - int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) { uint32_t driver_hash = 0; From 6b9ba1e2b1afccf19c66be953c23a1dcb5122bee Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 5 Feb 2017 16:23:13 +0000 Subject: [PATCH 23/90] Added preliminary support for Retro Achievements leaderboards --- cheevos/cheevos.c | 439 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 416 insertions(+), 23 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d7eb8c5e4e..a3d5526b33 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -82,6 +82,9 @@ #define CHEEVOS_JSON_KEY_CONSOLE_ID 0x071656e5U #define CHEEVOS_JSON_KEY_TOKEN 0x0e2dbd26U #define CHEEVOS_JSON_KEY_FLAGS 0x0d2e96b2U +#define CHEEVOS_JSON_KEY_LEADERBOARDS 0xf1247d2dU +#define CHEEVOS_JSON_KEY_MEM 0x0b8807e4U +#define CHEEVOS_JSON_KEY_FORMAT 0xb341208eU enum { @@ -241,9 +244,11 @@ typedef struct typedef struct { int in_cheevos; + int in_lboards; uint32_t field_hash; unsigned core_count; unsigned unofficial_count; + unsigned lboard_count; } cheevos_countud_t; typedef struct @@ -255,13 +260,15 @@ typedef struct typedef struct { int in_cheevos; + int in_lboards; int is_console_id; unsigned core_count; unsigned unofficial_count; + unsigned lboard_count; cheevos_field_t *field; cheevos_field_t id, memaddr, title, desc, points, author; - cheevos_field_t modified, created, badge, flags; + cheevos_field_t modified, created, badge, flags, format; } cheevos_readud_t; typedef struct @@ -271,6 +278,32 @@ typedef struct const uint32_t *ext_hashes; } cheevos_finder_t; +typedef struct +{ + cheevos_var_t var; + unsigned multiplier; +} cheevos_term_t; + +typedef struct +{ + cheevos_term_t *terms; + unsigned count; +} cheevos_expr_t; + +typedef struct +{ + unsigned id; + const char *title; + const char *description; + int active; + unsigned last_value; + + cheevos_condition_t start; + cheevos_condition_t cancel; + cheevos_condition_t submit; + cheevos_expr_t value; +} cheevos_leaderboard_t; + typedef struct { int console_id; @@ -278,25 +311,34 @@ typedef struct cheevoset_t core; cheevoset_t unofficial; + cheevos_leaderboard_t *leaderboards; + unsigned lboard_count; char token[32]; retro_ctx_memory_info_t meminfo[4]; } cheevos_locals_t; - static cheevos_locals_t cheevos_locals = { - 0, - true, - {NULL, 0}, - {NULL, 0}, - {0} + /* console_id */ 0, + /* core_supports */ true, + /* core */ {NULL, 0}, + /* unofficial */ {NULL, 0}, + /* leaderboards */ NULL, + /* lboard_count */ 0, + /* token */ {0}, + { + /* meminfo[0] */ {NULL, 0, 0}, + /* meminfo[1] */ {NULL, 0, 0}, + /* meminfo[2] */ {NULL, 0, 0}, + /* meminfo[3] */ {NULL, 0, 0} + } }; -bool cheevos_loaded = false; -int cheats_are_enabled = 0; -int cheats_were_enabled = 0; +bool cheevos_loaded = false; +int cheats_are_enabled = 0; +int cheats_were_enabled = 0; /***************************************************************************** Supporting functions. @@ -608,6 +650,43 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo) cheevos_build_memaddr(&cheevo->condition, memaddr, sizeof(memaddr)); RARCH_LOG("CHEEVOS memaddr (computed): %s\n", memaddr); } + +static void cheevos_log_lboard(const cheevos_leaderboard_t* lb) +{ + char mem[256]; + char* aux; + size_t left; + unsigned i; + + RARCH_LOG("CHEEVOS leaderboard %p\n", lb); + RARCH_LOG("CHEEVOS id: %u\n", lb->id); + RARCH_LOG("CHEEVOS title: %s\n", lb->title); + RARCH_LOG("CHEEVOS desc: %s\n", lb->description); + + cheevos_build_memaddr(&lb->start, mem, sizeof(mem)); + RARCH_LOG("CHEEVOS start: %s\n", mem); + + cheevos_build_memaddr(&lb->cancel, mem, sizeof(mem)); + RARCH_LOG("CHEEVOS cancel: %s\n", mem); + + cheevos_build_memaddr(&lb->submit, mem, sizeof(mem)); + RARCH_LOG("CHEEVOS submit: %s\n", mem); + + left = sizeof(mem); + aux = mem; + + for (i = 0; i < lb->value.count; i++) + { + if (i != 0) + cheevos_add_char(&aux, &left, '_'); + + cheevos_add_var(&lb->value.terms[i].var, &aux, &left); + cheevos_add_char(&aux, &left, '*'); + cheevos_add_uint(&aux, &left, lb->value.terms[i].multiplier); + } + + RARCH_LOG("CHEEVOS value: %s\n", mem); +} #endif static uint32_t cheevos_djb2(const char* str, size_t length) @@ -655,7 +734,7 @@ static int cheevos_http_get(const char **result, size_t *size, break; } - RARCH_ERR("CHEEVOS error getting %s: %s.\n", url, msg); + RARCH_ERR("CHEEVOS error during HTTP GET: %s.\n", msg); return ret; } @@ -756,6 +835,7 @@ static int cheevos_count__json_end_array(void *userdata) { cheevos_countud_t* ud = (cheevos_countud_t*)userdata; ud->in_cheevos = 0; + ud->in_lboards = 0; return 0; } @@ -767,6 +847,8 @@ static int cheevos_count__json_key(void *userdata, if (ud->field_hash == CHEEVOS_JSON_KEY_ACHIEVEMENTS) ud->in_cheevos = 1; + else if (ud->field_hash == CHEEVOS_JSON_KEY_LEADERBOARDS) + ud->in_lboards = 1; return 0; } @@ -785,12 +867,15 @@ static int cheevos_count__json_number(void *userdata, else if (flags == 5) ud->unofficial_count++; /* Unofficial achievements */ } + else if (ud->in_lboards && ud->field_hash == CHEEVOS_JSON_KEY_ID) + ud->lboard_count++; return 0; } static int cheevos_count_cheevos(const char *json, - unsigned *core_count, unsigned *unofficial_count) + unsigned *core_count, unsigned *unofficial_count, + unsigned *lboard_count) { static const jsonsax_handlers_t handlers = { @@ -813,11 +898,13 @@ static int cheevos_count_cheevos(const char *json, ud.in_cheevos = 0; ud.core_count = 0; ud.unofficial_count = 0; + ud.lboard_count = 0; res = jsonsax_parse(json, &handlers, (void*)&ud); *core_count = ud.core_count; *unofficial_count = ud.unofficial_count; + *lboard_count = ud.lboard_count; return res; } @@ -1256,6 +1343,111 @@ static int cheevos_parse_condition(cheevos_condition_t *condition, const char* m return 0; } +static void cheevos_free_condition(cheevos_condition_t* condition) +{ + unsigned i; + + if (condition->condsets) + { + for (i = 0; i < condition->count; i++) + { + free((void*)condition->condsets[i].conds); + } + + free((void*)condition->condsets); + } +} + +/***************************************************************************** +Parse the Mem field of leaderboards. +*****************************************************************************/ + +static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem) +{ + const char* aux; + char* end; + unsigned i; + expr->count = 1; + + for (aux = mem; *aux != '"'; aux++) + { + expr->count += *aux == '_'; + } + + expr->terms = (cheevos_term_t*)calloc(expr->count, sizeof(cheevos_term_t)); + + if (!expr->terms) + return -1; + + for (i = 0, aux = mem; i < expr->count; i++) + { + cheevos_parse_var(&expr->terms[i].var, &aux); + + if (*aux != '*') + { + free((void*)expr->terms); + return -1; + } + + expr->terms[i].multiplier = strtol(aux + 1, &end, 10); + aux = end + 1; + } + + return 0; +} + +static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem) +{ + lb->start.condsets = NULL; + lb->cancel.condsets = NULL; + lb->submit.condsets = NULL; + lb->value.terms = NULL; + + for (;;) + { + if (*mem == 'S' && mem[1] == 'T' && mem[2] == 'A' && mem[3] == ':') + { + if (cheevos_parse_condition(&lb->start, mem + 4)) + goto error; + } + else if (*mem == 'C' && mem[1] == 'A' && mem[2] == 'N' && mem[3] == ':') + { + if (cheevos_parse_condition(&lb->cancel, mem + 4)) + goto error; + } + else if (*mem == 'S' && mem[1] == 'U' && mem[2] == 'B' && mem[3] == ':') + { + if (cheevos_parse_condition(&lb->submit, mem + 4)) + goto error; + } + else if (*mem == 'V' && mem[1] == 'A' && mem[2] == 'L' && mem[3] == ':') + { + if (cheevos_parse_expression(&lb->value, mem + 4)) + goto error; + } + else + goto error; + + for (mem += 4;; mem++) + { + if (*mem == ':' && mem[1] == ':') + { + mem += 2; + break; + } + else if (*mem == '"') + return 0; + } + } + +error: + cheevos_free_condition(&lb->start); + cheevos_free_condition(&lb->cancel); + cheevos_free_condition(&lb->submit); + free((void*)lb->value.terms); + return -1; +} + /***************************************************************************** Load achievements from a JSON string. *****************************************************************************/ @@ -1317,11 +1509,38 @@ error: return -1; } +static int cheevos_new_lboard(cheevos_readud_t *ud) +{ + cheevos_leaderboard_t *lboard = cheevos_locals.leaderboards + ud->lboard_count++; + + lboard->id = strtol(ud->id.string, NULL, 10); + lboard->title = cheevos_dupstr(&ud->title); + lboard->description = cheevos_dupstr(&ud->desc); + + if (!lboard->title || !lboard->description) + goto error; + + if (cheevos_parse_mem(lboard, ud->memaddr.string)) + goto error; + +#ifdef CHEEVOS_VERBOSE + cheevos_log_lboard(lboard); +#endif + + return 0; + +error: + free((void*)lboard->title); + free((void*)lboard->description); + return -1; +} + static int cheevos_read__json_key( void *userdata, const char *name, size_t length) { cheevos_readud_t *ud = (cheevos_readud_t*)userdata; uint32_t hash = cheevos_djb2(name, length); + int common = ud->in_cheevos || ud->in_lboards; ud->field = NULL; @@ -1330,23 +1549,30 @@ static int cheevos_read__json_key( void *userdata, case CHEEVOS_JSON_KEY_ACHIEVEMENTS: ud->in_cheevos = 1; break; + case CHEEVOS_JSON_KEY_LEADERBOARDS: + ud->in_lboards = 1; + break; case CHEEVOS_JSON_KEY_CONSOLE_ID: ud->is_console_id = 1; break; case CHEEVOS_JSON_KEY_ID: - if (ud->in_cheevos) + if (common) ud->field = &ud->id; break; case CHEEVOS_JSON_KEY_MEMADDR: if (ud->in_cheevos) ud->field = &ud->memaddr; break; + case CHEEVOS_JSON_KEY_MEM: + if (ud->in_lboards) + ud->field = &ud->memaddr; + break; case CHEEVOS_JSON_KEY_TITLE: - if (ud->in_cheevos) + if (common) ud->field = &ud->title; break; case CHEEVOS_JSON_KEY_DESCRIPTION: - if (ud->in_cheevos) + if (common) ud->field = &ud->desc; break; case CHEEVOS_JSON_KEY_POINTS: @@ -1373,6 +1599,10 @@ static int cheevos_read__json_key( void *userdata, if (ud->in_cheevos) ud->field = &ud->flags; break; + case CHEEVOS_JSON_KEY_FORMAT: + if (ud->in_lboards) + ud->field = &ud->format; + break; default: break; } @@ -1419,6 +1649,8 @@ static int cheevos_read__json_end_object(void *userdata) if (ud->in_cheevos) return cheevos_new_cheevo(ud); + else if (ud->in_lboards) + return cheevos_new_lboard(ud); return 0; } @@ -1427,6 +1659,7 @@ static int cheevos_read__json_end_array(void *userdata) { cheevos_readud_t *ud = (cheevos_readud_t*)userdata; ud->in_cheevos = 0; + ud->in_lboards = 0; return 0; } @@ -1448,7 +1681,7 @@ static int cheevos_parse(const char *json) NULL }; - unsigned core_count, unofficial_count; + unsigned core_count, unofficial_count, lboard_count; int res; cheevos_readud_t ud; settings_t *settings = config_get_ptr(); @@ -1458,7 +1691,8 @@ static int cheevos_parse(const char *json) return 0; /* Count the number of achievements in the JSON file. */ - res = cheevos_count_cheevos(json, &core_count, &unofficial_count); + res = cheevos_count_cheevos(json, &core_count, &unofficial_count, + &lboard_count); if (res != JSONSAX_OK) return -1; @@ -1473,21 +1707,30 @@ static int cheevos_parse(const char *json) calloc(unofficial_count, sizeof(cheevo_t)); cheevos_locals.unofficial.count = unofficial_count; - if (!cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos) + cheevos_locals.leaderboards = (cheevos_leaderboard_t*) + calloc(lboard_count, sizeof(cheevos_leaderboard_t)); + cheevos_locals.lboard_count = lboard_count; + + if ( !cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos + || !cheevos_locals.leaderboards) { free((void*)cheevos_locals.core.cheevos); free((void*)cheevos_locals.unofficial.cheevos); - cheevos_locals.core.count = cheevos_locals.unofficial.count = 0; + free((void*)cheevos_locals.leaderboards); + cheevos_locals.core.count = cheevos_locals.unofficial.count = + cheevos_locals.lboard_count = 0; return -1; } /* Load the achievements. */ ud.in_cheevos = 0; + ud.in_lboards = 0; ud.is_console_id = 0; ud.field = NULL; ud.core_count = 0; ud.unofficial_count = 0; + ud.lboard_count = 0; if (jsonsax_parse(json, &handlers, (void*)&ud) != JSONSAX_OK) goto error; @@ -1535,7 +1778,6 @@ static unsigned cheevos_get_var_value(cheevos_var_t *var) if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) { - /* TODO Check with Scott if the bank id is needed */ const uint8_t *memory = cheevos_get_memory(var); unsigned live_val = 0; @@ -1950,6 +2192,155 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) } } +static int cheevos_test_lboard_condition(const cheevos_condition_t* condition) +{ + int dirty_conds = 0; + int reset_conds = 0; + int ret_val = 0; + int ret_val_sub_cond = condition->count == 1; + cheevos_condset_t *condset = condition->condsets; + const cheevos_condset_t *end = condset + condition->count; + + if (condset < end) + { + ret_val = cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0); + condset++; + } + + while (condset < end) + { + ret_val_sub_cond |= cheevos_test_cond_set(condset, &dirty_conds, &reset_conds, 0); + condset++; + } + + if (reset_conds) + { + for (condset = condition->condsets; condset < end; condset++) + cheevos_reset_cond_set(condset, 0); + } + + return ret_val && ret_val_sub_cond; +} + +static unsigned cheevos_expr_value(cheevos_expr_t* expr) +{ + cheevos_term_t* term = expr->terms; + unsigned i, value = 0; + + for (i = expr->count; i != 0; i--, term++) + { + value += cheevos_get_var_value(&term->var) * term->multiplier; + } + + return value; +} + +static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, + char* url, size_t url_size) +{ + settings_t *settings = config_get_ptr(); + char signature[64]; + MD5_CTX ctx; + uint8_t hash[16]; + + hash[0] = '\0'; + + snprintf(signature, sizeof(signature), "%u%s%u", lboard->id, + settings->cheevos.username, lboard->id); + + MD5_Init(&ctx); + MD5_Update(&ctx, (void*)signature, strlen(signature)); + MD5_Final(hash, &ctx); + + snprintf( + url, url_size, + "http://retroachievements.org/dorequest.php?r=submitlbentry&u=%s&t=%s&i=%u&s=%u" + "&v=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + settings->cheevos.username, cheevos_locals.token, lboard->id, + lboard->last_value, + hash[ 0], hash[ 1], hash[ 2], hash[ 3], + hash[ 4], hash[ 5], hash[ 6], hash[ 7], + hash[ 8], hash[ 9], hash[10], hash[11], + hash[12], hash[13], hash[14], hash[15] + ); + + url[url_size - 1] = 0; + +#ifdef CHEEVOS_LOG_URLS + cheevos_log_url("CHEEVOS url to submit the leaderboard: %s\n", url); +#endif +} + +static void cheevos_lboard_submit(void *task_data, void *user_data, const char *error) +{ + cheevos_leaderboard_t *lboard = (cheevos_leaderboard_t *)user_data; + + if (error == NULL) + { + RARCH_LOG("CHEEVOS submitted leaderboard %u.\n", lboard->id); + } + else + RARCH_ERR("CHEEVOS error submitting leaderboard %u\n", lboard->id); +#if 0 + { + char url[256]; + url[0] = '\0'; + + RARCH_ERR("CHEEVOS error submitting leaderboard %u, retrying...\n", lboard->id); + + cheevos_make_lboard_url(lboard, url, sizeof(url)); + task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); + } +#endif +} + +static void cheevos_test_leaderboards(void) +{ + cheevos_leaderboard_t* lboard = cheevos_locals.leaderboards; + unsigned i; + + for (i = cheevos_locals.lboard_count; i != 0; i--, lboard++) + { + if (lboard->active) + { + unsigned value = cheevos_expr_value(&lboard->value); + + if (value != lboard->last_value) + { +#ifdef CHEEVOS_VERBOSE + RARCH_LOG("CHEEVOS value %s %u\n", lboard->title, value); +#endif + lboard->last_value = value; + } + + if (cheevos_test_lboard_condition(&lboard->submit)) + { + char url[256]; + + cheevos_make_lboard_url(lboard, url, sizeof(url)); + task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); + + RARCH_LOG("CHEEVOS submit %s\n", lboard->title); + } + + if (cheevos_test_lboard_condition(&lboard->cancel)) + { + RARCH_LOG("CHEEVOS cancel %s\n", lboard->title); + lboard->active = 0; + } + } + else + { + if (cheevos_test_lboard_condition(&lboard->start)) + { + RARCH_LOG("CHEEVOS start %s\n", lboard->title); + lboard->active = 1; + lboard->last_value = (unsigned)-1; + } + } + } +} + /***************************************************************************** Free the loaded achievements. *****************************************************************************/ @@ -2698,13 +3089,17 @@ void cheevos_reset_game(void) const cheevo_t *end = cheevo + cheevos_locals.core.count; for (; cheevo < end; cheevo++) + { cheevo->last = 1; + } cheevo = cheevos_locals.unofficial.cheevos; end = cheevo + cheevos_locals.unofficial.count; for (; cheevo < end; cheevo++) + { cheevo->last = 1; + } } void cheevos_populate_menu(void *data, bool hardcore) @@ -2842,7 +3237,7 @@ bool cheevos_unload(void) cheevos_free_cheevo_set(&cheevos_locals.core); cheevos_free_cheevo_set(&cheevos_locals.unofficial); - cheevos_loaded = false; + cheevos_loaded = 0; return true; } @@ -2881,9 +3276,7 @@ void cheevos_test(void) if (settings->cheevos.test_unofficial) cheevos_test_cheevo_set(&cheevos_locals.unofficial); -#if 0 cheevos_test_leaderboards(); -#endif } bool cheevos_set_cheats(void) From b5153ced9d51428825112ebba6d859542631de43 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 5 Feb 2017 16:39:14 +0000 Subject: [PATCH 24/90] Make leaderboard term multipliers signed; mark leaderboards explicitly in log messages --- cheevos/cheevos.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index a3d5526b33..c66f828770 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -281,7 +281,7 @@ typedef struct typedef struct { cheevos_var_t var; - unsigned multiplier; + int multiplier; } cheevos_term_t; typedef struct @@ -296,7 +296,7 @@ typedef struct const char *title; const char *description; int active; - unsigned last_value; + int last_value; cheevos_condition_t start; cheevos_condition_t cancel; @@ -447,6 +447,16 @@ static void cheevos_add_uint(char** aux, size_t* left, unsigned v) cheevos_add_string(aux, left, buffer); } +static void cheevos_add_uint(char** aux, size_t* left, int v) +{ + char buffer[32]; + + snprintf(buffer, sizeof(buffer), "%d", v); + buffer[sizeof(buffer) - 1] = 0; + + cheevos_add_string(aux, left, buffer); +} + static void cheevos_log_var(const cheevos_var_t* var) { RARCH_LOG("CHEEVOS size: %s\n", @@ -682,7 +692,7 @@ static void cheevos_log_lboard(const cheevos_leaderboard_t* lb) cheevos_add_var(&lb->value.terms[i].var, &aux, &left); cheevos_add_char(&aux, &left, '*'); - cheevos_add_uint(&aux, &left, lb->value.terms[i].multiplier); + cheevos_add_int(&aux, &left, lb->value.terms[i].multiplier); } RARCH_LOG("CHEEVOS value: %s\n", mem); @@ -1389,7 +1399,7 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem) return -1; } - expr->terms[i].multiplier = strtol(aux + 1, &end, 10); + expr->terms[i].multiplier = (int)strtol(aux + 1, &end, 10); aux = end + 1; } @@ -2222,10 +2232,11 @@ static int cheevos_test_lboard_condition(const cheevos_condition_t* condition) return ret_val && ret_val_sub_cond; } -static unsigned cheevos_expr_value(cheevos_expr_t* expr) +static int cheevos_expr_value(cheevos_expr_t* expr) { cheevos_term_t* term = expr->terms; - unsigned i, value = 0; + unsigned i; + int value = 0; for (i = expr->count; i != 0; i--, term++) { @@ -2254,7 +2265,7 @@ static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, snprintf( url, url_size, - "http://retroachievements.org/dorequest.php?r=submitlbentry&u=%s&t=%s&i=%u&s=%u" + "http://retroachievements.org/dorequest.php?r=submitlbentry&u=%s&t=%s&i=%u&s=%d" "&v=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", settings->cheevos.username, cheevos_locals.token, lboard->id, lboard->last_value, @@ -2303,12 +2314,12 @@ static void cheevos_test_leaderboards(void) { if (lboard->active) { - unsigned value = cheevos_expr_value(&lboard->value); + int value = cheevos_expr_value(&lboard->value); if (value != lboard->last_value) { #ifdef CHEEVOS_VERBOSE - RARCH_LOG("CHEEVOS value %s %u\n", lboard->title, value); + RARCH_LOG("CHEEVOS value lboard %s %u\n", lboard->title, value); #endif lboard->last_value = value; } @@ -2320,12 +2331,12 @@ static void cheevos_test_leaderboards(void) cheevos_make_lboard_url(lboard, url, sizeof(url)); task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); - RARCH_LOG("CHEEVOS submit %s\n", lboard->title); + RARCH_LOG("CHEEVOS submit lboard %s\n", lboard->title); } if (cheevos_test_lboard_condition(&lboard->cancel)) { - RARCH_LOG("CHEEVOS cancel %s\n", lboard->title); + RARCH_LOG("CHEEVOS cancel lboard %s\n", lboard->title); lboard->active = 0; } } @@ -2333,9 +2344,9 @@ static void cheevos_test_leaderboards(void) { if (cheevos_test_lboard_condition(&lboard->start)) { - RARCH_LOG("CHEEVOS start %s\n", lboard->title); + RARCH_LOG("CHEEVOS start lboard %s\n", lboard->title); lboard->active = 1; - lboard->last_value = (unsigned)-1; + lboard->last_value = -1; } } } From bfcb8227f5fc869a95d2de5d3ea08d268585a330 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 5 Feb 2017 17:00:07 +0000 Subject: [PATCH 25/90] Fix typpo; parse constant values in leaderboards --- cheevos/cheevos.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index c66f828770..39be2afb93 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -447,7 +447,7 @@ static void cheevos_add_uint(char** aux, size_t* left, unsigned v) cheevos_add_string(aux, left, buffer); } -static void cheevos_add_uint(char** aux, size_t* left, int v) +static void cheevos_add_int(char** aux, size_t* left, int v) { char buffer[32]; @@ -1158,7 +1158,12 @@ static void cheevos_parse_var(cheevos_var_t *var, const char **memaddr) if (toupper(*str) == 'H') str++; else + { + if (toupper(*str) == 'V') + str++; + base = 10; + } } if (var->type != CHEEVOS_VAR_TYPE_VALUE_COMP) From 83619b25e63fdae6de2f2befd2c20c8188851309 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 5 Feb 2017 13:55:19 -0500 Subject: [PATCH 26/90] DOS: add keyboard driver to support non-joypad keys --- Makefile.common | 2 +- input/drivers/dos_input.c | 17 ++- input/drivers_joypad/dos_joypad.c | 85 +++++++----- input/drivers_keyboard/keyboard_event_dos.c | 56 ++++++++ input/drivers_keyboard/keyboard_event_dos.h | 137 ++++++++++++++++++++ input/input_keymaps.c | 98 ++++++++++++++ input/input_keymaps.h | 1 + 7 files changed, 356 insertions(+), 40 deletions(-) create mode 100644 input/drivers_keyboard/keyboard_event_dos.c create mode 100644 input/drivers_keyboard/keyboard_event_dos.h diff --git a/Makefile.common b/Makefile.common index bdceae0169..8be45a85e3 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1273,7 +1273,7 @@ endif ifneq ($(findstring DOS,$(OS)),) OBJ += gfx/drivers/vga_gfx.o gfx/drivers_font/vga_font.o \ input/drivers/dos_input.o input/drivers_joypad/dos_joypad.o \ - frontend/drivers/platform_dos.o + frontend/drivers/platform_dos.o input/drivers_keyboard/keyboard_event_dos.o ifeq ($(HAVE_MENU_COMMON), 1) OBJ += menu/drivers_display/menu_display_vga.o diff --git a/input/drivers/dos_input.c b/input/drivers/dos_input.c index e9b65ad98d..b73f0f73ab 100644 --- a/input/drivers/dos_input.c +++ b/input/drivers/dos_input.c @@ -14,16 +14,17 @@ * If not, see . */ +#include #include #include "../input_driver.h" +#include "../input_keymaps.h" #include "../input_joypad_driver.h" +#include "../drivers_keyboard/keyboard_event_dos.h" typedef struct dos_input { const input_device_driver_t *joypad; - unsigned char normal_keys[256]; - unsigned char extended_keys[256]; } dos_input_t; static void dos_input_poll(void *data) @@ -48,7 +49,10 @@ static int16_t dos_input_state(void *data, switch (device) { case RETRO_DEVICE_JOYPAD: - return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id); + return input_joypad_pressed(dos->joypad, joypad_info, port, binds[port], id) || + dos_keyboard_port_input_pressed(binds[port], id); + case RETRO_DEVICE_KEYBOARD: + return dos_keyboard_port_input_pressed(binds[port], id); } return 0; @@ -61,6 +65,8 @@ static void dos_input_free_input(void *data) if (dos && dos->joypad) dos->joypad->destroy(); + dos_keyboard_free(); + if (data) free(data); } @@ -72,8 +78,12 @@ static void* dos_input_init(const char *joypad_driver) if (!dos) return NULL; + dos_keyboard_free(); + dos->joypad = input_joypad_init_driver(joypad_driver, dos); + input_keymaps_init_keyboard_lut(rarch_key_map_dos); + return dos; } @@ -87,7 +97,6 @@ static uint64_t dos_input_get_capabilities(void *data) uint64_t caps = 0; caps |= UINT64_C(1) << RETRO_DEVICE_JOYPAD; - caps |= UINT64_C(1) << RETRO_DEVICE_KEYBOARD; return caps; } diff --git a/input/drivers_joypad/dos_joypad.c b/input/drivers_joypad/dos_joypad.c index 05f07b766d..686db8238e 100644 --- a/input/drivers_joypad/dos_joypad.c +++ b/input/drivers_joypad/dos_joypad.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -30,19 +29,17 @@ #include "../input_joypad_driver.h" #include "../input_driver.h" #include "../input_config.h" +#include "../input_keyboard.h" +#include "../input_keymaps.h" #include "../../tasks/tasks_internal.h" - -#define MAX_PADS 1 +#include "../drivers_keyboard/keyboard_event_dos.h" #define END_FUNC(x) static void x##_End() { } #define LOCK_VAR(x) LockData((void*)&x, sizeof(x)) #define LOCK_FUNC(x) LockCode(x, (int)x##_End - (int)x) -static uint64_t dos_key_state[MAX_PADS]; - -static unsigned char normal_keys[256]; -static unsigned char extended_keys[256]; +static uint16_t normal_keys[LAST_KEYCODE + 1]; static _go32_dpmi_seginfo old_kbd_int; static _go32_dpmi_seginfo kbd_int; @@ -85,7 +82,7 @@ int LockCode(void *a, int size) static void keyb_int(void) { - static unsigned char buffer; + static unsigned char buffer = 0; unsigned char rawcode; unsigned char make_break; int scancode; @@ -99,14 +96,14 @@ static void keyb_int(void) /* second byte of an extended key */ if (scancode < 0x60) { - extended_keys[scancode] = make_break; + normal_keys[scancode | (1 << 8)] = make_break; } buffer = 0; } else if (buffer >= 0xE1 && buffer <= 0xE2) { - buffer = 0; /* ingore these extended keys */ + buffer = 0; /* ignore these extended keys */ } else if (rawcode >= 0xE0 && rawcode <= 0xE2) { @@ -126,10 +123,10 @@ static void hook_keyb_int(void) _go32_dpmi_get_protected_mode_interrupt_vector(9, &old_kbd_int); memset(&kbd_int, 0, sizeof(kbd_int)); + memset(normal_keys, 0, sizeof(normal_keys)); LOCK_FUNC(keyb_int); LOCK_VAR(normal_keys); - LOCK_VAR(extended_keys); kbd_int.pm_selector = _go32_my_cs(); kbd_int.pm_offset = (uint32_t)&keyb_int; @@ -170,8 +167,6 @@ static void dos_joypad_autodetect_add(unsigned autoconf_pad) static bool dos_joypad_init(void *data) { - memset(dos_key_state, 0, sizeof(dos_key_state)); - hook_keyb_int(); dos_joypad_autodetect_add(0); @@ -183,44 +178,64 @@ static bool dos_joypad_init(void *data) static bool dos_joypad_button(unsigned port_num, uint16_t key) { + uint16_t *buf = dos_keyboard_state_get(port_num); + if (port_num >= MAX_PADS) return false; - return (dos_key_state[port_num] & (UINT64_C(1) << key)); -} + switch (key) + { + case RETRO_DEVICE_ID_JOYPAD_A: + return buf[DOSKEY_x]; + case RETRO_DEVICE_ID_JOYPAD_B: + return buf[DOSKEY_z]; + case RETRO_DEVICE_ID_JOYPAD_X: + return buf[DOSKEY_s]; + case RETRO_DEVICE_ID_JOYPAD_Y: + return buf[DOSKEY_a]; + case RETRO_DEVICE_ID_JOYPAD_SELECT: + return buf[DOSKEY_RSHIFT]; + case RETRO_DEVICE_ID_JOYPAD_START: + return buf[DOSKEY_RETURN]; + case RETRO_DEVICE_ID_JOYPAD_UP: + return buf[DOSKEY_UP]; + case RETRO_DEVICE_ID_JOYPAD_DOWN: + return buf[DOSKEY_DOWN]; + case RETRO_DEVICE_ID_JOYPAD_LEFT: + return buf[DOSKEY_LEFT]; + case RETRO_DEVICE_ID_JOYPAD_RIGHT: + return buf[DOSKEY_RIGHT]; + } -static uint64_t dos_joypad_get_buttons(unsigned port_num) -{ - if (port_num >= MAX_PADS) - return 0; - return dos_key_state[port_num]; + return false; } static void dos_joypad_poll(void) { uint32_t i; - for (i = 0; i < MAX_PADS; i++) + for (i = 0; i <= MAX_PADS; i++) { - uint64_t *cur_state = &dos_key_state[i]; + uint16_t *cur_state = dos_keyboard_state_get(i); + uint32_t key; - *cur_state = 0; - *cur_state |= extended_keys[75] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT : 0; - *cur_state |= extended_keys[77] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT : 0; - *cur_state |= extended_keys[72] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP : 0; - *cur_state |= extended_keys[80] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN : 0; - *cur_state |= normal_keys[28] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START : 0; /* ENTER */ - *cur_state |= normal_keys[54] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT : 0; /* RSHIFT */ - *cur_state |= normal_keys[44] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B : 0; /* Z */ - *cur_state |= normal_keys[45] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A : 0; /* X */ - *cur_state |= normal_keys[30] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y : 0; /* A */ - *cur_state |= normal_keys[31] ? UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X : 0; /* S */ + for (key = 0; key < LAST_KEYCODE; key++) + { + if (cur_state[key] != normal_keys[key]) + { + unsigned code = input_keymaps_translate_keysym_to_rk(key); + + input_keyboard_event(normal_keys[key], code, code, 0, RETRO_DEVICE_KEYBOARD); + } + } + + memcpy(cur_state, normal_keys, sizeof(normal_keys)); } } static bool dos_joypad_query_pad(unsigned pad) { - return pad < MAX_USERS && dos_key_state[pad]; + return (pad < MAX_USERS); } static int16_t dos_joypad_axis(unsigned port_num, uint32_t joyaxis) @@ -238,7 +253,7 @@ input_device_driver_t dos_joypad = { dos_joypad_query_pad, dos_joypad_destroy, dos_joypad_button, - dos_joypad_get_buttons, + NULL, dos_joypad_axis, dos_joypad_poll, NULL, diff --git a/input/drivers_keyboard/keyboard_event_dos.c b/input/drivers_keyboard/keyboard_event_dos.c new file mode 100644 index 0000000000..f7f8f373ef --- /dev/null +++ b/input/drivers_keyboard/keyboard_event_dos.c @@ -0,0 +1,56 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +#include "keyboard_event_dos.h" +#include "../input_keymaps.h" + +#define MAX_KEYS LAST_KEYCODE + 1 + +// First ports are used to keeping track of gamepad states. Last port is used for keyboard state +static uint16_t dos_key_state[MAX_PADS+1][MAX_KEYS]; + +bool dos_keyboard_port_input_pressed(const struct retro_keybind *binds, unsigned id) +{ + if (id < RARCH_BIND_LIST_END) + { + const struct retro_keybind *bind = &binds[id]; + unsigned key = input_keymaps_translate_rk_to_keysym(bind->key); + return dos_key_state[DOS_KEYBOARD_PORT][key]; + } + return false; +} + +bool dos_keyboard_input_pressed(unsigned key) +{ + unsigned keysym = input_keymaps_translate_rk_to_keysym(key); + return dos_key_state[DOS_KEYBOARD_PORT][keysym]; +} + +uint16_t *dos_keyboard_state_get(unsigned port) +{ + return dos_key_state[port]; +} + +void dos_keyboard_free(void) +{ + unsigned i, j; + + for (i = 0; i < MAX_PADS; i++) + for (j = 0; j < MAX_KEYS; j++) + dos_key_state[i][j] = 0; +} diff --git a/input/drivers_keyboard/keyboard_event_dos.h b/input/drivers_keyboard/keyboard_event_dos.h new file mode 100644 index 0000000000..0cecb85576 --- /dev/null +++ b/input/drivers_keyboard/keyboard_event_dos.h @@ -0,0 +1,137 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#ifndef _KEYBOARD_EVENT_DOS_H +#define _KEYBOARD_EVENT_DOS_H + +#include "../input_driver.h" + +/* + * Key codes. + */ +enum { + DOSKEY_ESCAPE = 0x1, + DOSKEY_F1 = 0x3b, + DOSKEY_F2 = 0x3c, + DOSKEY_F3 = 0x3d, + DOSKEY_F4 = 0x3e, + DOSKEY_F5 = 0x3f, + DOSKEY_F6 = 0x40, + DOSKEY_F7 = 0x41, + DOSKEY_F8 = 0x42, + DOSKEY_F9 = 0x43, + DOSKEY_F10 = 0x44, + + DOSKEY_BACKQUOTE = 0x29, + DOSKEY_1 = 0x2, + DOSKEY_2 = 0x3, + DOSKEY_3 = 0x4, + DOSKEY_4 = 0x5, + DOSKEY_5 = 0x6, + DOSKEY_6 = 0x7, + DOSKEY_7 = 0x8, + DOSKEY_8 = 0x9, + DOSKEY_9 = 0xa, + DOSKEY_0 = 0xb, + DOSKEY_MINUS = 0xc, + DOSKEY_EQUAL = 0xd, + DOSKEY_BACKSPACE = 0xe, + + DOSKEY_TAB = 0xf, + DOSKEY_q = 0x10, + DOSKEY_w = 0x11, + DOSKEY_e = 0x12, + DOSKEY_r = 0x13, + DOSKEY_t = 0x14, + DOSKEY_y = 0x15, + DOSKEY_u = 0x16, + DOSKEY_i = 0x17, + DOSKEY_o = 0x18, + DOSKEY_p = 0x19, + DOSKEY_LBRACKET = 0x1a, + DOSKEY_RBRACKET = 0x1b, + DOSKEY_BACKSLASH = 0x2b, + + DOSKEY_CAPSLOCK = 0x3a, + DOSKEY_a = 0x1e, + DOSKEY_s = 0x1f, + DOSKEY_d = 0x20, + DOSKEY_f = 0x21, + DOSKEY_g = 0x22, + DOSKEY_h = 0x23, + DOSKEY_j = 0x24, + DOSKEY_k = 0x25, + DOSKEY_l = 0x26, + DOSKEY_SEMICOLON = 0x27, + DOSKEY_QUOTE = 0x28, + DOSKEY_RETURN = 0x1c, + + DOSKEY_LSHIFT = 0x2a, + DOSKEY_z = 0x2c, + DOSKEY_x = 0x2d, + DOSKEY_c = 0x2e, + DOSKEY_v = 0x2f, + DOSKEY_b = 0x30, + DOSKEY_n = 0x31, + DOSKEY_m = 0x32, + DOSKEY_COMMA = 0x33, + DOSKEY_PERIOD = 0x34, + DOSKEY_SLASH = 0x35, + DOSKEY_RSHIFT = 0x36, + + DOSKEY_LCTRL = 0x1d, + DOSKEY_LSUPER = 0x15b, + DOSKEY_LALT = 0x38, + DOSKEY_SPACE = 0x39, + DOSKEY_RALT = 0x138, + DOSKEY_RSUPER = 0x15c, + DOSKEY_MENU = 0x15d, + DOSKEY_RCTRL = 0x11d, + + DOSKEY_UP = 0x148, + DOSKEY_DOWN = 0x150, + DOSKEY_LEFT = 0x14b, + DOSKEY_RIGHT = 0x14d, + + DOSKEY_HOME = 0x147, + DOSKEY_END = 0x14f, + DOSKEY_PGUP = 0x149, + DOSKEY_PGDN = 0x151, +}; + +#include + +#include + +#define LAST_KEYCODE 0x1ff + +#ifndef MAX_PADS +#define MAX_PADS 1 +#endif + +#define DOS_KEYBOARD_PORT MAX_PADS + +bool dos_keyboard_port_input_pressed(const struct retro_keybind *binds, unsigned id); + +bool dos_keyboard_input_pressed(unsigned key); + +uint16_t *dos_keyboard_state_get(unsigned port); + +void dos_keyboard_init(void); + +void dos_keyboard_free(void); + +#endif diff --git a/input/input_keymaps.c b/input/input_keymaps.c index a6317b254f..eb5566b851 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -32,6 +32,10 @@ #include "drivers_keyboard/keyboard_event_android.h" #endif +#ifdef DJGPP +#include "drivers_keyboard/keyboard_event_dos.h" +#endif + #ifdef __QNX__ #include #endif @@ -1311,6 +1315,100 @@ const struct rarch_key_map rarch_key_map_apple_hid[] = { }; #endif +#ifdef DJGPP +const struct rarch_key_map rarch_key_map_dos[] = { + { DOSKEY_ESCAPE, RETROK_ESCAPE }, + { DOSKEY_F1, RETROK_F1 }, + { DOSKEY_F2, RETROK_F2 }, + { DOSKEY_F3, RETROK_F3 }, + { DOSKEY_F4, RETROK_F4 }, + { DOSKEY_F5, RETROK_F5 }, + { DOSKEY_F6, RETROK_F6 }, + { DOSKEY_F7, RETROK_F7 }, + { DOSKEY_F8, RETROK_F8 }, + { DOSKEY_F9, RETROK_F9 }, + { DOSKEY_F10, RETROK_F10 }, + + { DOSKEY_BACKQUOTE, RETROK_BACKQUOTE }, + { DOSKEY_1, RETROK_1 }, + { DOSKEY_2, RETROK_2 }, + { DOSKEY_3, RETROK_3 }, + { DOSKEY_4, RETROK_4 }, + { DOSKEY_5, RETROK_5 }, + { DOSKEY_6, RETROK_6 }, + { DOSKEY_7, RETROK_7 }, + { DOSKEY_8, RETROK_8 }, + { DOSKEY_9, RETROK_9 }, + { DOSKEY_0, RETROK_0 }, + { DOSKEY_MINUS, RETROK_MINUS }, + { DOSKEY_EQUAL, RETROK_EQUALS }, + { DOSKEY_BACKSPACE, RETROK_BACKSPACE }, + + { DOSKEY_TAB, RETROK_TAB }, + { DOSKEY_q, RETROK_q }, + { DOSKEY_w, RETROK_w }, + { DOSKEY_e, RETROK_e }, + { DOSKEY_r, RETROK_r }, + { DOSKEY_t, RETROK_t }, + { DOSKEY_y, RETROK_y }, + { DOSKEY_u, RETROK_u }, + { DOSKEY_i, RETROK_i }, + { DOSKEY_o, RETROK_o }, + { DOSKEY_p, RETROK_p }, + { DOSKEY_LBRACKET, RETROK_LEFTBRACKET }, + { DOSKEY_RBRACKET, RETROK_RIGHTBRACKET }, + { DOSKEY_BACKSLASH, RETROK_BACKSLASH }, + + { DOSKEY_CAPSLOCK, RETROK_CAPSLOCK }, + { DOSKEY_a, RETROK_a }, + { DOSKEY_s, RETROK_s }, + { DOSKEY_d, RETROK_d }, + { DOSKEY_f, RETROK_f }, + { DOSKEY_g, RETROK_g }, + { DOSKEY_h, RETROK_h }, + { DOSKEY_j, RETROK_j }, + { DOSKEY_k, RETROK_k }, + { DOSKEY_l, RETROK_l }, + { DOSKEY_SEMICOLON, RETROK_SEMICOLON }, + { DOSKEY_QUOTE, RETROK_QUOTE }, + { DOSKEY_RETURN, RETROK_RETURN }, + + { DOSKEY_LSHIFT, RETROK_LSHIFT }, + { DOSKEY_z, RETROK_z }, + { DOSKEY_x, RETROK_x }, + { DOSKEY_c, RETROK_c }, + { DOSKEY_v, RETROK_v }, + { DOSKEY_b, RETROK_b }, + { DOSKEY_n, RETROK_n }, + { DOSKEY_m, RETROK_m }, + { DOSKEY_COMMA, RETROK_COMMA }, + { DOSKEY_PERIOD, RETROK_PERIOD }, + { DOSKEY_SLASH, RETROK_SLASH }, + { DOSKEY_RSHIFT, RETROK_RSHIFT }, + + { DOSKEY_LCTRL, RETROK_LCTRL }, + { DOSKEY_LSUPER, RETROK_LSUPER }, + { DOSKEY_LALT, RETROK_LALT }, + { DOSKEY_SPACE, RETROK_SPACE }, + { DOSKEY_RALT, RETROK_RALT }, + { DOSKEY_RSUPER, RETROK_RSUPER }, + { DOSKEY_MENU, RETROK_MENU }, + { DOSKEY_RCTRL, RETROK_RCTRL }, + + { DOSKEY_UP, RETROK_UP }, + { DOSKEY_DOWN, RETROK_DOWN }, + { DOSKEY_LEFT, RETROK_LEFT }, + { DOSKEY_RIGHT, RETROK_RIGHT }, + + { DOSKEY_HOME, RETROK_HOME }, + { DOSKEY_END, RETROK_END }, + { DOSKEY_PGUP, RETROK_PAGEUP }, + { DOSKEY_PGDN, RETROK_PAGEDOWN }, + + { 0, RETROK_UNKNOWN } +}; +#endif + static enum retro_key rarch_keysym_lut[RETROK_LAST]; /** diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 4e7b5dab32..6d7fc99892 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -57,6 +57,7 @@ extern const struct rarch_key_map rarch_key_map_linux[]; extern const struct rarch_key_map rarch_key_map_apple_hid[]; extern const struct rarch_key_map rarch_key_map_android[]; extern const struct rarch_key_map rarch_key_map_qnx[]; +extern const struct rarch_key_map rarch_key_map_dos[]; /** * input_keymaps_init_keyboard_lut: From 0bdcdac2dacdcdd559bd7ba0941d252026c845bc Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 5 Feb 2017 15:23:38 -0500 Subject: [PATCH 27/90] DOS: scale menu frame to fit screen --- gfx/drivers/vga_gfx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index 481cba965f..78a14d6dd4 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -368,7 +368,10 @@ static void vga_set_texture_frame(void *data, { for(x = 0; x < VGA_WIDTH; x++) { - unsigned short pixel = video_frame[width * y + x]; + /* scale incoming frame to fit the screen */ + unsigned scaled_x = (width / (float)VGA_WIDTH) * x; + unsigned scaled_y = (height / (float)VGA_HEIGHT) * y; + unsigned short pixel = video_frame[width * scaled_y + scaled_x]; unsigned r = (7.0f / 15.0f) * ((pixel & 0xF000) >> 12); unsigned g = (7.0f / 15.0f) * ((pixel & 0xF00) >> 8); unsigned b = (3.0f / 15.0f) * ((pixel & 0xF0) >> 4); From 6e5b7c3a7bc39e9e3690928bfd9bbe76480dd4ad Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Feb 2017 05:51:28 +0100 Subject: [PATCH 28/90] Fix relative includes --- cheevos/cheevos.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d7eb8c5e4e..54feeda363 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -27,22 +27,24 @@ #endif #ifdef HAVE_MENU -#include "menu/menu_driver.h" -#include "menu/menu_entries.h" +#include "../menu/menu_driver.h" +#include "../menu/menu_entries.h" #endif #include "cheevos.h" -#include "command.h" -#include "dynamic.h" -#include "network/net_http_special.h" -#include "tasks/tasks_internal.h" -#include "configuration.h" -#include "performance_counters.h" -#include "msg_hash.h" -#include "runloop.h" -#include "core.h" -#include "verbosity.h" +#include "../command.h" +#include "../dynamic.h" +#include "../configuration.h" +#include "../performance_counters.h" +#include "../msg_hash.h" +#include "../runloop.h" +#include "../core.h" + +#include "../network/net_http_special.h" +#include "../tasks/tasks_internal.h" + +#include "../verbosity.h" /* Define this macro to prevent cheevos from being deactivated. */ #undef CHEEVOS_DONT_DEACTIVATE From 52d46dcaf4bcdc5e33c0745c25312348249c0d19 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Feb 2017 05:51:51 +0100 Subject: [PATCH 29/90] Fix another relative include --- cheevos/cheevos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 54feeda363..8c7adc0fd9 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -23,7 +23,7 @@ #include #ifdef HAVE_CONFIG_H -#include "config.h" +#include "../config.h" #endif #ifdef HAVE_MENU From c7297d41b2f65385884dd4dbb6ec17f6b1bfb3b9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Feb 2017 05:55:25 +0100 Subject: [PATCH 30/90] Update Chinese --- intl/msg_hash_chs.c | 4279 ++++++++++++++++++++++++------------------- 1 file changed, 2399 insertions(+), 1880 deletions(-) diff --git a/intl/msg_hash_chs.c b/intl/msg_hash_chs.c index 1e618aaadc..8a87d5ba05 100644 --- a/intl/msg_hash_chs.c +++ b/intl/msg_hash_chs.c @@ -1,1881 +1,2400 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2017 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ +MSG_HASH( + MSG_COMPILER, + "???" + ) +MSG_HASH( + MSG_UNKNOWN_COMPILER, + "??????" + ) +MSG_HASH( + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "?????????" + ) +MSG_HASH( + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "????????????" + ) +MSG_HASH( + MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, + "??????????????" + ) +MSG_HASH( + MSG_GOT_CONNECTION_FROM, + "????? \"%s\"" + ) +MSG_HASH( + MSG_GOT_CONNECTION_FROM_NAME, + "????? \"%s (%s)\"" + ) +MSG_HASH( + MSG_PUBLIC_ADDRESS, + "????" + ) +MSG_HASH( + MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, + "?????????????????..." + ) +MSG_HASH( + MSG_NETPLAY_USERS_HAS_FLIPPED, + "??????????" + ) +MSG_HASH( + MSG_SETTING_DISK_IN_TRAY, + "Setting disk in tray" + ) +MSG_HASH( + MSG_WAITING_FOR_CLIENT, + "????? ..." + ) +MSG_HASH( + MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, + "??????" + ) +MSG_HASH( + MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, + "?????? %d ??" + ) +MSG_HASH( + MSG_NETPLAY_IMPLEMENTATIONS_DIFFER, + "?????????????RetroArch?????????" + ) +MSG_HASH( + MSG_NETPLAY_ENDIAN_DEPENDENT, + "This core does not support inter-architecture netplay between these systems" + ) +MSG_HASH( + MSG_NETPLAY_PLATFORM_DEPENDENT, + "This core does not support inter-architecture netplay" + ) +MSG_HASH( + MSG_NETPLAY_ENTER_PASSWORD, + "?????????????" + ) +MSG_HASH( + MSG_NETPLAY_INCORRECT_PASSWORD, + "????" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" ?????" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_HANGUP, + "????????????" + ) +MSG_HASH( + MSG_NETPLAY_CLIENT_HANGUP, + "???????" + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, + "???????" + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, + "??????" /*FIXME:"There are no free player slots"*/ + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY, + "?????????" + ) +MSG_HASH( + MSG_NETPLAY_PEER_PAUSED, + "?????? \"%s\" ??" + ) +MSG_HASH( + MSG_NETPLAY_CHANGED_NICK, + "???????? \"%s\"" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, + "Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SETTINGS, + "????????????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, + "????CPU?GPU?????????????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_THREADED, + "??????????????????????\n" + "??????????" + ) +MSG_HASH( + MSG_AUDIO_VOLUME, + "????" + ) +MSG_HASH( + MSG_AUTODETECT, + "????" + ) +MSG_HASH( + MSG_AUTOLOADING_SAVESTATE_FROM, + "???????" + ) +MSG_HASH( + MSG_CAPABILITIES, + "??" + ) +MSG_HASH( + MSG_CONNECTING_TO_NETPLAY_HOST, + "?????????" + ) +MSG_HASH( + MSG_CONNECTING_TO_PORT, + "?????" + ) +MSG_HASH( + MSG_CONNECTION_SLOT, + "?????" + ) +MSG_HASH( + MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, + "?????????????????????????" + ) +MSG_HASH( +MSG_FAILED_TO_SET_DISK, + "??????") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Cheevos??" /*FIXME:"Accounts Cheevos"*/ + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Retro ??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "????" + ) -#include -#include - -#include -#include - -#include "../msg_hash.h" -#include "../configuration.h" -#include "../verbosity.h" - -#if defined(_MSC_VER) && !defined(_XBOX) -/* https://support.microsoft.com/en-us/kb/980263 */ -#pragma execution_character_set("utf-8") -#pragma warning( disable : 4566 ) -#endif - -int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len) -{ - uint32_t driver_hash = 0; - settings_t *settings = config_get_ptr(); - - if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && - msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) - { - unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; - - switch (idx) - { - case RARCH_FAST_FORWARD_KEY: - snprintf(s, len, - "在快进和正常速度之间切换。" - ); - break; - case RARCH_FAST_FORWARD_HOLD_KEY: - snprintf(s, len, - "按住来快进。 \n" - " \n" - "放开按键来取消快进。" - ); - break; - case RARCH_PAUSE_TOGGLE: - snprintf(s, len, - "在暂停和不暂停状态间切换。"); - break; - case RARCH_FRAMEADVANCE: - snprintf(s, len, - "Frame advance when content is paused."); - break; - case RARCH_SHADER_NEXT: - snprintf(s, len, - "应用文件夹中的下一个Shader特效。"); - break; - case RARCH_SHADER_PREV: - snprintf(s, len, - "应用文件夹中的上一个Shader特效。"); - break; - case RARCH_CHEAT_INDEX_PLUS: - case RARCH_CHEAT_INDEX_MINUS: - case RARCH_CHEAT_TOGGLE: - snprintf(s, len, - "金手指。"); - break; - case RARCH_RESET: - snprintf(s, len, - "重置游戏内容。"); - break; - case RARCH_SCREENSHOT: - snprintf(s, len, - "截图。"); - break; - case RARCH_MUTE: - snprintf(s, len, - "静音/取消静音。"); - break; - case RARCH_OSK: - snprintf(s, len, - "显示/隐藏屏显键盘。"); - break; - case RARCH_NETPLAY_FLIP: - snprintf(s, len, - "Netplay flip users."); - break; - case RARCH_SLOWMOTION: - snprintf(s, len, - "按住并以慢动作运行。"); - break; - case RARCH_ENABLE_HOTKEY: - snprintf(s, len, - "启用其他热键. \n" - " \n" - "If this hotkey is bound to either\n" - "a keyboard, joybutton or joyaxis, \n" - "all other hotkeys will be enabled only \n" - "if this one is held at the same time. \n" - " \n" - "This is useful for RETRO_KEYBOARD centric \n" - "implementations which query a large area of \n" - "the keyboard, where it is not desirable that \n" - "hotkeys get in the way. \n" - " \n" - "Alternatively, all hotkeys for keyboard \n" - "could be disabled by the user."); - break; - case RARCH_VOLUME_UP: - snprintf(s, len, - "提高音量。"); - break; - case RARCH_VOLUME_DOWN: - snprintf(s, len, - "降低音量。"); - break; - case RARCH_OVERLAY_NEXT: - snprintf(s, len, - "切换到下一个屏幕覆层。将会循环选择。"); - break; - case RARCH_DISK_EJECT_TOGGLE: - snprintf(s, len, - "切换弹出光盘。 \n" - " \n" - "用于多光盘内容。 "); - break; - case RARCH_DISK_NEXT: - case RARCH_DISK_PREV: - snprintf(s, len, - "磁盘镜像周期。弹出后使用。 \n" - " \n" - "再次开关弹出完成。"); - break; - case RARCH_GRAB_MOUSE_TOGGLE: - snprintf(s, len, - "鼠标捕获开关 \n" - " \n" - "当鼠标捕获开启时,RetroArch将会隐藏鼠标指针,并 \n" - "使之控制在窗口中。这使得一些依靠鼠标相对位置的程 \n" - "序能更好运行。"); - break; - case RARCH_MENU_TOGGLE: - snprintf(s, len, "切换菜单显示。"); - break; - case RARCH_LOAD_STATE_KEY: - snprintf(s, len, - "加载游戏状态。"); - break; - case RARCH_FULLSCREEN_TOGGLE_KEY: - snprintf(s, len, - "切换到全屏模式。"); - break; - case RARCH_QUIT_KEY: - snprintf(s, len, - "用于正常退出 RetroArch 的按键 \n" - " \n" - "使用任何强制手段来退出RetroArch(如发送SIGKILL) \n" - "可能导致系统无法正确存储数据。" -#ifdef __unix__ - "\n在类Unix系统上,SIGINT/SIGTERM信号能够保证正常 \n" - "关闭程序。" -#endif - ""); - break; - case RARCH_STATE_SLOT_PLUS: - case RARCH_STATE_SLOT_MINUS: - snprintf(s, len, - "状态存储槽 \n" - " \n" - "当槽位选择为0时,状态存档将以*.state命名(或其他 \n" - "在命令行中定义的名称)。 \n" - " \n" - "当状态槽不为0时,路径将会设为,其中 \n" - "是状态槽的索引。"); - break; - case RARCH_SAVE_STATE_KEY: - snprintf(s, len, - "保存游戏状态。"); - break; - case RARCH_REWIND: - snprintf(s, len, - "按住按钮来回溯 \n" - " \n" - "回溯功能必须被启用。"); - break; - case RARCH_MOVIE_RECORD_TOGGLE: - snprintf(s, len, - "在录制和非录制模式切换。"); - break; - default: - if (string_is_empty(s)) - strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); - break; - } - - return 0; - } - - switch (msg) - { - case MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS: - snprintf(s, len, "你的登陆信息 \n" - "Retro Achievements 账号. \n" - " \n" - "访问 retroachievements.org 并注册 \n" - "以获取一个免费账号. \n" - " \n" - "在你注册以后, 你需要 \n" - "在RetroArch输入你的 \n" - "账号以及密码."); - break; - case MENU_ENUM_LABEL_CHEEVOS_USERNAME: - snprintf(s, len, "你的Retro Achievements账号的用户名。"); - break; - case MENU_ENUM_LABEL_CHEEVOS_PASSWORD: - snprintf(s, len, "你的Retro Achievements账号的密码。"); - break; - case MENU_ENUM_LABEL_USER_LANGUAGE: - snprintf(s, len, "依据选择的语言来本地化菜单和其他屏显消息。 \n" - " \n" - "需要重新启动来使之生效。 \n" - " \n" - "注意:可能不是所有的语言都已完成翻译工作。 \n" - " \n" - "若一个语言没有被翻译,则会退回到英语显示。"); - break; - case MENU_ENUM_LABEL_VIDEO_FONT_PATH: - snprintf(s, len, "改变屏显文字的字体。"); - break; - case MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS: - snprintf(s, len, "自动加载游戏内容指定的核心选项."); - break; - case MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE: - snprintf(s, len, "自动加载覆盖配置。"); - break; - case MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE: - snprintf(s, len, "自动加载输入重映射文件."); - break; - case MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE: - snprintf(s, len, "Sort save states in folders \n" - "named after the libretro core used."); - break; - case MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE: - snprintf(s, len, "Sort save files in folders \n" - "named after the libretro core used."); - break; - case MENU_ENUM_LABEL_RESUME_CONTENT: - snprintf(s, len, "Exits from the menu and returns back \n" - "to the content."); - break; - case MENU_ENUM_LABEL_RESTART_CONTENT: - snprintf(s, len, "Restarts the content from the beginning."); - break; - case MENU_ENUM_LABEL_CLOSE_CONTENT: - snprintf(s, len, "关闭内容并从内存中卸载。"); - break; - case MENU_ENUM_LABEL_UNDO_LOAD_STATE: - snprintf(s, len, "If a state was loaded, content will \n" - "go back to the state prior to loading."); - break; - case MENU_ENUM_LABEL_UNDO_SAVE_STATE: - snprintf(s, len, "如果状态被覆盖,它将 \n" - "它将回滚到上一保存的状态。"); - break; - case MENU_ENUM_LABEL_TAKE_SCREENSHOT: - snprintf(s, len, "创建一份截图. \n" - " \n" - "截图文件将会存放在 \n" - "截图目录之中."); - break; - case MENU_ENUM_LABEL_RUN: - snprintf(s, len, "启动内容."); - break; - case MENU_ENUM_LABEL_INFORMATION: - snprintf(s, len, "显示本内容的额外 \n" - "元数据信息."); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_CONFIG: - snprintf(s, len, "配置文件."); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE: - snprintf(s, len, "压缩归档文件."); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_RECORD_CONFIG: - snprintf(s, len, "记录配置文件."); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_CURSOR: - snprintf(s, len, "数据库指针文件。"); - break; - case MENU_ENUM_LABEL_FILE_CONFIG: - snprintf(s, len, "配置文件."); - break; - case MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY: - snprintf(s, len, - "选择本项以扫描当前 \n" - "目录中的内容."); - break; - case MENU_ENUM_LABEL_USE_THIS_DIRECTORY: - snprintf(s, len, - "选择本目录作为指定目录."); - break; - case MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY: - snprintf(s, len, - "内容数据库目录。 \n" - " \n" - "到内容数据库目录的 \n" - "路径。"); - break; - case MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY: - snprintf(s, len, - "缩略图目录. \n" - " \n" - "用以存放缩略图."); - break; - case MENU_ENUM_LABEL_LIBRETRO_INFO_PATH: - snprintf(s, len, - "核心Core信息目录. \n" - " \n" - "用于搜索libretro核心信息 \n" - "的目录。"); - break; - case MENU_ENUM_LABEL_PLAYLIST_DIRECTORY: - snprintf(s, len, - "运行列表目录. \n" - " \n" - "保存所有播放列表到 \n" - "此目录。"); - break; - case MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN: - snprintf(s, len, - "某些libretro核心可能会 \n" - "支持关机特性. \n" - " \n" - "If this option is left disabled, \n" - "selecting the shutdown procedure \n" - "would trigger RetroArch being shut \n" - "down. \n" - " \n" - "Enabling this option will load a \n" - "dummy core instead so that we remain \n" - "inside the menu and RetroArch won't \n" - "shutdown."); - break; - case MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE: - snprintf(s, len, - "Some cores might need \n" - "firmware or bios files. \n" - " \n" - "If this option is disabled, \n" - "it will try to load even if such \n" - "firmware is missing. \n" - "down. \n"); - break; - case MENU_ENUM_LABEL_PARENT_DIRECTORY: - snprintf(s, len, - "回到上级目录。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_SHADER_PRESET: - snprintf(s, len, - "Shader预设文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_SHADER: - snprintf(s, len, - "Shader文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_REMAP: - snprintf(s, len, - "控制重映射文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_CHEAT: - snprintf(s, len, - "金手指文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY: - snprintf(s, len, - "覆层文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_RDB: - snprintf(s, len, - "数据库文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_FONT: - snprintf(s, len, - "TrueType字体文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE: - snprintf(s, len, - "普通文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN: - snprintf(s, len, - "视频 \n" - " \n" - "选择文件并使用视频播放器打开。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN: - snprintf(s, len, - "音乐 \n" - " \n" - "选择文件并使用音乐播放器打开。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE: - snprintf(s, len, - "图片文件。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER: - snprintf(s, len, - "图片 \n" - " \n" - "选择文件并使用图片浏览器打开。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION: - snprintf(s, len, - "Libretro核心 \n" - " \n" - "选中核心将会使其关联至游戏。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_CORE: - snprintf(s, len, - "Libretro核心 \n" - " \n" - "选择该文件使 RetroArch 加载该核心。"); - break; - case MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY: - snprintf(s, len, - "目录 \n" - " \n" - "选择并打开该文件夹。"); - break; - case MENU_ENUM_LABEL_CACHE_DIRECTORY: - snprintf(s, len, - "缓存目录 \n" - " \n" - "被RetroArch解压的游戏内容会临时存放到这个文 \n" - "件夹。"); - break; - case MENU_ENUM_LABEL_HISTORY_LIST_ENABLE: - snprintf(s, len, - "若开启,所有在RetroArch中加载过的文件 \n" - "都会自动的放入最近使用历史列表中。"); - break; - case MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY: - snprintf(s, len, - "文件浏览器目录 \n" - " \n" - "设置文件浏览器的初始目录。"); - break; - case MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR: - snprintf(s, len, - "影响输入轮询过程在RetroArch中的执行方式。 \n" - " \n" - "稍早 - 输入轮询过程将在帧生成之前执行。 \n" - "正常 - 输入轮询过程将在被请求时执行。 \n" - "稍晚 - 输入轮询过程将在每一帧的首次请求时执行。 \n" - " \n" - "依据设置的不同,设置为“稍早”或“稍晚”可以获得较低 \n" - "的时延。 \n" - "当在进行在线游戏时,不管设置的值如何,都只会启用 \n" - "正常模式进行输入轮询过程。" - ); - break; - case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_HIDE_UNBOUND: - snprintf(s, len, - "隐藏不被核心使用的输入描述。"); - break; - case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE: - snprintf(s, len, - "显示器的视频刷新率。 \n" - "可被用来计算一个合适的音频输入率。"); - break; - case MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE: - snprintf(s, len, - "强制关闭sRGB帧缓冲支持。\n" - "\n" - "某些在Windows上的Intel的OpenGL驱动会对sRGB帧缓 \n" - "冲支持产生问题,需要启用以强制关闭程序对其的使用。"); - break; - case MENU_ENUM_LABEL_AUDIO_ENABLE: - snprintf(s, len, - "启用音频输出。"); - break; - case MENU_ENUM_LABEL_AUDIO_SYNC: - snprintf(s, len, - "同步音频(推荐)。"); - break; - case MENU_ENUM_LABEL_AUDIO_LATENCY: - snprintf(s, len, - "Desired audio latency in milliseconds. \n" - "Might not be honored if the audio driver \n" - "can't provide given latency."); - break; - case MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE: - snprintf(s, len, - "Allow cores to set rotation. If false, \n" - "rotation requests are honored, but ignored.\n\n" - "Used for setups where one manually rotates \n" - "the monitor."); - break; - case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_LABEL_SHOW: - snprintf(s, len, - "Show the input descriptors set by the core \n" - "instead of the default ones."); - break; - case MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE: - snprintf(s, len, - "Number of entries that will be kept in \n" - "content history playlist."); - break; - case MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN: - snprintf(s, len, - "To use windowed mode or not when going \n" - "fullscreen."); - break; - case MENU_ENUM_LABEL_VIDEO_FONT_SIZE: - snprintf(s, len, - "屏显信息的字体大小."); - break; - case MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX: - snprintf(s, len, - "Automatically increment slot index on each save, \n" - "generating multiple savestate files. \n" - "When the content is loaded, state slot will be \n" - "set to the highest existing value (last savestate)."); - break; - case MENU_ENUM_LABEL_FPS_SHOW: - snprintf(s, len, - "Enables displaying the current frames \n" - "per second."); - break; - case MENU_ENUM_LABEL_VIDEO_FONT_ENABLE: - snprintf(s, len, - "显示/隐藏屏显信息."); - break; - case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X: - case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y: - snprintf(s, len, - "Offset for where messages will be placed \n" - "onscreen. Values are in range [0.0, 1.0]."); - break; - case MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE: - snprintf(s, len, - "Enable or disable the current overlay."); - break; - case MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU: - snprintf(s, len, - "Hide the current overlay from appearing \n" - "inside the menu."); - break; - case MENU_ENUM_LABEL_OVERLAY_PRESET: - snprintf(s, len, - "Path to input overlay."); - break; - case MENU_ENUM_LABEL_OVERLAY_OPACITY: - snprintf(s, len, - "Overlay opacity."); - break; - case MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT: - snprintf(s, len, - "Input bind timer timeout (in seconds). \n" - "Amount of seconds to wait until proceeding \n" - "to the next bind."); - break; - case MENU_ENUM_LABEL_OVERLAY_SCALE: - snprintf(s, len, - "Overlay scale."); - break; - case MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE: - snprintf(s, len, - "音频输出采样率."); - break; - case MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT: - snprintf(s, len, - "Set to true if hardware-rendered cores \n" - "should get their private context. \n" - "Avoids having to assume hardware state changes \n" - "inbetween frames." - ); - break; - case MENU_ENUM_LABEL_CORE_LIST: - snprintf(s, len, - "加载内核. \n" - " \n" - "Browse for a libretro core \n" - "implementation. Where the browser \n" - "starts depends on your Core Directory \n" - "path. If blank, it will start in root. \n" - " \n" - "If Core Directory is a directory, the menu \n" - "will use that as top folder. If Core \n" - "Directory is a full path, it will start \n" - "in the folder where the file is."); - break; - case MENU_ENUM_LABEL_VALUE_MENU_ENUM_CONTROLS_PROLOG: - snprintf(s, len, - "你可以使用下述的方式通过游戏控制器或者键盘来对\n" - "菜单进行控制:\n" - " \n" - ); - break; - case MENU_ENUM_LABEL_WELCOME_TO_RETROARCH: - snprintf(s, len, - "欢迎来到 RetroArch\n" - ); - break; - case MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING_DESC: - { - /* Work around C89 limitations */ - char u[501]; - const char * t = - "RetroArch relies on an unique form of\n" - "audio/video synchronization where it needs to be\n" - "calibrated against the refresh rate of your\n" - "display for best performance results.\n" - " \n" - "If you experience any audio crackling or video\n" - "tearing, usually it means that you need to\n" - "calibrate the settings. Some choices below:\n" - " \n"; - snprintf(u, sizeof(u), /* can't inline this due to the printf arguments */ - "a) Go to '%s' -> '%s', and enable\n" - "'Threaded Video'. Refresh rate will not matter\n" - "in this mode, framerate will be higher,\n" - "but video might be less smooth.\n" - "b) Go to '%s' -> '%s', and look at\n" - "'%s'. Let it run for\n" - "2048 frames, then press 'OK'.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO)); - strlcpy(s, t, len); - strlcat(s, u, len); - } - break; - case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: - snprintf(s, len, - "若要扫描游戏内容,请访问菜单「%s」 \n" - "并选择「%s」或者「%s」。\n" - " \n" - "文件将会同数据库中的条目进行对比。 \n" - "若文件匹配某个条目,则它会被加入收藏中。 \n" - " \n" - "你可以无需每次都打开文件浏览器,而可以直接 \n" - "通过菜单项「%s」->「%s」 来访\n" - "问这些游戏内容。 \n" - " \n" - "注意:不是所有核心的游戏内容都支持扫描录入。" - , - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) - ); - break; - case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: - snprintf(s, len, - "欢迎使用RetroArch\n" - "\n" - "正在解压必要文件, 请稍等。\n" - "这可能需要一点时间……\n" - ); - break; - case MENU_ENUM_LABEL_INPUT_DRIVER: - if (settings) - driver_hash = msg_hash_calculate(settings->input.driver); - - switch (driver_hash) - { - case MENU_LABEL_INPUT_DRIVER_UDEV: - snprintf(s, len, - "udev Input driver. \n" - " \n" - "This driver can run without X. \n" - " \n" - "It uses the recent evdev joypad API \n" - "for joystick support. It supports \n" - "hotplugging and force feedback (if \n" - "supported by device). \n" - " \n" - "The driver reads evdev events for keyboard \n" - "support. It also supports keyboard callback, \n" - "mice and touchpads. \n" - " \n" - "By default in most distros, /dev/input nodes \n" - "are root-only (mode 600). You can set up a udev \n" - "rule which makes these accessible to non-root." - ); - break; - case MENU_LABEL_INPUT_DRIVER_LINUXRAW: - snprintf(s, len, - "linuxraw Input driver. \n" - " \n" - "This driver requires an active TTY. Keyboard \n" - "events are read directly from the TTY which \n" - "makes it simpler, but not as flexible as udev. \n" "Mice, etc, are not supported at all. \n" - " \n" - "This driver uses the older joystick API \n" - "(/dev/input/js*)."); - break; - default: - snprintf(s, len, - "Input driver.\n" - " \n" - "Depending on video driver, it might \n" - "force a different input driver."); - break; - } - break; - case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: - snprintf(s, len, - "加载游戏内容 \n" - "通过浏览来加载游戏内容。 \n" - " \n" - "你需要同时提供一个“核心”和游戏内容文 \n" - "件才能启动并加载游戏内容。 \n" - " \n" - "设置“文件浏览器目录”可以指定以哪个位 \n" - "置为文件浏览器的默认目录以方便加载。 \n" - "若没有设置,默认以根目录为基准。 \n" - " \n" - "文件浏览器会以上次加载的核心所支持的 \n" - "扩展名进行过滤,并使用该核心来加载游 \n" - "戏内容。" - ); - break; - case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY: - snprintf(s, len, - "从历史记录中加载内容. \n" - " \n" - "As content is loaded, content and libretro \n" - "core combinations are saved to history. \n" - " \n" - "The history is saved to a file in the same \n" - "directory as the RetroArch config file. If \n" - "no config file was loaded in startup, history \n" - "will not be saved or loaded, and will not exist \n" - "in the main menu." - ); - break; - case MENU_ENUM_LABEL_VIDEO_DRIVER: - snprintf(s, len, - "当前视频驱动."); - - if (string_is_equal(settings->video.driver, "gl")) - { - snprintf(s, len, - "OpenGL视频驱动. \n" - " \n" - "This driver allows libretro GL cores to \n" - "be used in addition to software-rendered \n" - "core implementations.\n" - " \n" - "Performance for software-rendered and \n" - "libretro GL core implementations is \n" - "dependent on your graphics card's \n" - "underlying GL driver)."); - } - else if (string_is_equal(settings->video.driver, "sdl2")) - { - snprintf(s, len, - "SDL 2 视频驱动.\n" - " \n" - "This is an SDL 2 software-rendered video \n" - "driver.\n" - " \n" - "Performance for software-rendered libretro \n" - "core implementations is dependent \n" - "on your platform SDL implementation."); - } - else if (string_is_equal(settings->video.driver, "sdl1")) - { - snprintf(s, len, - "SDL 视频驱动.\n" - " \n" - "This is an SDL 1.2 software-rendered video \n" - "driver.\n" - " \n" - "Performance is considered to be suboptimal. \n" - "Consider using it only as a last resort."); - } - else if (string_is_equal(settings->video.driver, "d3d")) - { - snprintf(s, len, - "Direct3D 视频驱动. \n" - " \n" - "Performance for software-rendered cores \n" - "is dependent on your graphic card's \n" - "underlying D3D driver)."); - } - else if (string_is_equal(settings->video.driver, "exynos")) - { - snprintf(s, len, - "Exynos-G2D 视频驱动. \n" - " \n" - "This is a low-level Exynos video driver. \n" - "Uses the G2D block in Samsung Exynos SoC \n" - "for blit operations. \n" - " \n" - "Performance for software rendered cores \n" - "should be optimal."); - } - else if (string_is_equal(settings->video.driver, "drm")) - { - snprintf(s, len, - "Plain DRM 视频驱动. \n" - " \n" - "This is a low-level video driver using. \n" - "libdrm for hardware scaling using \n" - "GPU overlays."); - } - else if (string_is_equal(settings->video.driver, "sunxi")) - { - snprintf(s, len, - "Sunxi-G2D 视频驱动. \n" - " \n" - "This is a low-level Sunxi video driver. \n" - "Uses the G2D block in Allwinner SoCs."); - } - break; - case MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN: - snprintf(s, len, - "音频DSP插件.\n" - " Processes audio before it's sent to \n" - "the driver." - ); - break; - case MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER: - if (settings) - driver_hash = msg_hash_calculate(settings->audio.resampler); - - switch (driver_hash) - { - case MENU_LABEL_AUDIO_RESAMPLER_DRIVER_SINC: - snprintf(s, len, - "Windowed SINC implementation."); - break; - case MENU_LABEL_AUDIO_RESAMPLER_DRIVER_CC: - snprintf(s, len, - "Convoluted Cosine implementation."); - break; - default: - if (string_is_empty(s)) - strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); - break; - } - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET: - snprintf(s, len, - "载入预设 Shader. \n" - " \n" - " Load a " -#ifdef HAVE_CG - "Cg" -#endif -#ifdef HAVE_GLSL -#ifdef HAVE_CG - "/" -#endif - "GLSL" -#endif -#ifdef HAVE_HLSL -#if defined(HAVE_CG) || defined(HAVE_HLSL) - "/" -#endif - "HLSL" -#endif - " 预设目录. \n" - "The menu shader menu is updated accordingly. \n" - " \n" - "If the CGP uses scaling methods which are not \n" - "simple, (i.e. source scaling, same scaling \n" - "factor for X/Y), the scaling factor displayed \n" - "in the menu might not be correct." - ); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_SCALE_PASS: - snprintf(s, len, - "Scale for this pass. \n" - " \n" - "The scale factor accumulates, i.e. 2x \n" - "for first pass and 2x for second pass \n" - "will give you a 4x total scale. \n" - " \n" - "If there is a scale factor for last \n" - "pass, the result is stretched to \n" - "screen with the filter specified in \n" - "'Default Filter'. \n" - " \n" - "If 'Don't Care' is set, either 1x \n" - "scale or stretch to fullscreen will \n" - "be used depending if it's not the last \n" - "pass or not." - ); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: - snprintf(s, len, - "Shader Passes. \n" - " \n" - "RetroArch allows you to mix and match various \n" - "shaders with arbitrary shader passes, with \n" - "custom hardware filters and scale factors. \n" - " \n" - "This option specifies the number of shader \n" - "passes to use. If you set this to 0, and use \n" - "Apply Shader Changes, you use a 'blank' shader. \n" - " \n" - "The Default Filter option will affect the \n" - "stretching filter."); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_PARAMETERS: - snprintf(s, len, - "Shader Parameters. \n" - " \n" - "Modifies current shader directly. Will not be \n" - "saved to CGP/GLSLP preset file."); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_PARAMETERS: - snprintf(s, len, - "Shader Preset Parameters. \n" - " \n" - "Modifies shader preset currently in menu." - ); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_PASS: - snprintf(s, len, - "Path to shader. \n" - " \n" - "All shaders must be of the same \n" - "type (i.e. CG, GLSL or HLSL). \n" - " \n" - "Set Shader Directory to set where \n" - "the browser starts to look for \n" - "shaders." - ); - break; - case MENU_ENUM_LABEL_CONFIGURATION_SETTINGS: - snprintf(s, len, - "Determines how configuration files \n" - "are loaded and prioritized."); - break; - case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: - snprintf(s, len, - "Saves config to disk on exit.\n" - "Useful for menu as settings can be\n" - "modified. Overwrites the config.\n" - " \n" - "#include's and comments are not \n" - "preserved. \n" - " \n" - "By design, the config file is \n" - "considered immutable as it is \n" - "likely maintained by the user, \n" - "and should not be overwritten \n" - "behind the user's back." -#if defined(RARCH_CONSOLE) || defined(RARCH_MOBILE) - "\nThis is not not the case on \n" - "consoles however, where \n" - "looking at the config file \n" - "manually isn't really an option." -#endif - ); - break; - case MENU_ENUM_LABEL_SHOW_HIDDEN_FILES: - snprintf(s, len, "显示隐藏文件和文件夹。"); - break; - case MENU_ENUM_LABEL_VIDEO_SHADER_FILTER_PASS: - snprintf(s, len, - "Hardware filter for this pass. \n" - " \n" - "If 'Don't Care' is set, 'Default \n" - "Filter' will be used." - ); - break; - case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL: - snprintf(s, len, - "Autosaves the non-volatile SRAM \n" - "at a regular interval.\n" - " \n" - "This is disabled by default unless set \n" - "otherwise. The interval is measured in \n" - "seconds. \n" - " \n" - "A value of 0 disables autosave."); - break; - case MENU_ENUM_LABEL_INPUT_BIND_DEVICE_TYPE: - snprintf(s, len, - "输入设备类型. \n" - " \n" - "Picks which device type to use. This is \n" - "relevant for the libretro core itself." - ); - break; - case MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL: - snprintf(s, len, - "设置libretro核心的log等级 \n" - "(GET_LOG_INTERFACE). \n" - " \n" - " If a log level issued by a libretro \n" - " core is below libretro_log level, it \n" - " is ignored.\n" - " \n" - " DEBUG logs are always ignored unless \n" - " verbose mode is activated (--verbose).\n" - " \n" - " DEBUG = 0\n" - " INFO = 1\n" - " WARN = 2\n" - " ERROR = 3" - ); - break; - case MENU_ENUM_LABEL_STATE_SLOT_INCREASE: - case MENU_ENUM_LABEL_STATE_SLOT_DECREASE: - snprintf(s, len, - "即时存档栏位.\n" - " \n" - " With slot set to 0, save state name is *.state \n" - " (or whatever defined on commandline).\n" - "When slot is != 0, path will be (path)(d), \n" - "where (d) is slot number."); - break; - case MENU_ENUM_LABEL_SHADER_APPLY_CHANGES: - snprintf(s, len, - "应用Shader更改. \n" - " \n" - "After changing shader settings, use this to \n" - "apply changes. \n" - " \n" - "Changing shader settings is a somewhat \n" - "expensive operation so it has to be \n" - "done explicitly. \n" - " \n" - "When you apply shaders, the menu shader \n" - "settings are saved to a temporary file (either \n" - "menu.cgp or menu.glslp) and loaded. The file \n" - "persists after RetroArch exits. The file is \n" - "saved to Shader Directory." - ); - break; - case MENU_ENUM_LABEL_MENU_TOGGLE: - snprintf(s, len, - "切换菜单."); - break; - case MENU_ENUM_LABEL_GRAB_MOUSE_TOGGLE: - snprintf(s, len, - "切换鼠标抓取.\n" - " \n" - "When mouse is grabbed, RetroArch hides the \n" - "mouse, and keeps the mouse pointer inside \n" - "the window to allow relative mouse input to \n" - "work better."); - break; - case MENU_ENUM_LABEL_DISK_NEXT: - snprintf(s, len, - "Cycles through disk images. Use after \n" - "ejecting. \n" - " \n" - " Complete by toggling eject again."); - break; - case MENU_ENUM_LABEL_VIDEO_FILTER: -#ifdef HAVE_FILTERS_BUILTIN - snprintf(s, len, - "CPU-based video filter."); -#else - snprintf(s, len, - "CPU-based video filter.\n" - " \n" - "Path to a dynamic library."); -#endif - break; - case MENU_ENUM_LABEL_AUDIO_DEVICE: - snprintf(s, len, - "Override the default audio device \n" - "the audio driver uses.\n" - "This is driver dependent. E.g.\n" -#ifdef HAVE_ALSA - " \n" - "ALSA 需要一个PCM设备." -#endif -#ifdef HAVE_OSS - " \n" - "OSS 需要一个路径 (例如. /dev/dsp)." -#endif -#ifdef HAVE_JACK - " \n" - "JACK wants portnames (e.g. system:playback1\n" - ",system:playback_2)." -#endif -#ifdef HAVE_RSOUND - " \n" - "RSound wants an IP address to an RSound \n" - "server." -#endif - ); - break; - case MENU_ENUM_LABEL_DISK_EJECT_TOGGLE: - snprintf(s, len, - "Toggles eject for disks.\n" - " \n" - "Used for multiple-disk content."); - break; - case MENU_ENUM_LABEL_ENABLE_HOTKEY: - snprintf(s, len, - "启用其他热键.\n" - " \n" - " If this hotkey is bound to either keyboard, \n" - "joybutton or joyaxis, all other hotkeys will \n" - "be disabled unless this hotkey is also held \n" - "at the same time. \n" - " \n" - "This is useful for RETRO_KEYBOARD centric \n" - "implementations which query a large area of \n" - "the keyboard, where it is not desirable that \n" - "hotkeys get in the way."); - break; - case MENU_ENUM_LABEL_REWIND_ENABLE: - snprintf(s, len, - "启用回溯倒带功能.\n" - " \n" - "这可能会严重影响性能, \n" - "所以缺省设置为关闭."); - break; - case MENU_ENUM_LABEL_LIBRETRO_DIR_PATH: - snprintf(s, len, - "核心目录. \n" - " \n" - "A directory for where to search for \n" - "libretro core implementations."); - break; - case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: - snprintf(s, len, - "自动匹配刷新率.\n" - " \n" - "The accurate refresh rate of our monitor (Hz).\n" - "This is used to calculate audio input rate with \n" - "the formula: \n" - " \n" - "audio_input_rate = game input rate * display \n" - "refresh rate / game refresh rate\n" - " \n" - "If the implementation does not report any \n" - "values, NTSC defaults will be assumed for \n" - "compatibility.\n" - " \n" - "This value should stay close to 60Hz to avoid \n" - "large pitch changes. If your monitor does \n" - "not run at 60Hz, or something close to it, \n" - "disable VSync, and leave this at its default."); - break; - case MENU_ENUM_LABEL_VIDEO_ROTATION: - snprintf(s, len, - "Forces a certain rotation \n" - "of the screen.\n" - " \n" - "The rotation is added to rotations which\n" - "the libretro core sets (see Video Allow\n" - "Rotate)."); - break; - case MENU_ENUM_LABEL_VIDEO_SCALE: - snprintf(s, len, - "全屏分辨率.\n" - " \n" - "Resolution of 0 uses the \n" - "resolution of the environment.\n"); - break; - case MENU_ENUM_LABEL_FASTFORWARD_RATIO: - snprintf(s, len, - "快进比率." - " \n" - "The maximum rate at which content will\n" - "be run when using fast forward.\n" - " \n" - " (E.g. 5.0 for 60 fps content => 300 fps \n" - "cap).\n" - " \n" - "RetroArch will go to sleep to ensure that \n" - "the maximum rate will not be exceeded.\n" - "Do not rely on this cap to be perfectly \n" - "accurate."); - break; - case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: - snprintf(s, len, - "指定输出显示器.\n" - " \n" - "0 (default) means no particular monitor \n" - "is preferred, 1 and up (1 being first \n" - "monitor), suggests RetroArch to use that \n" - "particular monitor."); - break; - case MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN: - snprintf(s, len, - "Forces cropping of overscanned \n" - "frames.\n" - " \n" - "Exact behavior of this option is \n" - "core-implementation specific."); - break; - case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: - snprintf(s, len, - "Only scales video in integer \n" - "steps.\n" - " \n" - "The base size depends on system-reported \n" - "geometry and aspect ratio.\n" - " \n" - "If Force Aspect is not set, X/Y will be \n" - "integer scaled independently."); - break; - case MENU_ENUM_LABEL_AUDIO_VOLUME: - snprintf(s, len, - "Audio volume, expressed in dB.\n" - " \n" - " 0 dB is normal volume. No gain will be applied.\n" - "Gain can be controlled in runtime with Input\n" - "Volume Up / Input Volume Down."); - break; - case MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA: - snprintf(s, len, - "Audio rate control.\n" - " \n" - "Setting this to 0 disables rate control.\n" - "Any other value controls audio rate control \n" - "delta.\n" - " \n" - "Defines how much input rate can be adjusted \n" - "dynamically.\n" - " \n" - " Input rate is defined as: \n" - " input rate * (1.0 +/- (rate control delta))"); - break; - case MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW: - snprintf(s, len, - "Maximum audio timing skew.\n" - " \n" - "Defines the maximum change in input rate.\n" - "You may want to increase this to enable\n" - "very large changes in timing, for example\n" - "running PAL cores on NTSC displays, at the\n" - "cost of inaccurate audio pitch.\n" - " \n" - " Input rate is defined as: \n" - " input rate * (1.0 +/- (max timing skew))"); - break; - case MENU_ENUM_LABEL_OVERLAY_NEXT: - snprintf(s, len, - "Toggles to next overlay.\n" - " \n" - "Wraps around."); - break; - case MENU_ENUM_LABEL_LOG_VERBOSITY: - snprintf(s, len, - "Enable or disable verbosity level \n" - "of frontend."); - break; - case MENU_ENUM_LABEL_VOLUME_UP: - snprintf(s, len, - "调高音量."); - break; - case MENU_ENUM_LABEL_VOLUME_DOWN: - snprintf(s, len, - "降低音量."); - break; - case MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION: - snprintf(s, len, - "Forcibly disable composition.\n" - "Only valid on Windows Vista/7 for now."); - break; - case MENU_ENUM_LABEL_PERFCNT_ENABLE: - snprintf(s, len, - "启用或关闭前端 \n" - "性能计数."); - break; - case MENU_ENUM_LABEL_SYSTEM_DIRECTORY: - snprintf(s, len, - "系统目录. \n" - " \n" - "Sets the 'system' directory.\n" - "Cores can query for this\n" - "directory to load BIOSes, \n" - "system-specific configs, etc."); - break; - case MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE: - case MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD: - snprintf(s, len, - "Automatically saves a savestate at the \n" - "end of RetroArch's lifetime.\n" - " \n" - "RetroArch will automatically load any savestate\n" - "with this path on startup if 'Auto Load State\n" - "is enabled."); - break; - case MENU_ENUM_LABEL_VIDEO_THREADED: - snprintf(s, len, - "Use threaded video driver.\n" - " \n" - "Using this might improve performance at the \n" - "possible cost of latency and more video \n" - "stuttering."); - break; - case MENU_ENUM_LABEL_VIDEO_VSYNC: - snprintf(s, len, - "视频垂直同步.\n"); - break; - case MENU_ENUM_LABEL_VIDEO_HARD_SYNC: - snprintf(s, len, - "尝试硬件同步 \n" - "CPU和GPU.\n" - " \n" - "可以降低潜在的性能 \n" - "开销."); - break; - case MENU_ENUM_LABEL_REWIND_GRANULARITY: - snprintf(s, len, - "Rewind granularity.\n" - " \n" - " When rewinding defined number of \n" - "frames, you can rewind several frames \n" - "at a time, increasing the rewinding \n" - "speed."); - break; - case MENU_ENUM_LABEL_SCREENSHOT: - snprintf(s, len, - "Take screenshot."); - break; - case MENU_ENUM_LABEL_VIDEO_FRAME_DELAY: - snprintf(s, len, - "Sets how many milliseconds to delay\n" - "after VSync before running the core.\n" - "\n" - "Can reduce latency at the cost of\n" - "higher risk of stuttering.\n" - " \n" - "Maximum is 15."); - break; - case MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES: - snprintf(s, len, - "Sets how many frames CPU can \n" - "run ahead of GPU when using 'GPU \n" - "Hard Sync'.\n" - " \n" - "Maximum is 3.\n" - " \n" - " 0: Syncs to GPU immediately.\n" - " 1: Syncs to previous frame.\n" - " 2: Etc ..."); - break; - case MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION: - snprintf(s, len, - "Inserts a black frame inbetween \n" - "frames.\n" - " \n" - "Useful for 120 Hz monitors who want to \n" - "play 60 Hz material with eliminated \n" - "ghosting.\n" - " \n" - "Video refresh rate should still be \n" - "configured as if it is a 60 Hz monitor \n" - "(divide refresh rate by 2)."); - break; - case MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN: - snprintf(s, len, - "Show startup screen in menu.\n" - "Is automatically set to false when seen\n" - "for the first time.\n" - " \n" - "This is only updated in config if\n" - "'Save Configuration on Exit' is enabled.\n"); - break; - case MENU_ENUM_LABEL_VIDEO_FULLSCREEN: - snprintf(s, len, "Toggles fullscreen."); - break; - case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: - snprintf(s, len, - "Block SRAM from being overwritten \n" - "when loading save states.\n" - " \n" - "Might potentially lead to buggy games."); - break; - case MENU_ENUM_LABEL_PAUSE_NONACTIVE: - snprintf(s, len, - "Pause gameplay when window focus \n" - "is lost."); - break; - case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT: - snprintf(s, len, - "Screenshots output of GPU shaded \n" - "material if available."); - break; - case MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY: - snprintf(s, len, - "截图目录 \n" - " \n" - "用于保存截图的文件夹。" - ); - break; - case MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL: - snprintf(s, len, - "VSync Swap Interval.\n" - " \n" - "Uses a custom swap interval for VSync. Set this \n" - "to effectively halve monitor refresh rate."); - break; - case MENU_ENUM_LABEL_SAVEFILE_DIRECTORY: - snprintf(s, len, - "游戏存盘目录. \n" - " \n" - "Save all save files (*.srm) to this \n" - "directory. This includes related files like \n" - ".bsv, .rt, .psrm, etc...\n" - " \n" - "This will be overridden by explicit command line\n" - "options."); - break; - case MENU_ENUM_LABEL_SAVESTATE_DIRECTORY: - snprintf(s, len, - "即时存档目录. \n" - " \n" - "Save all save states (*.state) to this \n" - "directory.\n" - " \n" - "This will be overridden by explicit command line\n" - "options."); - break; - case MENU_ENUM_LABEL_ASSETS_DIRECTORY: - snprintf(s, len, - "Assets Directory. \n" - " \n" - " This location is queried by default when \n" - "menu interfaces try to look for loadable \n" - "assets, etc."); - break; - case MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY: - snprintf(s, len, - "动态壁纸目录 \n" - " \n" - "保存用于主界面的、依据游戏内容变化的动态壁纸。"); - break; - case MENU_ENUM_LABEL_SLOWMOTION_RATIO: - snprintf(s, len, - "Slowmotion ratio." - " \n" - "When slowmotion, content will slow\n" - "down by factor."); - break; - case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: - snprintf(s, len, - "Defines axis threshold.\n" - " \n" - "How far an axis must be tilted to result\n" - "in a button press.\n" - " Possible values are [0.0, 1.0]."); - break; - case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: - snprintf(s, len, - "Turbo period.\n" - " \n" - "Describes the period of which turbo-enabled\n" - "buttons toggle.\n" - " \n" - "Numbers are described in frames." - ); - break; - case MENU_ENUM_LABEL_INPUT_DUTY_CYCLE: - snprintf(s, len, - "Duty cycle.\n" - " \n" - "Describes how long the period of a turbo-enabled\n" - "should be.\n" - " \n" - "Numbers are described in frames." - ); - break; - case MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE: - snprintf(s, len, "Enable touch support."); - break; - case MENU_ENUM_LABEL_INPUT_PREFER_FRONT_TOUCH: - snprintf(s, len, "Use front instead of back touch."); - break; - case MENU_ENUM_LABEL_MOUSE_ENABLE: - snprintf(s, len, "Enable mouse input inside the menu."); - break; - case MENU_ENUM_LABEL_POINTER_ENABLE: - snprintf(s, len, "Enable touch input inside the menu."); - break; - case MENU_ENUM_LABEL_MENU_WALLPAPER: - snprintf(s, len, "Path to an image to set as menu wallpaper."); - break; - case MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND: - snprintf(s, len, - "Wrap-around to beginning and/or end \n" - "if boundary of list is reached \n" - "horizontally and/or vertically."); - break; - case MENU_ENUM_LABEL_PAUSE_LIBRETRO: - snprintf(s, len, - "If disabled, the libretro core will keep \n" - "running in the background when we are in the \n" - "menu."); - break; - case MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE: - snprintf(s, len, - "Suspends the screensaver. Is a hint that \n" - "does not necessarily have to be \n" - "honored by the video driver."); - break; - case MENU_ENUM_LABEL_NETPLAY_MODE: - snprintf(s, len, - "Netplay client mode for the current user. \n" - "Will be 'Server' mode if disabled."); - break; - case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES: - snprintf(s, len, - "The amount of delay frames to use for netplay. \n" - " \n" - "Increasing this value will increase \n" - "performance, but introduce more latency."); - break; - case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: - snprintf(s, len, - "The frequency in frames with which netplay \n" - "will verify that the host and client are in \n" - "sync. \n" - " \n" - "With most cores, this value will have no \n" - "visible effect and can be ignored. With \n" - "nondeterminstic cores, this value determines \n" - "how often the netplay peers will be brought \n" - "into sync. With buggy cores, setting this \n" - "to any non-zero value will cause severe \n" - "performance issues. Set to zero to perform \n" - "no checks. This value is only used on the \n" - "netplay host. \n"); - break; - case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: - snprintf(s, len, - "Maximum amount of swapchain images. This \n" - "can tell the video driver to use a specific \n" - "video buffering mode. \n" - " \n" - "Single buffering - 1\n" - "Double buffering - 2\n" - "Triple buffering - 3\n" - " \n" - "Setting the right buffering mode can have \n" - "a big impact on latency."); - break; - case MENU_ENUM_LABEL_VIDEO_SMOOTH: - snprintf(s, len, - "Smoothens picture with bilinear filtering. \n" - "Should be disabled if using shaders."); - break; - case MENU_ENUM_LABEL_TIMEDATE_ENABLE: - snprintf(s, len, - "Shows current date and/or time inside menu."); - break; - case MENU_ENUM_LABEL_CORE_ENABLE: - snprintf(s, len, - "Shows current core inside menu."); - break; - case MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST: - snprintf(s, len, - "Enables Netplay in host (server) mode."); - break; - case MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT: - snprintf(s, len, - "Enables Netplay in client mode."); - break; - case MENU_ENUM_LABEL_NETPLAY_DISCONNECT: - snprintf(s, len, - "Disconnects an active Netplay connection."); - break; - case MENU_ENUM_LABEL_NETPLAY_SETTINGS: - snprintf(s, len, - "Setting related to Netplay."); - break; - case MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS: - snprintf(s, len, - "Search for and connect to netplay hosts on the local network."); - break; - case MENU_ENUM_LABEL_DYNAMIC_WALLPAPER: - snprintf(s, len, - "Dynamically load a new wallpaper \n" - "depending on context."); - break; - case MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL: - snprintf(s, len, - "URL to core updater directory on the \n" - "Libretro buildbot."); - break; - case MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL: - snprintf(s, len, - "URL to assets updater directory on the \n" - "Libretro buildbot."); - break; - case MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE: - snprintf(s, len, - "if enabled, overrides the input binds \n" - "with the remapped binds set for the \n" - "current core."); - break; - case MENU_ENUM_LABEL_OVERLAY_DIRECTORY: - snprintf(s, len, - "Overlay Directory. \n" - " \n" - "Defines a directory where overlays are \n" - "kept for easy access."); - break; - case MENU_ENUM_LABEL_INPUT_MAX_USERS: - snprintf(s, len, - "Maximum amount of users supported by \n" - "RetroArch."); - break; - case MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE: - snprintf(s, len, - "After downloading, automatically extract \n" - "archives that the downloads are contained \n" - "inside."); - break; - case MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE: - snprintf(s, len, - "Filter files being shown by \n" - "supported extensions."); - break; - case MENU_ENUM_LABEL_NETPLAY_NICKNAME: - snprintf(s, len, - "The username of the person running RetroArch. \n" - "This will be used for playing online games."); - break; - case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT: - snprintf(s, len, - "When being client over netplay, use \n" - "keybinds for player 1."); - break; - case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT: - snprintf(s, len, - "The port of the host IP address. \n" - "Can be either a TCP or UDP port."); - break; - case MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE: - snprintf(s, len, - "Enable or disable spectator mode for \n" - "the user during netplay."); - break; - case MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS: - snprintf(s, len, - "The address of the host to connect to."); - break; - case MENU_ENUM_LABEL_STDIN_CMD_ENABLE: - snprintf(s, len, - "Enable stdin command interface."); - break; - case MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT: - snprintf(s, len, - "Start User Interface companion driver \n" - "on boot (if available)."); - break; - case MENU_ENUM_LABEL_MENU_DRIVER: - snprintf(s, len, "Menu driver to use."); - break; - case MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO: - snprintf(s, len, - "Gamepad button combination to toggle menu. \n" - " \n" - "0 - None \n" - "1 - Press L + R + Y + D-Pad Down \n" - "simultaneously. \n" - "2 - Press L3 + R3 simultaneously. \n" - "3 - Press Start + Select simultaneously."); - break; - case MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU: - snprintf(s, len, "Allow any RetroPad to control the menu."); - break; - case MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE: - snprintf(s, len, - "Enable input auto-detection.\n" - " \n" - "Will attempt to auto-configure \n" - "joypads, Plug-and-Play style."); - break; - case MENU_ENUM_LABEL_CAMERA_ALLOW: - snprintf(s, len, - "Allow or disallow camera access by \n" - "cores."); - break; - case MENU_ENUM_LABEL_LOCATION_ALLOW: - snprintf(s, len, - "Allow or disallow location services \n" - "access by cores."); - break; - case MENU_ENUM_LABEL_TURBO: - snprintf(s, len, - "Turbo enable.\n" - " \n" - "Holding the turbo while pressing another \n" - "button will let the button enter a turbo \n" - "mode where the button state is modulated \n" - "with a periodic signal. \n" - " \n" - "The modulation stops when the button \n" - "itself (not turbo button) is released."); - break; - case MENU_ENUM_LABEL_OSK_ENABLE: - snprintf(s, len, - "Enable/disable on-screen keyboard."); - break; - case MENU_ENUM_LABEL_AUDIO_MUTE: - snprintf(s, len, - "Mute/unmute audio."); - break; - case MENU_ENUM_LABEL_REWIND: - snprintf(s, len, - "Hold button down to rewind.\n" - " \n" - "Rewind must be enabled."); - break; - case MENU_ENUM_LABEL_EXIT_EMULATOR: - snprintf(s, len, - "Key to exit RetroArch cleanly." -#if !defined(RARCH_MOBILE) && !defined(RARCH_CONSOLE) - "\nKilling it in any hard way (SIGKILL, \n" - "etc) will terminate without saving\n" - "RAM, etc. On Unix-likes,\n" - "SIGINT/SIGTERM allows\n" - "a clean deinitialization." -#endif - ); - break; - case MENU_ENUM_LABEL_LOAD_STATE: - snprintf(s, len, - "Loads state."); - break; - case MENU_ENUM_LABEL_SAVE_STATE: - snprintf(s, len, - "Saves state."); - break; - case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS: - snprintf(s, len, - "Netplay flip users."); - break; - case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS: - snprintf(s, len, - "Increment cheat index.\n"); - break; - case MENU_ENUM_LABEL_CHEAT_INDEX_MINUS: - snprintf(s, len, - "Decrement cheat index.\n"); - break; - case MENU_ENUM_LABEL_SHADER_PREV: - snprintf(s, len, - "Applies previous shader in directory."); - break; - case MENU_ENUM_LABEL_SHADER_NEXT: - snprintf(s, len, - "Applies next shader in directory."); - break; - case MENU_ENUM_LABEL_RESET: - snprintf(s, len, - "Reset the content.\n"); - break; - case MENU_ENUM_LABEL_PAUSE_TOGGLE: - snprintf(s, len, - "Toggle between paused and non-paused state."); - break; - case MENU_ENUM_LABEL_CHEAT_TOGGLE: - snprintf(s, len, - "打开金手指索引.\n"); - break; - case MENU_ENUM_LABEL_HOLD_FAST_FORWARD: - snprintf(s, len, - "Hold for fast-forward. Releasing button \n" - "disables fast-forward."); - break; - case MENU_ENUM_LABEL_SLOWMOTION: - snprintf(s, len, - "Hold for slowmotion."); - break; - case MENU_ENUM_LABEL_FRAME_ADVANCE: - snprintf(s, len, - "Frame advance when content is paused."); - break; - case MENU_ENUM_LABEL_MOVIE_RECORD_TOGGLE: - snprintf(s, len, - "Toggle between recording and not."); - break; - case MENU_ENUM_LABEL_L_X_PLUS: - case MENU_ENUM_LABEL_L_X_MINUS: - case MENU_ENUM_LABEL_L_Y_PLUS: - case MENU_ENUM_LABEL_L_Y_MINUS: - case MENU_ENUM_LABEL_R_X_PLUS: - case MENU_ENUM_LABEL_R_X_MINUS: - case MENU_ENUM_LABEL_R_Y_PLUS: - case MENU_ENUM_LABEL_R_Y_MINUS: - snprintf(s, len, - "Axis for analog stick (DualShock-esque).\n" - " \n" - "Bound as usual, however, if a real analog \n" - "axis is bound, it can be read as a true analog.\n" - " \n" - "Positive X axis is right. \n" - "Positive Y axis is down."); - break; - case MENU_ENUM_LABEL_VALUE_WHAT_IS_A_CORE_DESC: - snprintf(s, len, - "RetroArch本身并不能做什么事情。 \n" - " \n" - "如果想在上面干点什么,你需要向它加载一个程 \n" - "序。 \n" - "\n" - "我们把这样的程序叫做“Libretro核心”,简单 \n" - "的称呼其为“核心”。 \n" - " \n" - "你可以从“加载核心”菜单中选择一个核心。 \n" - " \n" -#ifdef HAVE_NETWORKING - "你可以通过以下几种方法来获取核心: \n" - "一、通过访问菜单项「%s」 \n" - " -> 「%s」来下载;\n" - "二、手动将其移入核心目录中,访问目录设置 \n" - "找到你的“%s”。", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) -#else - "你可以通过手动将核心移入目录中来添加他 \n" - "们,访问目录设置找到你的“%s”。", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) -#endif - ); - break; - case MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD_DESC: - snprintf(s, len, - "You can change the virtual gamepad overlay\n" - "by going to '%s' -> '%s'." - " \n" - "From there you can change the overlay,\n" - "change the size and opacity of the buttons, etc.\n" - " \n" - "NOTE: By default, virtual gamepad overlays are\n" - "hidden when in the menu.\n" - "If you'd like to change this behavior,\n" - "you can set '%s' to false.", - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS), - msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU) - ); - break; - default: - if (string_is_empty(s)) - strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); - return -1; - } - - return 0; -} - -const char *msg_hash_to_str_chs(enum msg_hash_enums msg) -{ - switch (msg) - { -#include "msg_hash_chs.h" - - default: -#if 0 - RARCH_LOG("Unimplemented: [%d]\n", msg); -#endif - break; - } - - return "null"; -} +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "????????" /*FIXME:"Achievement List (Hardcore)"*/ + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, + "Archive File Association Action" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "??" /*FIXME:"Block Frames"*/ + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "??DSP??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "??/??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, + "????(ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, + "????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, + "??????(KHz)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, + "????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, + "??????(dB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "SaveRAM??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "?????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "????Shader??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, + "???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, + "??????????SaveRAM" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "???????URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT, + "???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "?????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, + "????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, + "?????" /*FIXME: "Cheat Passes"*/ + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, +/* FIXME? Translate 'Achievements Hardcore Mode' */ + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, + "??????:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, + "Retro ??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, +/* FIXME? Translate 'Test Unofficial Achievements' */ + "?????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, + "??????:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, + "???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, + "????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, + "???????" + ) +MSG_HASH( +MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, + "???????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, + "?????????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DIR, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, + "???????URL") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, + "CPU??:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, + "CPU??:") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, + "?????????") /* TODO/FIXME - update */ +MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, + "") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, + "") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, + "") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, + "Disk Cycle Tray Status") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, + "??DPI??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, + "DPI??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, +/* FIXME? Translate 'Load Dummy on Core Shutdown' */ + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, + "??????????") /*FIXME: "Check for Missing Firmware Before Loading"*/ +MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, +/* FIXME? Translate 'Enable Achievements' */ + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, + "???????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, + "??/??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, + "???X") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, + "???X- (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, + "???X+ (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, + "???Y") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, + "???Y- (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, + "???Y+ (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, + "???X") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, + "???X- (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, + "???X+ (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, + "???Y") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, + "???Y- (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, + "???Y+ (?)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, + "???? ??/?? ??") /*FIXME:"Menu Swap OK & Cancel Buttons"*/ +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, + "????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, + "Turbo???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, + "A?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, + "B?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, + "L2?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, + "L3?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, + "L?(????)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, + "R2?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, + "R3?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, + "R?(????)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, + "X?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, + "Y?(??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, + "(?: %s)") /*FIXME:"(Key: %s)"*/ +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, + "????? -") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, + "????? +") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + "Game focus toggle") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, + "?????? ??/?? ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, + "?? RetroArch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, + "???Shader") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, + "???Shader") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, + "??? -") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, + "??? +") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, + "?? -") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, + "?? +") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OSK_OVERLAY_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, + "TURBO??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, + "Turbo??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, + "???? %u ???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, + "Lakka ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_FRENCH, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_GERMAN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, + "NV SHIELD") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, /* TODO/FIXME - update */ + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, + "...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, + "????P2??C1") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, + "????TCP/UDP??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, + "??NAT??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, + "N/A") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, + "????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, + "??Shader??.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OSK_OVERLAY_DIRECTORY, + "OSK????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, + "??PAL60??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, + "?? RetroArch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, + "BBFC ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, + "CERO ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, + "CRC32") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, + "Edge????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, + "Edge????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, + "Edge????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, + "ELSPA ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, + "ESRB ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, + "???(Famitsu)????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, + "MD5") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, + "PEGI ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, + "SHA1") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, + "TGDB ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, + "?? RetroArch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, + "Retro??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, + "Retro???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, + "RetroPad w/ Analog") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, + "Retro ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, + "??SAMBA??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, + "Savestate Thumbnails") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, + "") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, + "Shader") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, + "Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, + "Ribbon") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, + "Ribbon (??)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, + "Simple Snow") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, + "Snow") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, + "??SSH??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, + "?????RetroPad") +MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, + "??/BIOS??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, + "7zip ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, + "ALSA ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, + "Cg ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, + "Cocoa ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, + "CoreText ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, + "CPU??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, + "?????DPI") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, + "???????(mm)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, + "???????(mm)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, + "DirectSound ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, + "???????libretro?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, + "EGL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, + "OpenGL/Direct3D ????? (?????Shader) ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, + "FFmpeg ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, + "FreeType ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, + "Git??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, + "GLSL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, + "HLSL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, + "JACK ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, + "KMS/EGL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, + "LibretroDB ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, + "Libusb ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, + "libxml2 XML????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, + "Netplay (???) ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, + "OpenAL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, + "OpenGL ES ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, + "OpenGL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, + "OpenSL ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, + "OpenVG ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, + "OSS ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, + "PulseAudio ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, + "Python (Shader?????) ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, + "BMP ?? (RBMP)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, + "RetroRating ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, + "JPEG ?? (RJPEG)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, + "RoarAudio ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, + "PNG ?? (RPNG)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, + "RSound ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, + "TGA ?? (RTGA)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, + "SDL2 ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, + "SDL ????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, + "SDL1.2 ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, + "Slang ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, + "Udev ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, + "Video4Linux2 ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, + "Vulkan ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, + "Wayland ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, + "X11 ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, + "XAudio2 ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, + "XVideo ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, + "Zlib ??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, /* TODO/FIXME - update */ + "???????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, + "Boxarts") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, + "?") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, + "UI Companion Enable") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, + "UI Companion Start On Boot") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, + "Menubar") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, + "??CG Shader????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, + "??GLSL Shader????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, + "?? Lakka") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, + "??Slang Shader????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, + "??????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, + "") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, + "Crop Overscan (Reload)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, + "??????(OSD)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, + "????(OSD)??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, + "????(OSD)??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, + "????sRGB???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, + "??Gamma") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, + "??GPU??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, + "??GPU??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, + "??GPU??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, + "??GPU????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, + "????(OSD)X???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, + "????(OSD)Y???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, + "Shader????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_PARAMETERS, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, + "??Shader???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, + "????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, + "?????X") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, + "?????Y") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, + "?? VI ????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, + "?????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, + "Wi-Fi??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, + "Wi-Fi") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, + "FlatUI") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, + "Monochrome") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, + "Systematic") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, + "NeoActive") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, + "Pixel") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, + "RetroActive") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, + "Dot-Art") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, + "??Shader??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_ADD, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_SETTINGS, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_VIDEO, + "?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, + "?") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, + "Shader??") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, + "??????????????? http://retroachievements.org") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, + "?????????????????/???????") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, + "??????????????????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, + "????????") +MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, + "????????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, + "???????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, + "?????????") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, + "????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, + "?????????") +MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, + "???????????") +MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, + "?????????") +MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, + "???/????????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, + "??????????") +MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, + "?????????") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, + "?????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, + "????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, + "??????????") +MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, + "CPU????????") +MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, + "??????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, + "???????") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, + "??????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, + "?????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, + "???????????") +MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, + "??????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, + "??????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, + "??????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, + "???????????????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, + "?????RetroArch?????????") +MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, + "?????????????(SAMBA)?") +MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, + "????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, + "???????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, + "????????????(SSH)?") +MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, + "?????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, + "??????????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, + "??????????????????????\n" + "120Hz??????????60Hz???????\n" + "????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "????????????????????????\n" + "??(??)?") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, + "???????GPU???CPU????GPU????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + "??????????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, + "?????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, + "?????????(Hz)?") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, + "??????????") +MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, + "?????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, + "??????????????") +MSG_HASH(MSG_APPENDED_DISK, + "Appended disk") +MSG_HASH(MSG_APPLICATION_DIR, + "??????") +MSG_HASH(MSG_APPLYING_SHADER, + "Applying shader") +MSG_HASH(MSG_AUDIO_MUTED, + "???") +MSG_HASH(MSG_AUDIO_UNMUTED, + "?????") +MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, + "?? autoconf ?????") +MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, + "???????????") +MSG_HASH(MSG_AUTOSAVE_FAILED, + "??????????") +MSG_HASH(MSG_AUTO_SAVE_STATE_TO, + "???????") +MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, + "?? SRAM ??") +MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, + "Bringing up command interface on port") +MSG_HASH(MSG_BYTES, + "??") +MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, + "??????????????????") +MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, + "?????????????????.") +MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, + "????magic numbers??...") +MSG_HASH(MSG_COMPILED_AGAINST_API, + "Compiled against API") +MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, + "?????????????????") +MSG_HASH(MSG_CONNECTED_TO, + "???") +MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, + "???CRC32s?????????????") +MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, + "???????????????") +MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "??????????") +MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, + "Core options file created successfully.") +MSG_HASH(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, + "Could not find any next driver") +MSG_HASH(MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, + "Could not find compatible system.") +MSG_HASH(MSG_COULD_NOT_FIND_VALID_DATA_TRACK, + "??????????") +MSG_HASH(MSG_COULD_NOT_OPEN_DATA_TRACK, + "???????") +MSG_HASH(MSG_COULD_NOT_READ_CONTENT_FILE, + "????????") +MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, + "??????????.") +MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, + "????????.") +MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, + "CRC32 checksum mismatch between content file and saved content checksum in replay file header; replay highly likely to desync on playback.") +MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, + "Custom timing given") +MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, + "?????????") +MSG_HASH(MSG_DECOMPRESSION_FAILED, + "??????") +MSG_HASH(MSG_DETECTED_VIEWPORT_OF, + "Detected viewport of") +MSG_HASH(MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, + "Did not find a valid content patch.") +MSG_HASH(MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, + "Disconnect device from a valid port.") +MSG_HASH(MSG_DISK_CLOSED, + "???") +MSG_HASH(MSG_DISK_EJECTED, + "???") +MSG_HASH(MSG_DOWNLOADING, + "????") +MSG_HASH(MSG_DOWNLOAD_FAILED, + "????") +MSG_HASH(MSG_ERROR, + "??") +MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, + "Libretro core requires content, but nothing was provided.") +MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, + "Libretro core requires special content, but none were provided.") +MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, + "Error parsing arguments.") +MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, + "Error saving core options file.") +MSG_HASH(MSG_ERROR_SAVING_REMAP_FILE, + "Error saving remap file.") +MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, + "Error saving shader preset.") +MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, + "????????") +MSG_HASH(MSG_EXTRACTING, + "????") +MSG_HASH(MSG_EXTRACTING_FILE, + "????") +MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, + "???????") +MSG_HASH(MSG_FAILED_TO, + "Failed to") +MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, + "Failed to accept incoming spectator.") +MSG_HASH(MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, + "Failed to allocate memory for patched content...") +MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, + "Failed to apply shader.") +MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, + "Failed to bind socket.") +MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, + "???????") +MSG_HASH(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, + "????????????") +MSG_HASH(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, + "??????????.") +MSG_HASH(MSG_FAILED_TO_LOAD, + "????") +MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, + "??????") +MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, + "????????") +MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, + "Failed to load overlay.") +MSG_HASH(MSG_FAILED_TO_LOAD_STATE, + "Failed to load state from") +MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, + "??libretro????") +MSG_HASH(MSG_FAILED_TO_PATCH, + "??????") +MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, + "Failed to receive header from client.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, + "Failed to receive nickname.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, + "Failed to receive nickname from host.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, + "Failed to receive nickname size from host.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, + "Failed to receive SRAM data from host.") +MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, + "Failed to remove disk from tray.") +MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, + "????????") +MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, + "Failed to save SRAM") +MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, + "Failed to save state to") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, + "??????.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, + "????????.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, + "??????????.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, + "??????????.") +MSG_HASH(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, + "??SRAM????????.") +MSG_HASH(MSG_FAILED_TO_START_AUDIO_DRIVER, + "??????????????????????") +MSG_HASH(MSG_FAILED_TO_START_MOVIE_RECORD, + "????????.") +MSG_HASH(MSG_FAILED_TO_START_RECORDING, + "Failed to start recording.") +MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, + "Failed to take screenshot.") +MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, + "Failed to undo load state.") +MSG_HASH(MSG_FAILED_TO_UNDO_SAVE_STATE, + "Failed to undo save state.") +MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, + "Failed to unmute audio.") +MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, + "Fatal error received in") +MSG_HASH(MSG_FILE_NOT_FOUND, + "?????") +MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, + "Found auto savestate in") +MSG_HASH(MSG_FOUND_DISK_LABEL, + "Found disk label") +MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, + "Found first data track on file") +MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, + "Found last state slot") +MSG_HASH(MSG_FOUND_SHADER, + "Found shader") +MSG_HASH(MSG_FRAMES, + "?") +MSG_HASH(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, + "Per-Game Options: game-specific core options found at") +MSG_HASH(MSG_GOT_INVALID_DISK_INDEX, + "Got invalid disk index.") +MSG_HASH(MSG_GRAB_MOUSE_STATE, + "??????") +MSG_HASH(MSG_GAME_FOCUS_ON, + "Game focus on") +MSG_HASH(MSG_GAME_FOCUS_OFF, + "Game focus off") +MSG_HASH(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, + "Libretro core is hardware rendered. Must use post-shaded recording as well.") +MSG_HASH(MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, + "Inflated checksum did not match CRC32.") +MSG_HASH(MSG_INPUT_CHEAT, + "?????") +MSG_HASH(MSG_INPUT_CHEAT_FILENAME, + "Cheat Filename") +MSG_HASH(MSG_INPUT_PRESET_FILENAME, + "Preset Filename") +MSG_HASH(MSG_INTERFACE, + "??") +MSG_HASH(MSG_INTERNAL_STORAGE, + "????") +MSG_HASH(MSG_REMOVABLE_STORAGE, + "Removable Storage") +MSG_HASH(MSG_INVALID_NICKNAME_SIZE, + "Invalid nickname size.") +MSG_HASH(MSG_IN_BYTES, + "(??)") +MSG_HASH(MSG_IN_GIGABYTES, + "(???)") +MSG_HASH(MSG_IN_MEGABYTES, + "(???)") +MSG_HASH(MSG_LIBRETRO_ABI_BREAK, + "is compiled against a different version of libretro than this libretro implementation.") +MSG_HASH(MSG_LIBRETRO_FRONTEND, + "?libretro??????") +MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, + "?????? #%d.") +MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, + "?????? #-1 (auto).") +MSG_HASH(MSG_LOADING, + "????") +MSG_HASH(MSG_FIRMWARE, + "???????????") +MSG_HASH(MSG_LOADING_CONTENT_FILE, + "????????") +MSG_HASH(MSG_LOADING_HISTORY_FILE, + "????????") +MSG_HASH(MSG_LOADING_STATE, + "??????") +MSG_HASH(MSG_MEMORY, + "??") +MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, + "???????BSV1???") +MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, + "??????????????????????????") +MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, + "??????.") +MSG_HASH(MSG_MOVIE_RECORD_STOPPED, + "???????") +MSG_HASH(MSG_NETPLAY_FAILED, + "??????????") +MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, + "????????????") +MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, + "????????") +MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, + "?????????") +MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, + "???????") +MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, + "???????") +MSG_HASH(MSG_PAUSED, + "???") +MSG_HASH(MSG_PROGRAM, + "RetroArch") +MSG_HASH(MSG_READING_FIRST_DATA_TRACK, + "????????...") +MSG_HASH(MSG_RECEIVED, + "????") +MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, + "???????????") +MSG_HASH(MSG_RECORDING_TO, + "???") +MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, + "?????????") +MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, + "Redirecting save file to") +MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, + "Redirecting savestate to") +MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, + "Remap file saved successfully.") +MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, + "Removed disk from tray.") +MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, + "????????") +MSG_HASH(MSG_RESET, + "??") +MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, + "???????????????") +MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, + "???????") +MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, + "Shaders: restoring default shader preset to") +MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, + "Reverting savefile directory to") +MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, + "Reverting savestate directory to") +MSG_HASH(MSG_REWINDING, + "?????") +MSG_HASH(MSG_REWIND_INIT, + "Initializing rewind buffer with size") +MSG_HASH(MSG_REWIND_INIT_FAILED, + "?????????. ??????.") +MSG_HASH(MSG_REWIND_INIT_FAILED_THREADED_AUDIO, + "Implementation uses threaded audio. Cannot use rewind.") +MSG_HASH(MSG_REWIND_REACHED_END, + "????????.") +MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, + "???????") +MSG_HASH(MSG_SAVED_STATE_TO_SLOT, + "?????? #%d.") +MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, + "?????? #-1 (auto).") +MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, + "?????") +MSG_HASH(MSG_SAVING_RAM_TYPE, + "?? RAM ??") +MSG_HASH(MSG_SAVING_STATE, + "???") +MSG_HASH(MSG_SCANNING, + "???") +MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, + "??????????") +MSG_HASH(MSG_SENDING_COMMAND, + "????") +MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, + "Several patches are explicitly defined, ignoring all...") +MSG_HASH(MSG_SHADER, + "Shader") +MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, + "Shader preset saved successfully.") +MSG_HASH(MSG_SKIPPING_SRAM_LOAD, + "?? SRAM ???") +MSG_HASH(MSG_SLOW_MOTION, + "????") +MSG_HASH(MSG_SLOW_MOTION_REWIND, + "??????") +MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, + "SRAM will not be saved.") +MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, + "????.") +MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, + "Starting movie record to") +MSG_HASH(MSG_STATE_SIZE, + "State size") +MSG_HASH(MSG_STATE_SLOT, + "?????") +MSG_HASH(MSG_TAKING_SCREENSHOT, + "???") +MSG_HASH(MSG_TO, + "?") +MSG_HASH(MSG_UNDID_LOAD_STATE, + "????????") +MSG_HASH(MSG_UNDOING_SAVE_STATE, + "??????") +MSG_HASH(MSG_UNKNOWN, + "??") +MSG_HASH(MSG_UNPAUSED, + "?????") +MSG_HASH(MSG_UNRECOGNIZED_COMMAND, + "???????") +MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, + "Using core name for new config.") +MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, + "??libretro??????????") +MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, + "Connect device from a valid port.") +MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, + "???????") +MSG_HASH(MSG_VALUE_REBOOTING, + "????") +MSG_HASH(MSG_VALUE_SHUTTING_DOWN, + "????") +MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, + "libretro API??") +MSG_HASH(MSG_VIEWPORT_SIZE_CALCULATION_FAILED, + "Viewport size calculation failed! Will continue using raw data. This will probably not work right ...") +MSG_HASH(MSG_VIRTUAL_DISK_TRAY, + "virtual disk tray.") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, + "Desired audio latency in milliseconds. Might not be honored if the audio driver can't provide given latency.") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, + "??/?????") +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, + "Helps smooth out imperfections in timing when synchronizing audio and video at the same time. Be aware that if disabled, proper synchronization is nearly impossible to obtain." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_ALLOW, + "?????????????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_ALLOW, + "Allow or disallow location services access by cores." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, + "Maximum amount of users supported by RetroArch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, + "Influence how input polling is done inside RetroArch. Setting it to 'Early' or 'Late' can result in less latency, depending on your configuration." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, + "Allows any user to control the menu. If disabled, only User 1 can control the menu." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_VOLUME, + "Audio volume (in dB). 0 dB is normal volume, no gain applied." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SYNC, + "????????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + "How far an axis must be tilted to result in a button press." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, + "Amount of seconds to wait until proceeding to the next bind." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, + "Describes the period of which turbo-enabled buttons toggle. Numbers are described in frames." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, + "Describes how long the period of a turbo-enabled button should be. Numbers are described in frames." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VSYNC, + "???????????????????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, + "Allow cores to set rotation. When disabled, rotation requests are ignored. Useful for setups where one manually rotates the screen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, + "Some cores might have a shutdown feature. If enabled, it will prevent the core from shutting RetroArch down. Instead, it loads a dummy core." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, + "Check if all the required firmware is present before attempting to load content." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, + "Vertical refresh rate of your screen. Used to calculate a suitable audio input rate. NOTE: This will be ignored if 'Threaded Video' is enabled." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE, + "???????" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, + "The maximum change in audio input rate. You may want to increase this to enable very large changes in timing, for example running PAL cores on NTSC displays, at the cost of inaccurate audio pitch." + ) +MSG_HASH( + MSG_FAILED, + "???" + ) +MSG_HASH( + MSG_SUCCEEDED, + "???" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED, + "???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, + "??? Cursor List" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, + "??? - ??? : ???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, + "??? - ??? : ???" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISABLED, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLED, + "??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, + "??????" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, + "??? - ??? : Origin") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, + "??? - ??? : Franchise") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, + "??? - ??? : ESRB Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, + "??? - ??? : ELSPA Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, + "??? - ??? : PEGI Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, + "??? - ??? : CERO Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, + "??? - ??? : BBFC Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, + "??? - ??? : ?????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, + "??? - ??? : ????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, + "??? - ??? : ????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, + "??? - ??? : Edge Magazine Issue") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, + "??? - ??? : Edge Magazine Rating") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, + "?????") +MSG_HASH(MSG_WIFI_SCAN_COMPLETE, + "Wi-Fi ?????") +MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, + "??????...") +MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, + "???????????") +MSG_HASH(MSG_NETPLAY_LAN_SCANNING, + "????????...") +MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, + "?????????????") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, + "Enable or disable composition (Windows only).") +MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, + "??????????????/???????") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, + "?????????????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, + "??????") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, + "Use the same controls for both the menu and the game. Applies to the keyboard.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, + "???????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, + "?? %d ????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, + "????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + "??????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, + "???") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, + "??") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, + "??????????????") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, + "????????????????????") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, + "??URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL, + "URL??" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_START, + "??" + ) +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, + "Bokeh") From 959b1c4b13bbe1f6629dac239089425932c4d791 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Feb 2017 05:56:01 +0100 Subject: [PATCH 31/90] Revert "Update Chinese" This reverts commit c7297d41b2f65385884dd4dbb6ec17f6b1bfb3b9. --- intl/msg_hash_chs.c | 4279 +++++++++++++++++++------------------------ 1 file changed, 1880 insertions(+), 2399 deletions(-) diff --git a/intl/msg_hash_chs.c b/intl/msg_hash_chs.c index 8a87d5ba05..1e618aaadc 100644 --- a/intl/msg_hash_chs.c +++ b/intl/msg_hash_chs.c @@ -1,2400 +1,1881 @@ -MSG_HASH( - MSG_COMPILER, - "???" - ) -MSG_HASH( - MSG_UNKNOWN_COMPILER, - "??????" - ) -MSG_HASH( - MSG_DEVICE_DISCONNECTED_FROM_PORT, - "?????????" - ) -MSG_HASH( - MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "????????????" - ) -MSG_HASH( - MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "??????????????" - ) -MSG_HASH( - MSG_GOT_CONNECTION_FROM, - "????? \"%s\"" - ) -MSG_HASH( - MSG_GOT_CONNECTION_FROM_NAME, - "????? \"%s (%s)\"" - ) -MSG_HASH( - MSG_PUBLIC_ADDRESS, - "????" - ) -MSG_HASH( - MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, - "?????????????????..." - ) -MSG_HASH( - MSG_NETPLAY_USERS_HAS_FLIPPED, - "??????????" - ) -MSG_HASH( - MSG_SETTING_DISK_IN_TRAY, - "Setting disk in tray" - ) -MSG_HASH( - MSG_WAITING_FOR_CLIENT, - "????? ..." - ) -MSG_HASH( - MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, - "??????" - ) -MSG_HASH( - MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, - "?????? %d ??" - ) -MSG_HASH( - MSG_NETPLAY_IMPLEMENTATIONS_DIFFER, - "?????????????RetroArch?????????" - ) -MSG_HASH( - MSG_NETPLAY_ENDIAN_DEPENDENT, - "This core does not support inter-architecture netplay between these systems" - ) -MSG_HASH( - MSG_NETPLAY_PLATFORM_DEPENDENT, - "This core does not support inter-architecture netplay" - ) -MSG_HASH( - MSG_NETPLAY_ENTER_PASSWORD, - "?????????????" - ) -MSG_HASH( - MSG_NETPLAY_INCORRECT_PASSWORD, - "????" - ) -MSG_HASH( - MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" ?????" - ) -MSG_HASH( - MSG_NETPLAY_SERVER_HANGUP, - "????????????" - ) -MSG_HASH( - MSG_NETPLAY_CLIENT_HANGUP, - "???????" - ) -MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, - "???????" - ) -MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, - "??????" /*FIXME:"There are no free player slots"*/ - ) -MSG_HASH( - MSG_NETPLAY_CANNOT_PLAY, - "?????????" - ) -MSG_HASH( - MSG_NETPLAY_PEER_PAUSED, - "?????? \"%s\" ??" - ) -MSG_HASH( - MSG_NETPLAY_CHANGED_NICK, - "???????? \"%s\"" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, - "Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "????????????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "????CPU?GPU?????????????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "??????????????????????\n" - "??????????" - ) -MSG_HASH( - MSG_AUDIO_VOLUME, - "????" - ) -MSG_HASH( - MSG_AUTODETECT, - "????" - ) -MSG_HASH( - MSG_AUTOLOADING_SAVESTATE_FROM, - "???????" - ) -MSG_HASH( - MSG_CAPABILITIES, - "??" - ) -MSG_HASH( - MSG_CONNECTING_TO_NETPLAY_HOST, - "?????????" - ) -MSG_HASH( - MSG_CONNECTING_TO_PORT, - "?????" - ) -MSG_HASH( - MSG_CONNECTION_SLOT, - "?????" - ) -MSG_HASH( - MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, - "?????????????????????????" - ) -MSG_HASH( -MSG_FAILED_TO_SET_DISK, - "??????") -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Cheevos??" /*FIXME:"Accounts Cheevos"*/ - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro ??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "????" - ) +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "????????" /*FIXME:"Achievement List (Hardcore)"*/ - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ADD_TAB, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, - "Archive File Association Action" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "??" /*FIXME:"Block Frames"*/ - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "??DSP??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "??/??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - "????(ms)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, - "????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, - "??????(KHz)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, - "????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "??????(dB)" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "SaveRAM??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "?????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "????Shader??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, - "???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, - "??????????SaveRAM" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "???????URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT, - "???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "?????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "?????" /*FIXME: "Cheat Passes"*/ - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, -/* FIXME? Translate 'Achievements Hardcore Mode' */ - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, - "??????:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "Retro ??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, -/* FIXME? Translate 'Test Unofficial Achievements' */ - "?????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, - "??????:" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, - "???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, - "???????" - ) -MSG_HASH( -MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, - "???????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "?????????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_DIR, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "???????URL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, - "CPU??:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, - "CPU??:") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, - "?????????") /* TODO/FIXME - update */ -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Disk Cycle Tray Status") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "??DPI??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "DPI??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, -/* FIXME? Translate 'Load Dummy on Core Shutdown' */ - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "??????????") /*FIXME: "Check for Missing Firmware Before Loading"*/ -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, -/* FIXME? Translate 'Enable Achievements' */ - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "???????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "??/??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LOADING_CONTENT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, - "???X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, - "???X- (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "???X+ (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, - "???Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "???Y- (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "???Y+ (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, - "???X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, - "???X- (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, - "???X+ (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, - "???Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, - "???Y- (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, - "???Y+ (?)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "???? ??/?? ??") /*FIXME:"Menu Swap OK & Cancel Buttons"*/ -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Turbo???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, - "A?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "B?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, - "L2?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, - "L3?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "L?(????)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, - "R2?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, - "R3?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "R?(????)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, - "X?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, - "Y?(??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(?: %s)") /*FIXME:"(Key: %s)"*/ -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, - "????? -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, - "????? +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Game focus toggle") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "?????? ??/?? ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, - "?? RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, - "???Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "???Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "??? -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "??? +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, - "?? -") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, - "?? +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OSK_OVERLAY_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, - "TURBO??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Turbo??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "???? %u ???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, - "Lakka ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_FRENCH, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_GERMAN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ITALIAN, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, - "NV SHIELD") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, /* TODO/FIXME - update */ - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, - "...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, - "????P2??C1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "????TCP/UDP??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "??NAT??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE, - "N/A") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORES_AVAILABLE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "??Shader??.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OSK_OVERLAY_DIRECTORY, - "OSK????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, - "??PAL60??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, - "?? RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, - "BBFC ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, - "CERO ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, - "CRC32") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edge????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Edge????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Edge????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, - "ELSPA ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, - "ESRB ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "???(Famitsu)????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, - "MD5") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, - "PEGI ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, - "SHA1") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "TGDB ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, - "?? RetroArch") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "Retro??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, - "Retro???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, - "RetroPad w/ Analog") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Retro ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, - "??SAMBA??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Savestate Thumbnails") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, - "Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, - "Ribbon") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, - "Ribbon (??)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, - "Simple Snow") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, - "Snow") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, - "??SSH??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, - "?????RetroPad") -MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "??/BIOS??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, - "7zip ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, - "ALSA ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_BUILD_DATE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CG_SUPPORT, - "Cg ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COCOA_SUPPORT, - "Cocoa ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COMMAND_IFACE_SUPPORT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CORETEXT_SUPPORT, - "CoreText ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_CPU_FEATURES, - "CPU??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_DPI, - "?????DPI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_HEIGHT, - "???????(mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, - "???????(mm)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, - "DirectSound ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, - "???????libretro?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, - "EGL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, - "OpenGL/Direct3D ????? (?????Shader) ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FFMPEG_SUPPORT, - "FFmpeg ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FREETYPE_SUPPORT, - "FreeType ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_IDENTIFIER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_NAME, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION, - "Git??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_GLSL_SUPPORT, - "GLSL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_HLSL_SUPPORT, - "HLSL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_JACK_SUPPORT, - "JACK ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_KMS_SUPPORT, - "KMS/EGL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBRETRODB_SUPPORT, - "LibretroDB ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBUSB_SUPPORT, - "Libusb ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_LIBXML2_SUPPORT, - "libxml2 XML????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, - "Netplay (???) ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, - "OpenAL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, - "OpenGL ES ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGL_SUPPORT, - "OpenGL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENSL_SUPPORT, - "OpenSL ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENVG_SUPPORT, - "OpenVG ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OSS_SUPPORT, - "OSS ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OVERLAY_SUPPORT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGED, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, - "PulseAudio ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, - "Python (Shader?????) ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, - "BMP ?? (RBMP)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, - "RetroRating ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, - "JPEG ?? (RJPEG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, - "RoarAudio ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, - "PNG ?? (RPNG)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, - "RSound ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, - "TGA ?? (RTGA)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, - "SDL2 ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, - "SDL ????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, - "SDL1.2 ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, - "Slang ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, - "Udev ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, - "Video4Linux2 ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, - "Vulkan ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, - "Wayland ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, - "X11 ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XAUDIO2_SUPPORT, - "XAudio2 ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, - "XVideo ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, - "Zlib ??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, /* TODO/FIXME - update */ - "???????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Boxarts") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, - "?") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, - "UI Companion Enable") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, - "UI Companion Start On Boot") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, - "Menubar") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "??CG Shader????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "??GLSL Shader????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "?? Lakka") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, - "??Slang Shader????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, - "??????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, - "") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, - "Crop Overscan (Reload)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "??????(OSD)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "????(OSD)??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "????(OSD)??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, - "????sRGB???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_DELAY, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, - "??Gamma") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "??GPU??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "??GPU??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, - "??GPU??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "??GPU????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, - "????(OSD)X???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, - "????(OSD)Y???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Shader????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_PARAMETERS, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "??Shader???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, - "????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, - "?????X") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, - "?????Y") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "?? VI ????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "?????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, - "Wi-Fi??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, - "Wi-Fi") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, - "FlatUI") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, - "Monochrome") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, - "Systematic") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, - "NeoActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, - "Pixel") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, - "RetroActive") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, - "Dot-Art") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "??Shader??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_ADD, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_SETTINGS, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_VIDEO, - "?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, - "?") -MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, - "Shader??") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "??????????????? http://retroachievements.org") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "?????????????????/???????") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "??????????????????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "????????") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "????????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "???????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "?????????") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, - "????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, - "?????????") -MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "???????????") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "?????????") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, - "???/????????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "??????????") -MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "?????????") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "?????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, - "????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, - "??????????") -MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, - "CPU????????") -MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, - "??????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, - "???????") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "??????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, - "?????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "???????????") -MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, - "??????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, - "??????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, - "??????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "???????????????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "?????RetroArch?????????") -MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, - "?????????????(SAMBA)?") -MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, - "????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, - "???????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, - "????????????(SSH)?") -MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, - "?????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, - "??????????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "??????????????????????\n" - "120Hz??????????60Hz???????\n" - "????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "????????????????????????\n" - "??(??)?") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "???????GPU???CPU????GPU????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - "??????????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, - "?????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, - "?????????(Hz)?") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "??????????") -MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, - "?????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "??????????????") -MSG_HASH(MSG_APPENDED_DISK, - "Appended disk") -MSG_HASH(MSG_APPLICATION_DIR, - "??????") -MSG_HASH(MSG_APPLYING_SHADER, - "Applying shader") -MSG_HASH(MSG_AUDIO_MUTED, - "???") -MSG_HASH(MSG_AUDIO_UNMUTED, - "?????") -MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "?? autoconf ?????") -MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "???????????") -MSG_HASH(MSG_AUTOSAVE_FAILED, - "??????????") -MSG_HASH(MSG_AUTO_SAVE_STATE_TO, - "???????") -MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, - "?? SRAM ??") -MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, - "Bringing up command interface on port") -MSG_HASH(MSG_BYTES, - "??") -MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, - "??????????????????") -MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, - "?????????????????.") -MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, - "????magic numbers??...") -MSG_HASH(MSG_COMPILED_AGAINST_API, - "Compiled against API") -MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, - "?????????????????") -MSG_HASH(MSG_CONNECTED_TO, - "???") -MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, - "???CRC32s?????????????") -MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, - "???????????????") -MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, - "??????????") -MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, - "Core options file created successfully.") -MSG_HASH(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, - "Could not find any next driver") -MSG_HASH(MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, - "Could not find compatible system.") -MSG_HASH(MSG_COULD_NOT_FIND_VALID_DATA_TRACK, - "??????????") -MSG_HASH(MSG_COULD_NOT_OPEN_DATA_TRACK, - "???????") -MSG_HASH(MSG_COULD_NOT_READ_CONTENT_FILE, - "????????") -MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, - "??????????.") -MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, - "????????.") -MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, - "CRC32 checksum mismatch between content file and saved content checksum in replay file header; replay highly likely to desync on playback.") -MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, - "Custom timing given") -MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, - "?????????") -MSG_HASH(MSG_DECOMPRESSION_FAILED, - "??????") -MSG_HASH(MSG_DETECTED_VIEWPORT_OF, - "Detected viewport of") -MSG_HASH(MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, - "Did not find a valid content patch.") -MSG_HASH(MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, - "Disconnect device from a valid port.") -MSG_HASH(MSG_DISK_CLOSED, - "???") -MSG_HASH(MSG_DISK_EJECTED, - "???") -MSG_HASH(MSG_DOWNLOADING, - "????") -MSG_HASH(MSG_DOWNLOAD_FAILED, - "????") -MSG_HASH(MSG_ERROR, - "??") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, - "Libretro core requires content, but nothing was provided.") -MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, - "Libretro core requires special content, but none were provided.") -MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, - "Error parsing arguments.") -MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, - "Error saving core options file.") -MSG_HASH(MSG_ERROR_SAVING_REMAP_FILE, - "Error saving remap file.") -MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, - "Error saving shader preset.") -MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, - "????????") -MSG_HASH(MSG_EXTRACTING, - "????") -MSG_HASH(MSG_EXTRACTING_FILE, - "????") -MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, - "???????") -MSG_HASH(MSG_FAILED_TO, - "Failed to") -MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, - "Failed to accept incoming spectator.") -MSG_HASH(MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, - "Failed to allocate memory for patched content...") -MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, - "Failed to apply shader.") -MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, - "Failed to bind socket.") -MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, - "???????") -MSG_HASH(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, - "????????????") -MSG_HASH(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, - "??????????.") -MSG_HASH(MSG_FAILED_TO_LOAD, - "????") -MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, - "??????") -MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, - "????????") -MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, - "Failed to load overlay.") -MSG_HASH(MSG_FAILED_TO_LOAD_STATE, - "Failed to load state from") -MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, - "??libretro????") -MSG_HASH(MSG_FAILED_TO_PATCH, - "??????") -MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, - "Failed to receive header from client.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, - "Failed to receive nickname.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, - "Failed to receive nickname from host.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, - "Failed to receive nickname size from host.") -MSG_HASH(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, - "Failed to receive SRAM data from host.") -MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, - "Failed to remove disk from tray.") -MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, - "????????") -MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, - "Failed to save SRAM") -MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, - "Failed to save state to") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, - "??????.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, - "????????.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, - "??????????.") -MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, - "??????????.") -MSG_HASH(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, - "??SRAM????????.") -MSG_HASH(MSG_FAILED_TO_START_AUDIO_DRIVER, - "??????????????????????") -MSG_HASH(MSG_FAILED_TO_START_MOVIE_RECORD, - "????????.") -MSG_HASH(MSG_FAILED_TO_START_RECORDING, - "Failed to start recording.") -MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, - "Failed to take screenshot.") -MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, - "Failed to undo load state.") -MSG_HASH(MSG_FAILED_TO_UNDO_SAVE_STATE, - "Failed to undo save state.") -MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, - "Failed to unmute audio.") -MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, - "Fatal error received in") -MSG_HASH(MSG_FILE_NOT_FOUND, - "?????") -MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, - "Found auto savestate in") -MSG_HASH(MSG_FOUND_DISK_LABEL, - "Found disk label") -MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, - "Found first data track on file") -MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, - "Found last state slot") -MSG_HASH(MSG_FOUND_SHADER, - "Found shader") -MSG_HASH(MSG_FRAMES, - "?") -MSG_HASH(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, - "Per-Game Options: game-specific core options found at") -MSG_HASH(MSG_GOT_INVALID_DISK_INDEX, - "Got invalid disk index.") -MSG_HASH(MSG_GRAB_MOUSE_STATE, - "??????") -MSG_HASH(MSG_GAME_FOCUS_ON, - "Game focus on") -MSG_HASH(MSG_GAME_FOCUS_OFF, - "Game focus off") -MSG_HASH(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, - "Libretro core is hardware rendered. Must use post-shaded recording as well.") -MSG_HASH(MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, - "Inflated checksum did not match CRC32.") -MSG_HASH(MSG_INPUT_CHEAT, - "?????") -MSG_HASH(MSG_INPUT_CHEAT_FILENAME, - "Cheat Filename") -MSG_HASH(MSG_INPUT_PRESET_FILENAME, - "Preset Filename") -MSG_HASH(MSG_INTERFACE, - "??") -MSG_HASH(MSG_INTERNAL_STORAGE, - "????") -MSG_HASH(MSG_REMOVABLE_STORAGE, - "Removable Storage") -MSG_HASH(MSG_INVALID_NICKNAME_SIZE, - "Invalid nickname size.") -MSG_HASH(MSG_IN_BYTES, - "(??)") -MSG_HASH(MSG_IN_GIGABYTES, - "(???)") -MSG_HASH(MSG_IN_MEGABYTES, - "(???)") -MSG_HASH(MSG_LIBRETRO_ABI_BREAK, - "is compiled against a different version of libretro than this libretro implementation.") -MSG_HASH(MSG_LIBRETRO_FRONTEND, - "?libretro??????") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, - "?????? #%d.") -MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, - "?????? #-1 (auto).") -MSG_HASH(MSG_LOADING, - "????") -MSG_HASH(MSG_FIRMWARE, - "???????????") -MSG_HASH(MSG_LOADING_CONTENT_FILE, - "????????") -MSG_HASH(MSG_LOADING_HISTORY_FILE, - "????????") -MSG_HASH(MSG_LOADING_STATE, - "??????") -MSG_HASH(MSG_MEMORY, - "??") -MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "???????BSV1???") -MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, - "??????????????????????????") -MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, - "??????.") -MSG_HASH(MSG_MOVIE_RECORD_STOPPED, - "???????") -MSG_HASH(MSG_NETPLAY_FAILED, - "??????????") -MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "????????????") -MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, - "????????") -MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, - "?????????") -MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, - "???????") -MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "???????") -MSG_HASH(MSG_PAUSED, - "???") -MSG_HASH(MSG_PROGRAM, - "RetroArch") -MSG_HASH(MSG_READING_FIRST_DATA_TRACK, - "????????...") -MSG_HASH(MSG_RECEIVED, - "????") -MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "???????????") -MSG_HASH(MSG_RECORDING_TO, - "???") -MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, - "?????????") -MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, - "Redirecting save file to") -MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, - "Redirecting savestate to") -MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, - "Remap file saved successfully.") -MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, - "Removed disk from tray.") -MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, - "????????") -MSG_HASH(MSG_RESET, - "??") -MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "???????????????") -MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, - "???????") -MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, - "Shaders: restoring default shader preset to") -MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, - "Reverting savefile directory to") -MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, - "Reverting savestate directory to") -MSG_HASH(MSG_REWINDING, - "?????") -MSG_HASH(MSG_REWIND_INIT, - "Initializing rewind buffer with size") -MSG_HASH(MSG_REWIND_INIT_FAILED, - "?????????. ??????.") -MSG_HASH(MSG_REWIND_INIT_FAILED_THREADED_AUDIO, - "Implementation uses threaded audio. Cannot use rewind.") -MSG_HASH(MSG_REWIND_REACHED_END, - "????????.") -MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, - "???????") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT, - "?????? #%d.") -MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, - "?????? #-1 (auto).") -MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, - "?????") -MSG_HASH(MSG_SAVING_RAM_TYPE, - "?? RAM ??") -MSG_HASH(MSG_SAVING_STATE, - "???") -MSG_HASH(MSG_SCANNING, - "???") -MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, - "??????????") -MSG_HASH(MSG_SENDING_COMMAND, - "????") -MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, - "Several patches are explicitly defined, ignoring all...") -MSG_HASH(MSG_SHADER, - "Shader") -MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, - "Shader preset saved successfully.") -MSG_HASH(MSG_SKIPPING_SRAM_LOAD, - "?? SRAM ???") -MSG_HASH(MSG_SLOW_MOTION, - "????") -MSG_HASH(MSG_SLOW_MOTION_REWIND, - "??????") -MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, - "SRAM will not be saved.") -MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, - "????.") -MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, - "Starting movie record to") -MSG_HASH(MSG_STATE_SIZE, - "State size") -MSG_HASH(MSG_STATE_SLOT, - "?????") -MSG_HASH(MSG_TAKING_SCREENSHOT, - "???") -MSG_HASH(MSG_TO, - "?") -MSG_HASH(MSG_UNDID_LOAD_STATE, - "????????") -MSG_HASH(MSG_UNDOING_SAVE_STATE, - "??????") -MSG_HASH(MSG_UNKNOWN, - "??") -MSG_HASH(MSG_UNPAUSED, - "?????") -MSG_HASH(MSG_UNRECOGNIZED_COMMAND, - "???????") -MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, - "Using core name for new config.") -MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, - "??libretro??????????") -MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, - "Connect device from a valid port.") -MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "???????") -MSG_HASH(MSG_VALUE_REBOOTING, - "????") -MSG_HASH(MSG_VALUE_SHUTTING_DOWN, - "????") -MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, - "libretro API??") -MSG_HASH(MSG_VIEWPORT_SIZE_CALCULATION_FAILED, - "Viewport size calculation failed! Will continue using raw data. This will probably not work right ...") -MSG_HASH(MSG_VIRTUAL_DISK_TRAY, - "virtual disk tray.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, - "Desired audio latency in milliseconds. Might not be honored if the audio driver can't provide given latency.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "??/?????") -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Helps smooth out imperfections in timing when synchronizing audio and video at the same time. Be aware that if disabled, proper synchronization is nearly impossible to obtain." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CAMERA_ALLOW, - "?????????????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_LOCATION_ALLOW, - "Allow or disallow location services access by cores." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, - "Maximum amount of users supported by RetroArch." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, - "Influence how input polling is done inside RetroArch. Setting it to 'Early' or 'Late' can result in less latency, depending on your configuration." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, - "Allows any user to control the menu. If disabled, only User 1 can control the menu." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "Audio volume (in dB). 0 dB is normal volume, no gain applied." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "????????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "How far an axis must be tilted to result in a button press." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, - "Amount of seconds to wait until proceeding to the next bind." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Describes the period of which turbo-enabled buttons toggle. Numbers are described in frames." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, - "Describes how long the period of a turbo-enabled button should be. Numbers are described in frames." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_VSYNC, - "???????????????????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, - "Allow cores to set rotation. When disabled, rotation requests are ignored. Useful for setups where one manually rotates the screen." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, - "Some cores might have a shutdown feature. If enabled, it will prevent the core from shutting RetroArch down. Instead, it loads a dummy core." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, - "Check if all the required firmware is present before attempting to load content." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Vertical refresh rate of your screen. Used to calculate a suitable audio input rate. NOTE: This will be ignored if 'Threaded Video' is enabled." - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_ENABLE, - "???????" - ) -MSG_HASH( - MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "The maximum change in audio input rate. You may want to increase this to enable very large changes in timing, for example running PAL cores on NTSC displays, at the cost of inaccurate audio pitch." - ) -MSG_HASH( - MSG_FAILED, - "???" - ) -MSG_HASH( - MSG_SUCCEEDED, - "???" - ) -MSG_HASH( - MSG_DEVICE_NOT_CONFIGURED, - "???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, - "??? Cursor List" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, - "??? - ??? : ???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, - "??? - ??? : ???" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DISABLED, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_ENABLED, - "??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, - "??????" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, - "??? - ??? : Origin") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, - "??? - ??? : Franchise") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, - "??? - ??? : ESRB Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, - "??? - ??? : ELSPA Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, - "??? - ??? : PEGI Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, - "??? - ??? : CERO Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, - "??? - ??? : BBFC Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, - "??? - ??? : ?????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, - "??? - ??? : ????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, - "??? - ??? : ????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, - "??? - ??? : Edge Magazine Issue") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, - "??? - ??? : Edge Magazine Rating") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, - "?????") -MSG_HASH(MSG_WIFI_SCAN_COMPLETE, - "Wi-Fi ?????") -MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, - "??????...") -MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, - "???????????") -MSG_HASH(MSG_NETPLAY_LAN_SCANNING, - "????????...") -MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "?????????????") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Enable or disable composition (Windows only).") -MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "??????????????/???????") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, - "?????????????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "??????") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, - "Use the same controls for both the menu and the game. Applies to the keyboard.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "???????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "?? %d ????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "??????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, - "???") -MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, - "??") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "??????????????") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, - "????????????????????") -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "??URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "URL??" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_START, - "??" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, - "Bokeh") +#include +#include + +#include +#include + +#include "../msg_hash.h" +#include "../configuration.h" +#include "../verbosity.h" + +#if defined(_MSC_VER) && !defined(_XBOX) +/* https://support.microsoft.com/en-us/kb/980263 */ +#pragma execution_character_set("utf-8") +#pragma warning( disable : 4566 ) +#endif + +int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len) +{ + uint32_t driver_hash = 0; + settings_t *settings = config_get_ptr(); + + if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && + msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) + { + unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; + + switch (idx) + { + case RARCH_FAST_FORWARD_KEY: + snprintf(s, len, + "在快进和正常速度之间切换。" + ); + break; + case RARCH_FAST_FORWARD_HOLD_KEY: + snprintf(s, len, + "按住来快进。 \n" + " \n" + "放开按键来取消快进。" + ); + break; + case RARCH_PAUSE_TOGGLE: + snprintf(s, len, + "在暂停和不暂停状态间切换。"); + break; + case RARCH_FRAMEADVANCE: + snprintf(s, len, + "Frame advance when content is paused."); + break; + case RARCH_SHADER_NEXT: + snprintf(s, len, + "应用文件夹中的下一个Shader特效。"); + break; + case RARCH_SHADER_PREV: + snprintf(s, len, + "应用文件夹中的上一个Shader特效。"); + break; + case RARCH_CHEAT_INDEX_PLUS: + case RARCH_CHEAT_INDEX_MINUS: + case RARCH_CHEAT_TOGGLE: + snprintf(s, len, + "金手指。"); + break; + case RARCH_RESET: + snprintf(s, len, + "重置游戏内容。"); + break; + case RARCH_SCREENSHOT: + snprintf(s, len, + "截图。"); + break; + case RARCH_MUTE: + snprintf(s, len, + "静音/取消静音。"); + break; + case RARCH_OSK: + snprintf(s, len, + "显示/隐藏屏显键盘。"); + break; + case RARCH_NETPLAY_FLIP: + snprintf(s, len, + "Netplay flip users."); + break; + case RARCH_SLOWMOTION: + snprintf(s, len, + "按住并以慢动作运行。"); + break; + case RARCH_ENABLE_HOTKEY: + snprintf(s, len, + "启用其他热键. \n" + " \n" + "If this hotkey is bound to either\n" + "a keyboard, joybutton or joyaxis, \n" + "all other hotkeys will be enabled only \n" + "if this one is held at the same time. \n" + " \n" + "This is useful for RETRO_KEYBOARD centric \n" + "implementations which query a large area of \n" + "the keyboard, where it is not desirable that \n" + "hotkeys get in the way. \n" + " \n" + "Alternatively, all hotkeys for keyboard \n" + "could be disabled by the user."); + break; + case RARCH_VOLUME_UP: + snprintf(s, len, + "提高音量。"); + break; + case RARCH_VOLUME_DOWN: + snprintf(s, len, + "降低音量。"); + break; + case RARCH_OVERLAY_NEXT: + snprintf(s, len, + "切换到下一个屏幕覆层。将会循环选择。"); + break; + case RARCH_DISK_EJECT_TOGGLE: + snprintf(s, len, + "切换弹出光盘。 \n" + " \n" + "用于多光盘内容。 "); + break; + case RARCH_DISK_NEXT: + case RARCH_DISK_PREV: + snprintf(s, len, + "磁盘镜像周期。弹出后使用。 \n" + " \n" + "再次开关弹出完成。"); + break; + case RARCH_GRAB_MOUSE_TOGGLE: + snprintf(s, len, + "鼠标捕获开关 \n" + " \n" + "当鼠标捕获开启时,RetroArch将会隐藏鼠标指针,并 \n" + "使之控制在窗口中。这使得一些依靠鼠标相对位置的程 \n" + "序能更好运行。"); + break; + case RARCH_MENU_TOGGLE: + snprintf(s, len, "切换菜单显示。"); + break; + case RARCH_LOAD_STATE_KEY: + snprintf(s, len, + "加载游戏状态。"); + break; + case RARCH_FULLSCREEN_TOGGLE_KEY: + snprintf(s, len, + "切换到全屏模式。"); + break; + case RARCH_QUIT_KEY: + snprintf(s, len, + "用于正常退出 RetroArch 的按键 \n" + " \n" + "使用任何强制手段来退出RetroArch(如发送SIGKILL) \n" + "可能导致系统无法正确存储数据。" +#ifdef __unix__ + "\n在类Unix系统上,SIGINT/SIGTERM信号能够保证正常 \n" + "关闭程序。" +#endif + ""); + break; + case RARCH_STATE_SLOT_PLUS: + case RARCH_STATE_SLOT_MINUS: + snprintf(s, len, + "状态存储槽 \n" + " \n" + "当槽位选择为0时,状态存档将以*.state命名(或其他 \n" + "在命令行中定义的名称)。 \n" + " \n" + "当状态槽不为0时,路径将会设为,其中 \n" + "是状态槽的索引。"); + break; + case RARCH_SAVE_STATE_KEY: + snprintf(s, len, + "保存游戏状态。"); + break; + case RARCH_REWIND: + snprintf(s, len, + "按住按钮来回溯 \n" + " \n" + "回溯功能必须被启用。"); + break; + case RARCH_MOVIE_RECORD_TOGGLE: + snprintf(s, len, + "在录制和非录制模式切换。"); + break; + default: + if (string_is_empty(s)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); + break; + } + + return 0; + } + + switch (msg) + { + case MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS: + snprintf(s, len, "你的登陆信息 \n" + "Retro Achievements 账号. \n" + " \n" + "访问 retroachievements.org 并注册 \n" + "以获取一个免费账号. \n" + " \n" + "在你注册以后, 你需要 \n" + "在RetroArch输入你的 \n" + "账号以及密码."); + break; + case MENU_ENUM_LABEL_CHEEVOS_USERNAME: + snprintf(s, len, "你的Retro Achievements账号的用户名。"); + break; + case MENU_ENUM_LABEL_CHEEVOS_PASSWORD: + snprintf(s, len, "你的Retro Achievements账号的密码。"); + break; + case MENU_ENUM_LABEL_USER_LANGUAGE: + snprintf(s, len, "依据选择的语言来本地化菜单和其他屏显消息。 \n" + " \n" + "需要重新启动来使之生效。 \n" + " \n" + "注意:可能不是所有的语言都已完成翻译工作。 \n" + " \n" + "若一个语言没有被翻译,则会退回到英语显示。"); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_PATH: + snprintf(s, len, "改变屏显文字的字体。"); + break; + case MENU_ENUM_LABEL_GAME_SPECIFIC_OPTIONS: + snprintf(s, len, "自动加载游戏内容指定的核心选项."); + break; + case MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE: + snprintf(s, len, "自动加载覆盖配置。"); + break; + case MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE: + snprintf(s, len, "自动加载输入重映射文件."); + break; + case MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE: + snprintf(s, len, "Sort save states in folders \n" + "named after the libretro core used."); + break; + case MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE: + snprintf(s, len, "Sort save files in folders \n" + "named after the libretro core used."); + break; + case MENU_ENUM_LABEL_RESUME_CONTENT: + snprintf(s, len, "Exits from the menu and returns back \n" + "to the content."); + break; + case MENU_ENUM_LABEL_RESTART_CONTENT: + snprintf(s, len, "Restarts the content from the beginning."); + break; + case MENU_ENUM_LABEL_CLOSE_CONTENT: + snprintf(s, len, "关闭内容并从内存中卸载。"); + break; + case MENU_ENUM_LABEL_UNDO_LOAD_STATE: + snprintf(s, len, "If a state was loaded, content will \n" + "go back to the state prior to loading."); + break; + case MENU_ENUM_LABEL_UNDO_SAVE_STATE: + snprintf(s, len, "如果状态被覆盖,它将 \n" + "它将回滚到上一保存的状态。"); + break; + case MENU_ENUM_LABEL_TAKE_SCREENSHOT: + snprintf(s, len, "创建一份截图. \n" + " \n" + "截图文件将会存放在 \n" + "截图目录之中."); + break; + case MENU_ENUM_LABEL_RUN: + snprintf(s, len, "启动内容."); + break; + case MENU_ENUM_LABEL_INFORMATION: + snprintf(s, len, "显示本内容的额外 \n" + "元数据信息."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CONFIG: + snprintf(s, len, "配置文件."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE: + snprintf(s, len, "压缩归档文件."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_RECORD_CONFIG: + snprintf(s, len, "记录配置文件."); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CURSOR: + snprintf(s, len, "数据库指针文件。"); + break; + case MENU_ENUM_LABEL_FILE_CONFIG: + snprintf(s, len, "配置文件."); + break; + case MENU_ENUM_LABEL_SCAN_THIS_DIRECTORY: + snprintf(s, len, + "选择本项以扫描当前 \n" + "目录中的内容."); + break; + case MENU_ENUM_LABEL_USE_THIS_DIRECTORY: + snprintf(s, len, + "选择本目录作为指定目录."); + break; + case MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY: + snprintf(s, len, + "内容数据库目录。 \n" + " \n" + "到内容数据库目录的 \n" + "路径。"); + break; + case MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY: + snprintf(s, len, + "缩略图目录. \n" + " \n" + "用以存放缩略图."); + break; + case MENU_ENUM_LABEL_LIBRETRO_INFO_PATH: + snprintf(s, len, + "核心Core信息目录. \n" + " \n" + "用于搜索libretro核心信息 \n" + "的目录。"); + break; + case MENU_ENUM_LABEL_PLAYLIST_DIRECTORY: + snprintf(s, len, + "运行列表目录. \n" + " \n" + "保存所有播放列表到 \n" + "此目录。"); + break; + case MENU_ENUM_LABEL_DUMMY_ON_CORE_SHUTDOWN: + snprintf(s, len, + "某些libretro核心可能会 \n" + "支持关机特性. \n" + " \n" + "If this option is left disabled, \n" + "selecting the shutdown procedure \n" + "would trigger RetroArch being shut \n" + "down. \n" + " \n" + "Enabling this option will load a \n" + "dummy core instead so that we remain \n" + "inside the menu and RetroArch won't \n" + "shutdown."); + break; + case MENU_ENUM_LABEL_CHECK_FOR_MISSING_FIRMWARE: + snprintf(s, len, + "Some cores might need \n" + "firmware or bios files. \n" + " \n" + "If this option is disabled, \n" + "it will try to load even if such \n" + "firmware is missing. \n" + "down. \n"); + break; + case MENU_ENUM_LABEL_PARENT_DIRECTORY: + snprintf(s, len, + "回到上级目录。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_SHADER_PRESET: + snprintf(s, len, + "Shader预设文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_SHADER: + snprintf(s, len, + "Shader文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_REMAP: + snprintf(s, len, + "控制重映射文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CHEAT: + snprintf(s, len, + "金手指文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY: + snprintf(s, len, + "覆层文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_RDB: + snprintf(s, len, + "数据库文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_FONT: + snprintf(s, len, + "TrueType字体文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE: + snprintf(s, len, + "普通文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_MOVIE_OPEN: + snprintf(s, len, + "视频 \n" + " \n" + "选择文件并使用视频播放器打开。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_MUSIC_OPEN: + snprintf(s, len, + "音乐 \n" + " \n" + "选择文件并使用音乐播放器打开。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE: + snprintf(s, len, + "图片文件。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_IMAGE_OPEN_WITH_VIEWER: + snprintf(s, len, + "图片 \n" + " \n" + "选择文件并使用图片浏览器打开。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION: + snprintf(s, len, + "Libretro核心 \n" + " \n" + "选中核心将会使其关联至游戏。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_CORE: + snprintf(s, len, + "Libretro核心 \n" + " \n" + "选择该文件使 RetroArch 加载该核心。"); + break; + case MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY: + snprintf(s, len, + "目录 \n" + " \n" + "选择并打开该文件夹。"); + break; + case MENU_ENUM_LABEL_CACHE_DIRECTORY: + snprintf(s, len, + "缓存目录 \n" + " \n" + "被RetroArch解压的游戏内容会临时存放到这个文 \n" + "件夹。"); + break; + case MENU_ENUM_LABEL_HISTORY_LIST_ENABLE: + snprintf(s, len, + "若开启,所有在RetroArch中加载过的文件 \n" + "都会自动的放入最近使用历史列表中。"); + break; + case MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY: + snprintf(s, len, + "文件浏览器目录 \n" + " \n" + "设置文件浏览器的初始目录。"); + break; + case MENU_ENUM_LABEL_INPUT_POLL_TYPE_BEHAVIOR: + snprintf(s, len, + "影响输入轮询过程在RetroArch中的执行方式。 \n" + " \n" + "稍早 - 输入轮询过程将在帧生成之前执行。 \n" + "正常 - 输入轮询过程将在被请求时执行。 \n" + "稍晚 - 输入轮询过程将在每一帧的首次请求时执行。 \n" + " \n" + "依据设置的不同,设置为“稍早”或“稍晚”可以获得较低 \n" + "的时延。 \n" + "当在进行在线游戏时,不管设置的值如何,都只会启用 \n" + "正常模式进行输入轮询过程。" + ); + break; + case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_HIDE_UNBOUND: + snprintf(s, len, + "隐藏不被核心使用的输入描述。"); + break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE: + snprintf(s, len, + "显示器的视频刷新率。 \n" + "可被用来计算一个合适的音频输入率。"); + break; + case MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE: + snprintf(s, len, + "强制关闭sRGB帧缓冲支持。\n" + "\n" + "某些在Windows上的Intel的OpenGL驱动会对sRGB帧缓 \n" + "冲支持产生问题,需要启用以强制关闭程序对其的使用。"); + break; + case MENU_ENUM_LABEL_AUDIO_ENABLE: + snprintf(s, len, + "启用音频输出。"); + break; + case MENU_ENUM_LABEL_AUDIO_SYNC: + snprintf(s, len, + "同步音频(推荐)。"); + break; + case MENU_ENUM_LABEL_AUDIO_LATENCY: + snprintf(s, len, + "Desired audio latency in milliseconds. \n" + "Might not be honored if the audio driver \n" + "can't provide given latency."); + break; + case MENU_ENUM_LABEL_VIDEO_ALLOW_ROTATE: + snprintf(s, len, + "Allow cores to set rotation. If false, \n" + "rotation requests are honored, but ignored.\n\n" + "Used for setups where one manually rotates \n" + "the monitor."); + break; + case MENU_ENUM_LABEL_INPUT_DESCRIPTOR_LABEL_SHOW: + snprintf(s, len, + "Show the input descriptors set by the core \n" + "instead of the default ones."); + break; + case MENU_ENUM_LABEL_CONTENT_HISTORY_SIZE: + snprintf(s, len, + "Number of entries that will be kept in \n" + "content history playlist."); + break; + case MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN: + snprintf(s, len, + "To use windowed mode or not when going \n" + "fullscreen."); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_SIZE: + snprintf(s, len, + "屏显信息的字体大小."); + break; + case MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX: + snprintf(s, len, + "Automatically increment slot index on each save, \n" + "generating multiple savestate files. \n" + "When the content is loaded, state slot will be \n" + "set to the highest existing value (last savestate)."); + break; + case MENU_ENUM_LABEL_FPS_SHOW: + snprintf(s, len, + "Enables displaying the current frames \n" + "per second."); + break; + case MENU_ENUM_LABEL_VIDEO_FONT_ENABLE: + snprintf(s, len, + "显示/隐藏屏显信息."); + break; + case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_X: + case MENU_ENUM_LABEL_VIDEO_MESSAGE_POS_Y: + snprintf(s, len, + "Offset for where messages will be placed \n" + "onscreen. Values are in range [0.0, 1.0]."); + break; + case MENU_ENUM_LABEL_INPUT_OVERLAY_ENABLE: + snprintf(s, len, + "Enable or disable the current overlay."); + break; + case MENU_ENUM_LABEL_INPUT_OVERLAY_HIDE_IN_MENU: + snprintf(s, len, + "Hide the current overlay from appearing \n" + "inside the menu."); + break; + case MENU_ENUM_LABEL_OVERLAY_PRESET: + snprintf(s, len, + "Path to input overlay."); + break; + case MENU_ENUM_LABEL_OVERLAY_OPACITY: + snprintf(s, len, + "Overlay opacity."); + break; + case MENU_ENUM_LABEL_INPUT_BIND_TIMEOUT: + snprintf(s, len, + "Input bind timer timeout (in seconds). \n" + "Amount of seconds to wait until proceeding \n" + "to the next bind."); + break; + case MENU_ENUM_LABEL_OVERLAY_SCALE: + snprintf(s, len, + "Overlay scale."); + break; + case MENU_ENUM_LABEL_AUDIO_OUTPUT_RATE: + snprintf(s, len, + "音频输出采样率."); + break; + case MENU_ENUM_LABEL_VIDEO_SHARED_CONTEXT: + snprintf(s, len, + "Set to true if hardware-rendered cores \n" + "should get their private context. \n" + "Avoids having to assume hardware state changes \n" + "inbetween frames." + ); + break; + case MENU_ENUM_LABEL_CORE_LIST: + snprintf(s, len, + "加载内核. \n" + " \n" + "Browse for a libretro core \n" + "implementation. Where the browser \n" + "starts depends on your Core Directory \n" + "path. If blank, it will start in root. \n" + " \n" + "If Core Directory is a directory, the menu \n" + "will use that as top folder. If Core \n" + "Directory is a full path, it will start \n" + "in the folder where the file is."); + break; + case MENU_ENUM_LABEL_VALUE_MENU_ENUM_CONTROLS_PROLOG: + snprintf(s, len, + "你可以使用下述的方式通过游戏控制器或者键盘来对\n" + "菜单进行控制:\n" + " \n" + ); + break; + case MENU_ENUM_LABEL_WELCOME_TO_RETROARCH: + snprintf(s, len, + "欢迎来到 RetroArch\n" + ); + break; + case MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING_DESC: + { + /* Work around C89 limitations */ + char u[501]; + const char * t = + "RetroArch relies on an unique form of\n" + "audio/video synchronization where it needs to be\n" + "calibrated against the refresh rate of your\n" + "display for best performance results.\n" + " \n" + "If you experience any audio crackling or video\n" + "tearing, usually it means that you need to\n" + "calibrate the settings. Some choices below:\n" + " \n"; + snprintf(u, sizeof(u), /* can't inline this due to the printf arguments */ + "a) Go to '%s' -> '%s', and enable\n" + "'Threaded Video'. Refresh rate will not matter\n" + "in this mode, framerate will be higher,\n" + "but video might be less smooth.\n" + "b) Go to '%s' -> '%s', and look at\n" + "'%s'. Let it run for\n" + "2048 frames, then press 'OK'.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO)); + strlcpy(s, t, len); + strlcat(s, u, len); + } + break; + case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: + snprintf(s, len, + "若要扫描游戏内容,请访问菜单「%s」 \n" + "并选择「%s」或者「%s」。\n" + " \n" + "文件将会同数据库中的条目进行对比。 \n" + "若文件匹配某个条目,则它会被加入收藏中。 \n" + " \n" + "你可以无需每次都打开文件浏览器,而可以直接 \n" + "通过菜单项「%s」->「%s」 来访\n" + "问这些游戏内容。 \n" + " \n" + "注意:不是所有核心的游戏内容都支持扫描录入。" + , + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SCAN_FILE), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST) + ); + break; + case MENU_ENUM_LABEL_VALUE_EXTRACTING_PLEASE_WAIT: + snprintf(s, len, + "欢迎使用RetroArch\n" + "\n" + "正在解压必要文件, 请稍等。\n" + "这可能需要一点时间……\n" + ); + break; + case MENU_ENUM_LABEL_INPUT_DRIVER: + if (settings) + driver_hash = msg_hash_calculate(settings->input.driver); + + switch (driver_hash) + { + case MENU_LABEL_INPUT_DRIVER_UDEV: + snprintf(s, len, + "udev Input driver. \n" + " \n" + "This driver can run without X. \n" + " \n" + "It uses the recent evdev joypad API \n" + "for joystick support. It supports \n" + "hotplugging and force feedback (if \n" + "supported by device). \n" + " \n" + "The driver reads evdev events for keyboard \n" + "support. It also supports keyboard callback, \n" + "mice and touchpads. \n" + " \n" + "By default in most distros, /dev/input nodes \n" + "are root-only (mode 600). You can set up a udev \n" + "rule which makes these accessible to non-root." + ); + break; + case MENU_LABEL_INPUT_DRIVER_LINUXRAW: + snprintf(s, len, + "linuxraw Input driver. \n" + " \n" + "This driver requires an active TTY. Keyboard \n" + "events are read directly from the TTY which \n" + "makes it simpler, but not as flexible as udev. \n" "Mice, etc, are not supported at all. \n" + " \n" + "This driver uses the older joystick API \n" + "(/dev/input/js*)."); + break; + default: + snprintf(s, len, + "Input driver.\n" + " \n" + "Depending on video driver, it might \n" + "force a different input driver."); + break; + } + break; + case MENU_ENUM_LABEL_LOAD_CONTENT_LIST: + snprintf(s, len, + "加载游戏内容 \n" + "通过浏览来加载游戏内容。 \n" + " \n" + "你需要同时提供一个“核心”和游戏内容文 \n" + "件才能启动并加载游戏内容。 \n" + " \n" + "设置“文件浏览器目录”可以指定以哪个位 \n" + "置为文件浏览器的默认目录以方便加载。 \n" + "若没有设置,默认以根目录为基准。 \n" + " \n" + "文件浏览器会以上次加载的核心所支持的 \n" + "扩展名进行过滤,并使用该核心来加载游 \n" + "戏内容。" + ); + break; + case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY: + snprintf(s, len, + "从历史记录中加载内容. \n" + " \n" + "As content is loaded, content and libretro \n" + "core combinations are saved to history. \n" + " \n" + "The history is saved to a file in the same \n" + "directory as the RetroArch config file. If \n" + "no config file was loaded in startup, history \n" + "will not be saved or loaded, and will not exist \n" + "in the main menu." + ); + break; + case MENU_ENUM_LABEL_VIDEO_DRIVER: + snprintf(s, len, + "当前视频驱动."); + + if (string_is_equal(settings->video.driver, "gl")) + { + snprintf(s, len, + "OpenGL视频驱动. \n" + " \n" + "This driver allows libretro GL cores to \n" + "be used in addition to software-rendered \n" + "core implementations.\n" + " \n" + "Performance for software-rendered and \n" + "libretro GL core implementations is \n" + "dependent on your graphics card's \n" + "underlying GL driver)."); + } + else if (string_is_equal(settings->video.driver, "sdl2")) + { + snprintf(s, len, + "SDL 2 视频驱动.\n" + " \n" + "This is an SDL 2 software-rendered video \n" + "driver.\n" + " \n" + "Performance for software-rendered libretro \n" + "core implementations is dependent \n" + "on your platform SDL implementation."); + } + else if (string_is_equal(settings->video.driver, "sdl1")) + { + snprintf(s, len, + "SDL 视频驱动.\n" + " \n" + "This is an SDL 1.2 software-rendered video \n" + "driver.\n" + " \n" + "Performance is considered to be suboptimal. \n" + "Consider using it only as a last resort."); + } + else if (string_is_equal(settings->video.driver, "d3d")) + { + snprintf(s, len, + "Direct3D 视频驱动. \n" + " \n" + "Performance for software-rendered cores \n" + "is dependent on your graphic card's \n" + "underlying D3D driver)."); + } + else if (string_is_equal(settings->video.driver, "exynos")) + { + snprintf(s, len, + "Exynos-G2D 视频驱动. \n" + " \n" + "This is a low-level Exynos video driver. \n" + "Uses the G2D block in Samsung Exynos SoC \n" + "for blit operations. \n" + " \n" + "Performance for software rendered cores \n" + "should be optimal."); + } + else if (string_is_equal(settings->video.driver, "drm")) + { + snprintf(s, len, + "Plain DRM 视频驱动. \n" + " \n" + "This is a low-level video driver using. \n" + "libdrm for hardware scaling using \n" + "GPU overlays."); + } + else if (string_is_equal(settings->video.driver, "sunxi")) + { + snprintf(s, len, + "Sunxi-G2D 视频驱动. \n" + " \n" + "This is a low-level Sunxi video driver. \n" + "Uses the G2D block in Allwinner SoCs."); + } + break; + case MENU_ENUM_LABEL_AUDIO_DSP_PLUGIN: + snprintf(s, len, + "音频DSP插件.\n" + " Processes audio before it's sent to \n" + "the driver." + ); + break; + case MENU_ENUM_LABEL_AUDIO_RESAMPLER_DRIVER: + if (settings) + driver_hash = msg_hash_calculate(settings->audio.resampler); + + switch (driver_hash) + { + case MENU_LABEL_AUDIO_RESAMPLER_DRIVER_SINC: + snprintf(s, len, + "Windowed SINC implementation."); + break; + case MENU_LABEL_AUDIO_RESAMPLER_DRIVER_CC: + snprintf(s, len, + "Convoluted Cosine implementation."); + break; + default: + if (string_is_empty(s)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); + break; + } + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET: + snprintf(s, len, + "载入预设 Shader. \n" + " \n" + " Load a " +#ifdef HAVE_CG + "Cg" +#endif +#ifdef HAVE_GLSL +#ifdef HAVE_CG + "/" +#endif + "GLSL" +#endif +#ifdef HAVE_HLSL +#if defined(HAVE_CG) || defined(HAVE_HLSL) + "/" +#endif + "HLSL" +#endif + " 预设目录. \n" + "The menu shader menu is updated accordingly. \n" + " \n" + "If the CGP uses scaling methods which are not \n" + "simple, (i.e. source scaling, same scaling \n" + "factor for X/Y), the scaling factor displayed \n" + "in the menu might not be correct." + ); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_SCALE_PASS: + snprintf(s, len, + "Scale for this pass. \n" + " \n" + "The scale factor accumulates, i.e. 2x \n" + "for first pass and 2x for second pass \n" + "will give you a 4x total scale. \n" + " \n" + "If there is a scale factor for last \n" + "pass, the result is stretched to \n" + "screen with the filter specified in \n" + "'Default Filter'. \n" + " \n" + "If 'Don't Care' is set, either 1x \n" + "scale or stretch to fullscreen will \n" + "be used depending if it's not the last \n" + "pass or not." + ); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: + snprintf(s, len, + "Shader Passes. \n" + " \n" + "RetroArch allows you to mix and match various \n" + "shaders with arbitrary shader passes, with \n" + "custom hardware filters and scale factors. \n" + " \n" + "This option specifies the number of shader \n" + "passes to use. If you set this to 0, and use \n" + "Apply Shader Changes, you use a 'blank' shader. \n" + " \n" + "The Default Filter option will affect the \n" + "stretching filter."); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PARAMETERS: + snprintf(s, len, + "Shader Parameters. \n" + " \n" + "Modifies current shader directly. Will not be \n" + "saved to CGP/GLSLP preset file."); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_PARAMETERS: + snprintf(s, len, + "Shader Preset Parameters. \n" + " \n" + "Modifies shader preset currently in menu." + ); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_PASS: + snprintf(s, len, + "Path to shader. \n" + " \n" + "All shaders must be of the same \n" + "type (i.e. CG, GLSL or HLSL). \n" + " \n" + "Set Shader Directory to set where \n" + "the browser starts to look for \n" + "shaders." + ); + break; + case MENU_ENUM_LABEL_CONFIGURATION_SETTINGS: + snprintf(s, len, + "Determines how configuration files \n" + "are loaded and prioritized."); + break; + case MENU_ENUM_LABEL_CONFIG_SAVE_ON_EXIT: + snprintf(s, len, + "Saves config to disk on exit.\n" + "Useful for menu as settings can be\n" + "modified. Overwrites the config.\n" + " \n" + "#include's and comments are not \n" + "preserved. \n" + " \n" + "By design, the config file is \n" + "considered immutable as it is \n" + "likely maintained by the user, \n" + "and should not be overwritten \n" + "behind the user's back." +#if defined(RARCH_CONSOLE) || defined(RARCH_MOBILE) + "\nThis is not not the case on \n" + "consoles however, where \n" + "looking at the config file \n" + "manually isn't really an option." +#endif + ); + break; + case MENU_ENUM_LABEL_SHOW_HIDDEN_FILES: + snprintf(s, len, "显示隐藏文件和文件夹。"); + break; + case MENU_ENUM_LABEL_VIDEO_SHADER_FILTER_PASS: + snprintf(s, len, + "Hardware filter for this pass. \n" + " \n" + "If 'Don't Care' is set, 'Default \n" + "Filter' will be used." + ); + break; + case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL: + snprintf(s, len, + "Autosaves the non-volatile SRAM \n" + "at a regular interval.\n" + " \n" + "This is disabled by default unless set \n" + "otherwise. The interval is measured in \n" + "seconds. \n" + " \n" + "A value of 0 disables autosave."); + break; + case MENU_ENUM_LABEL_INPUT_BIND_DEVICE_TYPE: + snprintf(s, len, + "输入设备类型. \n" + " \n" + "Picks which device type to use. This is \n" + "relevant for the libretro core itself." + ); + break; + case MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL: + snprintf(s, len, + "设置libretro核心的log等级 \n" + "(GET_LOG_INTERFACE). \n" + " \n" + " If a log level issued by a libretro \n" + " core is below libretro_log level, it \n" + " is ignored.\n" + " \n" + " DEBUG logs are always ignored unless \n" + " verbose mode is activated (--verbose).\n" + " \n" + " DEBUG = 0\n" + " INFO = 1\n" + " WARN = 2\n" + " ERROR = 3" + ); + break; + case MENU_ENUM_LABEL_STATE_SLOT_INCREASE: + case MENU_ENUM_LABEL_STATE_SLOT_DECREASE: + snprintf(s, len, + "即时存档栏位.\n" + " \n" + " With slot set to 0, save state name is *.state \n" + " (or whatever defined on commandline).\n" + "When slot is != 0, path will be (path)(d), \n" + "where (d) is slot number."); + break; + case MENU_ENUM_LABEL_SHADER_APPLY_CHANGES: + snprintf(s, len, + "应用Shader更改. \n" + " \n" + "After changing shader settings, use this to \n" + "apply changes. \n" + " \n" + "Changing shader settings is a somewhat \n" + "expensive operation so it has to be \n" + "done explicitly. \n" + " \n" + "When you apply shaders, the menu shader \n" + "settings are saved to a temporary file (either \n" + "menu.cgp or menu.glslp) and loaded. The file \n" + "persists after RetroArch exits. The file is \n" + "saved to Shader Directory." + ); + break; + case MENU_ENUM_LABEL_MENU_TOGGLE: + snprintf(s, len, + "切换菜单."); + break; + case MENU_ENUM_LABEL_GRAB_MOUSE_TOGGLE: + snprintf(s, len, + "切换鼠标抓取.\n" + " \n" + "When mouse is grabbed, RetroArch hides the \n" + "mouse, and keeps the mouse pointer inside \n" + "the window to allow relative mouse input to \n" + "work better."); + break; + case MENU_ENUM_LABEL_DISK_NEXT: + snprintf(s, len, + "Cycles through disk images. Use after \n" + "ejecting. \n" + " \n" + " Complete by toggling eject again."); + break; + case MENU_ENUM_LABEL_VIDEO_FILTER: +#ifdef HAVE_FILTERS_BUILTIN + snprintf(s, len, + "CPU-based video filter."); +#else + snprintf(s, len, + "CPU-based video filter.\n" + " \n" + "Path to a dynamic library."); +#endif + break; + case MENU_ENUM_LABEL_AUDIO_DEVICE: + snprintf(s, len, + "Override the default audio device \n" + "the audio driver uses.\n" + "This is driver dependent. E.g.\n" +#ifdef HAVE_ALSA + " \n" + "ALSA 需要一个PCM设备." +#endif +#ifdef HAVE_OSS + " \n" + "OSS 需要一个路径 (例如. /dev/dsp)." +#endif +#ifdef HAVE_JACK + " \n" + "JACK wants portnames (e.g. system:playback1\n" + ",system:playback_2)." +#endif +#ifdef HAVE_RSOUND + " \n" + "RSound wants an IP address to an RSound \n" + "server." +#endif + ); + break; + case MENU_ENUM_LABEL_DISK_EJECT_TOGGLE: + snprintf(s, len, + "Toggles eject for disks.\n" + " \n" + "Used for multiple-disk content."); + break; + case MENU_ENUM_LABEL_ENABLE_HOTKEY: + snprintf(s, len, + "启用其他热键.\n" + " \n" + " If this hotkey is bound to either keyboard, \n" + "joybutton or joyaxis, all other hotkeys will \n" + "be disabled unless this hotkey is also held \n" + "at the same time. \n" + " \n" + "This is useful for RETRO_KEYBOARD centric \n" + "implementations which query a large area of \n" + "the keyboard, where it is not desirable that \n" + "hotkeys get in the way."); + break; + case MENU_ENUM_LABEL_REWIND_ENABLE: + snprintf(s, len, + "启用回溯倒带功能.\n" + " \n" + "这可能会严重影响性能, \n" + "所以缺省设置为关闭."); + break; + case MENU_ENUM_LABEL_LIBRETRO_DIR_PATH: + snprintf(s, len, + "核心目录. \n" + " \n" + "A directory for where to search for \n" + "libretro core implementations."); + break; + case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: + snprintf(s, len, + "自动匹配刷新率.\n" + " \n" + "The accurate refresh rate of our monitor (Hz).\n" + "This is used to calculate audio input rate with \n" + "the formula: \n" + " \n" + "audio_input_rate = game input rate * display \n" + "refresh rate / game refresh rate\n" + " \n" + "If the implementation does not report any \n" + "values, NTSC defaults will be assumed for \n" + "compatibility.\n" + " \n" + "This value should stay close to 60Hz to avoid \n" + "large pitch changes. If your monitor does \n" + "not run at 60Hz, or something close to it, \n" + "disable VSync, and leave this at its default."); + break; + case MENU_ENUM_LABEL_VIDEO_ROTATION: + snprintf(s, len, + "Forces a certain rotation \n" + "of the screen.\n" + " \n" + "The rotation is added to rotations which\n" + "the libretro core sets (see Video Allow\n" + "Rotate)."); + break; + case MENU_ENUM_LABEL_VIDEO_SCALE: + snprintf(s, len, + "全屏分辨率.\n" + " \n" + "Resolution of 0 uses the \n" + "resolution of the environment.\n"); + break; + case MENU_ENUM_LABEL_FASTFORWARD_RATIO: + snprintf(s, len, + "快进比率." + " \n" + "The maximum rate at which content will\n" + "be run when using fast forward.\n" + " \n" + " (E.g. 5.0 for 60 fps content => 300 fps \n" + "cap).\n" + " \n" + "RetroArch will go to sleep to ensure that \n" + "the maximum rate will not be exceeded.\n" + "Do not rely on this cap to be perfectly \n" + "accurate."); + break; + case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: + snprintf(s, len, + "指定输出显示器.\n" + " \n" + "0 (default) means no particular monitor \n" + "is preferred, 1 and up (1 being first \n" + "monitor), suggests RetroArch to use that \n" + "particular monitor."); + break; + case MENU_ENUM_LABEL_VIDEO_CROP_OVERSCAN: + snprintf(s, len, + "Forces cropping of overscanned \n" + "frames.\n" + " \n" + "Exact behavior of this option is \n" + "core-implementation specific."); + break; + case MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER: + snprintf(s, len, + "Only scales video in integer \n" + "steps.\n" + " \n" + "The base size depends on system-reported \n" + "geometry and aspect ratio.\n" + " \n" + "If Force Aspect is not set, X/Y will be \n" + "integer scaled independently."); + break; + case MENU_ENUM_LABEL_AUDIO_VOLUME: + snprintf(s, len, + "Audio volume, expressed in dB.\n" + " \n" + " 0 dB is normal volume. No gain will be applied.\n" + "Gain can be controlled in runtime with Input\n" + "Volume Up / Input Volume Down."); + break; + case MENU_ENUM_LABEL_AUDIO_RATE_CONTROL_DELTA: + snprintf(s, len, + "Audio rate control.\n" + " \n" + "Setting this to 0 disables rate control.\n" + "Any other value controls audio rate control \n" + "delta.\n" + " \n" + "Defines how much input rate can be adjusted \n" + "dynamically.\n" + " \n" + " Input rate is defined as: \n" + " input rate * (1.0 +/- (rate control delta))"); + break; + case MENU_ENUM_LABEL_AUDIO_MAX_TIMING_SKEW: + snprintf(s, len, + "Maximum audio timing skew.\n" + " \n" + "Defines the maximum change in input rate.\n" + "You may want to increase this to enable\n" + "very large changes in timing, for example\n" + "running PAL cores on NTSC displays, at the\n" + "cost of inaccurate audio pitch.\n" + " \n" + " Input rate is defined as: \n" + " input rate * (1.0 +/- (max timing skew))"); + break; + case MENU_ENUM_LABEL_OVERLAY_NEXT: + snprintf(s, len, + "Toggles to next overlay.\n" + " \n" + "Wraps around."); + break; + case MENU_ENUM_LABEL_LOG_VERBOSITY: + snprintf(s, len, + "Enable or disable verbosity level \n" + "of frontend."); + break; + case MENU_ENUM_LABEL_VOLUME_UP: + snprintf(s, len, + "调高音量."); + break; + case MENU_ENUM_LABEL_VOLUME_DOWN: + snprintf(s, len, + "降低音量."); + break; + case MENU_ENUM_LABEL_VIDEO_DISABLE_COMPOSITION: + snprintf(s, len, + "Forcibly disable composition.\n" + "Only valid on Windows Vista/7 for now."); + break; + case MENU_ENUM_LABEL_PERFCNT_ENABLE: + snprintf(s, len, + "启用或关闭前端 \n" + "性能计数."); + break; + case MENU_ENUM_LABEL_SYSTEM_DIRECTORY: + snprintf(s, len, + "系统目录. \n" + " \n" + "Sets the 'system' directory.\n" + "Cores can query for this\n" + "directory to load BIOSes, \n" + "system-specific configs, etc."); + break; + case MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE: + case MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD: + snprintf(s, len, + "Automatically saves a savestate at the \n" + "end of RetroArch's lifetime.\n" + " \n" + "RetroArch will automatically load any savestate\n" + "with this path on startup if 'Auto Load State\n" + "is enabled."); + break; + case MENU_ENUM_LABEL_VIDEO_THREADED: + snprintf(s, len, + "Use threaded video driver.\n" + " \n" + "Using this might improve performance at the \n" + "possible cost of latency and more video \n" + "stuttering."); + break; + case MENU_ENUM_LABEL_VIDEO_VSYNC: + snprintf(s, len, + "视频垂直同步.\n"); + break; + case MENU_ENUM_LABEL_VIDEO_HARD_SYNC: + snprintf(s, len, + "尝试硬件同步 \n" + "CPU和GPU.\n" + " \n" + "可以降低潜在的性能 \n" + "开销."); + break; + case MENU_ENUM_LABEL_REWIND_GRANULARITY: + snprintf(s, len, + "Rewind granularity.\n" + " \n" + " When rewinding defined number of \n" + "frames, you can rewind several frames \n" + "at a time, increasing the rewinding \n" + "speed."); + break; + case MENU_ENUM_LABEL_SCREENSHOT: + snprintf(s, len, + "Take screenshot."); + break; + case MENU_ENUM_LABEL_VIDEO_FRAME_DELAY: + snprintf(s, len, + "Sets how many milliseconds to delay\n" + "after VSync before running the core.\n" + "\n" + "Can reduce latency at the cost of\n" + "higher risk of stuttering.\n" + " \n" + "Maximum is 15."); + break; + case MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES: + snprintf(s, len, + "Sets how many frames CPU can \n" + "run ahead of GPU when using 'GPU \n" + "Hard Sync'.\n" + " \n" + "Maximum is 3.\n" + " \n" + " 0: Syncs to GPU immediately.\n" + " 1: Syncs to previous frame.\n" + " 2: Etc ..."); + break; + case MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION: + snprintf(s, len, + "Inserts a black frame inbetween \n" + "frames.\n" + " \n" + "Useful for 120 Hz monitors who want to \n" + "play 60 Hz material with eliminated \n" + "ghosting.\n" + " \n" + "Video refresh rate should still be \n" + "configured as if it is a 60 Hz monitor \n" + "(divide refresh rate by 2)."); + break; + case MENU_ENUM_LABEL_RGUI_SHOW_START_SCREEN: + snprintf(s, len, + "Show startup screen in menu.\n" + "Is automatically set to false when seen\n" + "for the first time.\n" + " \n" + "This is only updated in config if\n" + "'Save Configuration on Exit' is enabled.\n"); + break; + case MENU_ENUM_LABEL_VIDEO_FULLSCREEN: + snprintf(s, len, "Toggles fullscreen."); + break; + case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: + snprintf(s, len, + "Block SRAM from being overwritten \n" + "when loading save states.\n" + " \n" + "Might potentially lead to buggy games."); + break; + case MENU_ENUM_LABEL_PAUSE_NONACTIVE: + snprintf(s, len, + "Pause gameplay when window focus \n" + "is lost."); + break; + case MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT: + snprintf(s, len, + "Screenshots output of GPU shaded \n" + "material if available."); + break; + case MENU_ENUM_LABEL_SCREENSHOT_DIRECTORY: + snprintf(s, len, + "截图目录 \n" + " \n" + "用于保存截图的文件夹。" + ); + break; + case MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL: + snprintf(s, len, + "VSync Swap Interval.\n" + " \n" + "Uses a custom swap interval for VSync. Set this \n" + "to effectively halve monitor refresh rate."); + break; + case MENU_ENUM_LABEL_SAVEFILE_DIRECTORY: + snprintf(s, len, + "游戏存盘目录. \n" + " \n" + "Save all save files (*.srm) to this \n" + "directory. This includes related files like \n" + ".bsv, .rt, .psrm, etc...\n" + " \n" + "This will be overridden by explicit command line\n" + "options."); + break; + case MENU_ENUM_LABEL_SAVESTATE_DIRECTORY: + snprintf(s, len, + "即时存档目录. \n" + " \n" + "Save all save states (*.state) to this \n" + "directory.\n" + " \n" + "This will be overridden by explicit command line\n" + "options."); + break; + case MENU_ENUM_LABEL_ASSETS_DIRECTORY: + snprintf(s, len, + "Assets Directory. \n" + " \n" + " This location is queried by default when \n" + "menu interfaces try to look for loadable \n" + "assets, etc."); + break; + case MENU_ENUM_LABEL_DYNAMIC_WALLPAPERS_DIRECTORY: + snprintf(s, len, + "动态壁纸目录 \n" + " \n" + "保存用于主界面的、依据游戏内容变化的动态壁纸。"); + break; + case MENU_ENUM_LABEL_SLOWMOTION_RATIO: + snprintf(s, len, + "Slowmotion ratio." + " \n" + "When slowmotion, content will slow\n" + "down by factor."); + break; + case MENU_ENUM_LABEL_INPUT_AXIS_THRESHOLD: + snprintf(s, len, + "Defines axis threshold.\n" + " \n" + "How far an axis must be tilted to result\n" + "in a button press.\n" + " Possible values are [0.0, 1.0]."); + break; + case MENU_ENUM_LABEL_INPUT_TURBO_PERIOD: + snprintf(s, len, + "Turbo period.\n" + " \n" + "Describes the period of which turbo-enabled\n" + "buttons toggle.\n" + " \n" + "Numbers are described in frames." + ); + break; + case MENU_ENUM_LABEL_INPUT_DUTY_CYCLE: + snprintf(s, len, + "Duty cycle.\n" + " \n" + "Describes how long the period of a turbo-enabled\n" + "should be.\n" + " \n" + "Numbers are described in frames." + ); + break; + case MENU_ENUM_LABEL_INPUT_TOUCH_ENABLE: + snprintf(s, len, "Enable touch support."); + break; + case MENU_ENUM_LABEL_INPUT_PREFER_FRONT_TOUCH: + snprintf(s, len, "Use front instead of back touch."); + break; + case MENU_ENUM_LABEL_MOUSE_ENABLE: + snprintf(s, len, "Enable mouse input inside the menu."); + break; + case MENU_ENUM_LABEL_POINTER_ENABLE: + snprintf(s, len, "Enable touch input inside the menu."); + break; + case MENU_ENUM_LABEL_MENU_WALLPAPER: + snprintf(s, len, "Path to an image to set as menu wallpaper."); + break; + case MENU_ENUM_LABEL_NAVIGATION_WRAPAROUND: + snprintf(s, len, + "Wrap-around to beginning and/or end \n" + "if boundary of list is reached \n" + "horizontally and/or vertically."); + break; + case MENU_ENUM_LABEL_PAUSE_LIBRETRO: + snprintf(s, len, + "If disabled, the libretro core will keep \n" + "running in the background when we are in the \n" + "menu."); + break; + case MENU_ENUM_LABEL_SUSPEND_SCREENSAVER_ENABLE: + snprintf(s, len, + "Suspends the screensaver. Is a hint that \n" + "does not necessarily have to be \n" + "honored by the video driver."); + break; + case MENU_ENUM_LABEL_NETPLAY_MODE: + snprintf(s, len, + "Netplay client mode for the current user. \n" + "Will be 'Server' mode if disabled."); + break; + case MENU_ENUM_LABEL_NETPLAY_DELAY_FRAMES: + snprintf(s, len, + "The amount of delay frames to use for netplay. \n" + " \n" + "Increasing this value will increase \n" + "performance, but introduce more latency."); + break; + case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: + snprintf(s, len, + "The frequency in frames with which netplay \n" + "will verify that the host and client are in \n" + "sync. \n" + " \n" + "With most cores, this value will have no \n" + "visible effect and can be ignored. With \n" + "nondeterminstic cores, this value determines \n" + "how often the netplay peers will be brought \n" + "into sync. With buggy cores, setting this \n" + "to any non-zero value will cause severe \n" + "performance issues. Set to zero to perform \n" + "no checks. This value is only used on the \n" + "netplay host. \n"); + break; + case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: + snprintf(s, len, + "Maximum amount of swapchain images. This \n" + "can tell the video driver to use a specific \n" + "video buffering mode. \n" + " \n" + "Single buffering - 1\n" + "Double buffering - 2\n" + "Triple buffering - 3\n" + " \n" + "Setting the right buffering mode can have \n" + "a big impact on latency."); + break; + case MENU_ENUM_LABEL_VIDEO_SMOOTH: + snprintf(s, len, + "Smoothens picture with bilinear filtering. \n" + "Should be disabled if using shaders."); + break; + case MENU_ENUM_LABEL_TIMEDATE_ENABLE: + snprintf(s, len, + "Shows current date and/or time inside menu."); + break; + case MENU_ENUM_LABEL_CORE_ENABLE: + snprintf(s, len, + "Shows current core inside menu."); + break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_HOST: + snprintf(s, len, + "Enables Netplay in host (server) mode."); + break; + case MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT: + snprintf(s, len, + "Enables Netplay in client mode."); + break; + case MENU_ENUM_LABEL_NETPLAY_DISCONNECT: + snprintf(s, len, + "Disconnects an active Netplay connection."); + break; + case MENU_ENUM_LABEL_NETPLAY_SETTINGS: + snprintf(s, len, + "Setting related to Netplay."); + break; + case MENU_ENUM_LABEL_NETPLAY_LAN_SCAN_SETTINGS: + snprintf(s, len, + "Search for and connect to netplay hosts on the local network."); + break; + case MENU_ENUM_LABEL_DYNAMIC_WALLPAPER: + snprintf(s, len, + "Dynamically load a new wallpaper \n" + "depending on context."); + break; + case MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL: + snprintf(s, len, + "URL to core updater directory on the \n" + "Libretro buildbot."); + break; + case MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL: + snprintf(s, len, + "URL to assets updater directory on the \n" + "Libretro buildbot."); + break; + case MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE: + snprintf(s, len, + "if enabled, overrides the input binds \n" + "with the remapped binds set for the \n" + "current core."); + break; + case MENU_ENUM_LABEL_OVERLAY_DIRECTORY: + snprintf(s, len, + "Overlay Directory. \n" + " \n" + "Defines a directory where overlays are \n" + "kept for easy access."); + break; + case MENU_ENUM_LABEL_INPUT_MAX_USERS: + snprintf(s, len, + "Maximum amount of users supported by \n" + "RetroArch."); + break; + case MENU_ENUM_LABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE: + snprintf(s, len, + "After downloading, automatically extract \n" + "archives that the downloads are contained \n" + "inside."); + break; + case MENU_ENUM_LABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE: + snprintf(s, len, + "Filter files being shown by \n" + "supported extensions."); + break; + case MENU_ENUM_LABEL_NETPLAY_NICKNAME: + snprintf(s, len, + "The username of the person running RetroArch. \n" + "This will be used for playing online games."); + break; + case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT: + snprintf(s, len, + "When being client over netplay, use \n" + "keybinds for player 1."); + break; + case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT: + snprintf(s, len, + "The port of the host IP address. \n" + "Can be either a TCP or UDP port."); + break; + case MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE: + snprintf(s, len, + "Enable or disable spectator mode for \n" + "the user during netplay."); + break; + case MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS: + snprintf(s, len, + "The address of the host to connect to."); + break; + case MENU_ENUM_LABEL_STDIN_CMD_ENABLE: + snprintf(s, len, + "Enable stdin command interface."); + break; + case MENU_ENUM_LABEL_UI_COMPANION_START_ON_BOOT: + snprintf(s, len, + "Start User Interface companion driver \n" + "on boot (if available)."); + break; + case MENU_ENUM_LABEL_MENU_DRIVER: + snprintf(s, len, "Menu driver to use."); + break; + case MENU_ENUM_LABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO: + snprintf(s, len, + "Gamepad button combination to toggle menu. \n" + " \n" + "0 - None \n" + "1 - Press L + R + Y + D-Pad Down \n" + "simultaneously. \n" + "2 - Press L3 + R3 simultaneously. \n" + "3 - Press Start + Select simultaneously."); + break; + case MENU_ENUM_LABEL_INPUT_ALL_USERS_CONTROL_MENU: + snprintf(s, len, "Allow any RetroPad to control the menu."); + break; + case MENU_ENUM_LABEL_INPUT_AUTODETECT_ENABLE: + snprintf(s, len, + "Enable input auto-detection.\n" + " \n" + "Will attempt to auto-configure \n" + "joypads, Plug-and-Play style."); + break; + case MENU_ENUM_LABEL_CAMERA_ALLOW: + snprintf(s, len, + "Allow or disallow camera access by \n" + "cores."); + break; + case MENU_ENUM_LABEL_LOCATION_ALLOW: + snprintf(s, len, + "Allow or disallow location services \n" + "access by cores."); + break; + case MENU_ENUM_LABEL_TURBO: + snprintf(s, len, + "Turbo enable.\n" + " \n" + "Holding the turbo while pressing another \n" + "button will let the button enter a turbo \n" + "mode where the button state is modulated \n" + "with a periodic signal. \n" + " \n" + "The modulation stops when the button \n" + "itself (not turbo button) is released."); + break; + case MENU_ENUM_LABEL_OSK_ENABLE: + snprintf(s, len, + "Enable/disable on-screen keyboard."); + break; + case MENU_ENUM_LABEL_AUDIO_MUTE: + snprintf(s, len, + "Mute/unmute audio."); + break; + case MENU_ENUM_LABEL_REWIND: + snprintf(s, len, + "Hold button down to rewind.\n" + " \n" + "Rewind must be enabled."); + break; + case MENU_ENUM_LABEL_EXIT_EMULATOR: + snprintf(s, len, + "Key to exit RetroArch cleanly." +#if !defined(RARCH_MOBILE) && !defined(RARCH_CONSOLE) + "\nKilling it in any hard way (SIGKILL, \n" + "etc) will terminate without saving\n" + "RAM, etc. On Unix-likes,\n" + "SIGINT/SIGTERM allows\n" + "a clean deinitialization." +#endif + ); + break; + case MENU_ENUM_LABEL_LOAD_STATE: + snprintf(s, len, + "Loads state."); + break; + case MENU_ENUM_LABEL_SAVE_STATE: + snprintf(s, len, + "Saves state."); + break; + case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS: + snprintf(s, len, + "Netplay flip users."); + break; + case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS: + snprintf(s, len, + "Increment cheat index.\n"); + break; + case MENU_ENUM_LABEL_CHEAT_INDEX_MINUS: + snprintf(s, len, + "Decrement cheat index.\n"); + break; + case MENU_ENUM_LABEL_SHADER_PREV: + snprintf(s, len, + "Applies previous shader in directory."); + break; + case MENU_ENUM_LABEL_SHADER_NEXT: + snprintf(s, len, + "Applies next shader in directory."); + break; + case MENU_ENUM_LABEL_RESET: + snprintf(s, len, + "Reset the content.\n"); + break; + case MENU_ENUM_LABEL_PAUSE_TOGGLE: + snprintf(s, len, + "Toggle between paused and non-paused state."); + break; + case MENU_ENUM_LABEL_CHEAT_TOGGLE: + snprintf(s, len, + "打开金手指索引.\n"); + break; + case MENU_ENUM_LABEL_HOLD_FAST_FORWARD: + snprintf(s, len, + "Hold for fast-forward. Releasing button \n" + "disables fast-forward."); + break; + case MENU_ENUM_LABEL_SLOWMOTION: + snprintf(s, len, + "Hold for slowmotion."); + break; + case MENU_ENUM_LABEL_FRAME_ADVANCE: + snprintf(s, len, + "Frame advance when content is paused."); + break; + case MENU_ENUM_LABEL_MOVIE_RECORD_TOGGLE: + snprintf(s, len, + "Toggle between recording and not."); + break; + case MENU_ENUM_LABEL_L_X_PLUS: + case MENU_ENUM_LABEL_L_X_MINUS: + case MENU_ENUM_LABEL_L_Y_PLUS: + case MENU_ENUM_LABEL_L_Y_MINUS: + case MENU_ENUM_LABEL_R_X_PLUS: + case MENU_ENUM_LABEL_R_X_MINUS: + case MENU_ENUM_LABEL_R_Y_PLUS: + case MENU_ENUM_LABEL_R_Y_MINUS: + snprintf(s, len, + "Axis for analog stick (DualShock-esque).\n" + " \n" + "Bound as usual, however, if a real analog \n" + "axis is bound, it can be read as a true analog.\n" + " \n" + "Positive X axis is right. \n" + "Positive Y axis is down."); + break; + case MENU_ENUM_LABEL_VALUE_WHAT_IS_A_CORE_DESC: + snprintf(s, len, + "RetroArch本身并不能做什么事情。 \n" + " \n" + "如果想在上面干点什么,你需要向它加载一个程 \n" + "序。 \n" + "\n" + "我们把这样的程序叫做“Libretro核心”,简单 \n" + "的称呼其为“核心”。 \n" + " \n" + "你可以从“加载核心”菜单中选择一个核心。 \n" + " \n" +#ifdef HAVE_NETWORKING + "你可以通过以下几种方法来获取核心: \n" + "一、通过访问菜单项「%s」 \n" + " -> 「%s」来下载;\n" + "二、手动将其移入核心目录中,访问目录设置 \n" + "找到你的“%s”。", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) +#else + "你可以通过手动将核心移入目录中来添加他 \n" + "们,访问目录设置找到你的“%s”。", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH) +#endif + ); + break; + case MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD_DESC: + snprintf(s, len, + "You can change the virtual gamepad overlay\n" + "by going to '%s' -> '%s'." + " \n" + "From there you can change the overlay,\n" + "change the size and opacity of the buttons, etc.\n" + " \n" + "NOTE: By default, virtual gamepad overlays are\n" + "hidden when in the menu.\n" + "If you'd like to change this behavior,\n" + "you can set '%s' to false.", + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU) + ); + break; + default: + if (string_is_empty(s)) + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE), len); + return -1; + } + + return 0; +} + +const char *msg_hash_to_str_chs(enum msg_hash_enums msg) +{ + switch (msg) + { +#include "msg_hash_chs.h" + + default: +#if 0 + RARCH_LOG("Unimplemented: [%d]\n", msg); +#endif + break; + } + + return "null"; +} From 593d1ff7b5233093b57211fa84a7271acadcc34c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 6 Feb 2017 05:56:33 +0100 Subject: [PATCH 32/90] Update Chinese --- intl/msg_hash_chs.h | 220 ++++++++++++++++++++++---------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 6f955cc773..605e24f2a0 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1,42 +1,42 @@ MSG_HASH( MSG_COMPILER, - "Compiler" + "编译器" ) MSG_HASH( MSG_UNKNOWN_COMPILER, - "Unknown compiler" + "未知的编译器" ) MSG_HASH( MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Device disconnected from port" + "设备已从端口上断开" ) MSG_HASH( MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Unknown netplay command received" + "接收到未知的联机游戏指令" ) MSG_HASH( MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "文件已存在. Saving to backup buffer" + "文件已存在。保存到备份缓冲区" ) MSG_HASH( MSG_GOT_CONNECTION_FROM, - "Got connection from: \"%s\"" + "连接来自: \"%s\"" ) MSG_HASH( MSG_GOT_CONNECTION_FROM_NAME, - "Got connection from: \"%s (%s)\"" + "连接来自: \"%s (%s)\"" ) MSG_HASH( MSG_PUBLIC_ADDRESS, - "Public address" + "公开地址" ) MSG_HASH( MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, - "No arguments supplied and no menu builtin, displaying help..." + "未提供参数也没有内建菜单,显示帮助..." ) MSG_HASH( MSG_NETPLAY_USERS_HAS_FLIPPED, - "Netplay users has flipped" + "联机游戏用户已被踢出" ) MSG_HASH( MSG_SETTING_DISK_IN_TRAY, @@ -44,19 +44,19 @@ MSG_HASH( ) MSG_HASH( MSG_WAITING_FOR_CLIENT, - "Waiting for client ..." + "等待客户端 ..." ) MSG_HASH( MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, - "You have left the game" + "你已离开游戏" ) MSG_HASH( MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, - "You have joined as player %d" + "你已作为玩家 %d 加入" ) MSG_HASH( MSG_NETPLAY_IMPLEMENTATIONS_DIFFER, - "Implementations differ. Make sure you're using the exact same versions of RetroArch and the core." + "实现有差异。确保正在使用的RetroArch和核心是同版本的。" ) MSG_HASH( MSG_NETPLAY_ENDIAN_DEPENDENT, @@ -68,43 +68,43 @@ MSG_HASH( ) MSG_HASH( MSG_NETPLAY_ENTER_PASSWORD, - "Enter netplay server password:" + "输入联机游戏服务器的密码:" ) MSG_HASH( MSG_NETPLAY_INCORRECT_PASSWORD, - "Incorrect password" + "密码错误" ) MSG_HASH( MSG_NETPLAY_SERVER_NAMED_HANGUP, - "\"%s\" has disconnected" + "\"%s\" 已断开连接" ) MSG_HASH( MSG_NETPLAY_SERVER_HANGUP, - "A netplay client has disconnected" + "一个联机游戏客户端已断开" ) MSG_HASH( MSG_NETPLAY_CLIENT_HANGUP, - "Netplay disconnected" + "联机游戏已断开" ) MSG_HASH( MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, - "You do not have permission to play" + "你没有游戏权限" ) MSG_HASH( MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, - "There are no free player slots" + "已无空闲插槽" /*FIXME:"There are no free player slots"*/ ) MSG_HASH( MSG_NETPLAY_CANNOT_PLAY, - "Cannot switch to play mode" + "无法切换到游戏模式" ) MSG_HASH( MSG_NETPLAY_PEER_PAUSED, - "Netplay peer \"%s\" paused" + "联机游戏对方 \"%s\" 暂停" ) MSG_HASH( MSG_NETPLAY_CHANGED_NICK, - "Your nickname changed to \"%s\"" + "你的昵称已修改为 \"%s\"" ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, @@ -133,27 +133,27 @@ MSG_HASH( ) MSG_HASH( MSG_AUTOLOADING_SAVESTATE_FROM, - "Auto-loading savestate from" + "自动加载存档从" ) MSG_HASH( MSG_CAPABILITIES, - "Capabilities" + "容量" ) MSG_HASH( MSG_CONNECTING_TO_NETPLAY_HOST, - "Connecting to netplay host" + "连接到联机游戏主机" ) MSG_HASH( MSG_CONNECTING_TO_PORT, - "Connecting to port" + "连接到端口" ) MSG_HASH( MSG_CONNECTION_SLOT, - "Connection slot" + "连接到插槽" ) MSG_HASH( MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, - "Sorry, unimplemented: cores that don't demand content cannot participate in netplay." + "对不起,未实现:核心未请求内容,无法加入联机游戏。" ) MSG_HASH( MSG_FAILED_TO_SET_DISK, @@ -164,7 +164,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, - "Accounts Cheevos" + "Cheevos账户" /*FIXME:"Accounts Cheevos"*/ ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, @@ -189,7 +189,7 @@ MSG_HASH( MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Achievement List (Hardcore)" + "成就列表(硬核)" /*FIXME:"Achievement List (Hardcore)"*/ ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, @@ -205,7 +205,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Netplay Rooms" + "联机游戏房间" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, @@ -221,7 +221,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Block Frames" + "块帧" /*FIXME:"Block Frames"*/ ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, @@ -245,7 +245,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, - "Turbo/Deadzone" + "涡轮/盲区" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, @@ -417,7 +417,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "Cheat Passes" + "金手指通过" /*FIXME: "Cheat Passes"*/ ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, @@ -598,9 +598,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, "驱动") MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, /* FIXME? Translate 'Load Dummy on Core Shutdown' */ - "Load Dummy on Core Shutdown") + "核心关闭时加载虚拟程序") MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "Check for Missing Firmware Before Loading") + "加载前检查丢失的固件") /*FIXME: "Check for Missing Firmware Before Loading"*/ MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, "动态壁纸") MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, @@ -691,7 +691,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, "输入轴阈值") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Menu Swap OK & Cancel Buttons") + "菜单切换 确定/取消 按钮") /*FIXME:"Menu Swap OK & Cancel Buttons"*/ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, "绑定全部") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, @@ -747,7 +747,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, "Y键(左侧)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, - "(Key: %s)") + "(键: %s)") /*FIXME:"(Key: %s)"*/ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, "键盘控制器映射类型") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, @@ -789,9 +789,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, "静音开关") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, - "Netplay flip users") + "联机游戏踢出用户") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Netplay toggle play/spectate mode") + "联机游戏切换 游戏/围观 模式") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, "切换屏幕键盘") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, @@ -999,19 +999,19 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, "用户名") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Server Password") + "服务器密码") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, "在线游戏设置") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, - "Netplay Stateless Mode") + "联机无状态模式") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Server Spectate-Only Password") + "服务器围观的密码") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, "启用在线游戏旁观者") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, "在线游戏TCP/UDP端口") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Netplay NAT Traversal") + "联机NAT遍历") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, "网络命令") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, @@ -1135,11 +1135,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, "开发者") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, - "Edge Magazine Issue") + "Edge杂志发行") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, - "Edge Magazine Rating") + "Edge杂志评分") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, - "Edge Magazine Review") + "Edge杂志评论") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, "ELSPA 分级") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, @@ -1147,7 +1147,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, "ESRB 分级") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, - "Famitsu Magazine Rating") + "次世代(Famitsu)杂志评分") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, "经销商") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, @@ -1175,7 +1175,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, "启动游戏内容") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, - "TGDB Rating") + "TGDB 评分") MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, "重启") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, @@ -1213,9 +1213,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, "继续") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, - "RetroKeyboard") + "Retro键盘") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, - "RetroPad") + "Retro触摸板") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, "RetroPad w/ Analog") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, @@ -1631,7 +1631,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, "多线程渲染") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Deflicker") + "降低闪烁") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, "自定义视口高度") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, @@ -1641,7 +1641,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, "自定义视口Y") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Set VI Screen Width") + "设置 VI 屏幕宽度") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, "垂直同步") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, @@ -1705,7 +1705,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY, "显示历史页") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_ADD, - "Display Import content Tab") + "显示导入内容页") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES, "显示图像页") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC, @@ -1721,11 +1721,11 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, "Shader预设") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Enable or disable achievements. For more information, visit http://retroachievements.org") + "打开或关闭成就。更多内容请访问 http://retroachievements.org") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "Enable or disable unofficial achievements and/or beta features for testing purposes.") + "为测试目的而打开或关闭非官方成就和/或测试版特性。") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "Enable or disable savestates, cheats, rewind, fast-forward, pause, and slow-motion for all games.") + "为所有游戏打开或关闭存档、金手指、回退、快进、暂停和慢动作。") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, "修改驱动设置。") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, @@ -1733,7 +1733,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, "修改核心设置。") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Change settings for the recording.") + "修改录制的设置。") MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, "修改显示覆盖、键盘覆盖和屏幕通知的设置。") MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, @@ -1804,9 +1804,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, "在帧与帧之间插入黑色的中间帧,通常用于消除在\n" "120Hz刷新率的显示器上运行60Hz的游戏内容带来\n" "的鬼影。") - MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "以增加画面卡顿的风险换取低延时,在垂直同步后增加\n" - "时延(毫秒)。") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "以增加画面卡顿的风险换取低延时,在垂直同步后增加\n" + "时延(毫秒)。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, "设置当开启“强制GPU同步”时CPU可以预先GPU多少帧。") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, @@ -1832,35 +1832,35 @@ MSG_HASH(MSG_AUDIO_MUTED, MSG_HASH(MSG_AUDIO_UNMUTED, "取消静音。") MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, - "Error saving autoconf file.") + "保存 autoconf 文件错误。") MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, - "Autoconfig file saved successfully.") + "自动配置文件保存成功。") MSG_HASH(MSG_AUTOSAVE_FAILED, - "Could not initialize autosave.") + "无法初始化自动保存。") MSG_HASH(MSG_AUTO_SAVE_STATE_TO, "自动保存状态至") MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, - "Blocking SRAM Overwrite") + "阻止 SRAM 覆盖") MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, "Bringing up command interface on port") MSG_HASH(MSG_BYTES, - "bytes") + "字节") MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, - "Cannot infer new config path. Use current time.") + "无法推断新的配置路径,使用当前时间。") MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, "硬核模式开启:及时存档和回放被禁用.") MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, - "Comparing with known magic numbers...") + "与已知的magic numbers比较...") MSG_HASH(MSG_COMPILED_AGAINST_API, "Compiled against API") MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, - "Config directory not set. Cannot save new config.") + "未设置配置目录,无法保存新的配置。") MSG_HASH(MSG_CONNECTED_TO, "连接至") MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, - "Content CRC32s differ. Cannot use different games.") + "内容的CRC32s不同。无法使用不同的游戏。") MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, - "Content loading skipped. Implementation will load it on its own.") + "跳过内容加载。实现将自行加载。") MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, "核心不支持保存状态。") MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, @@ -2066,25 +2066,25 @@ MSG_HASH(MSG_LOADING_STATE, MSG_HASH(MSG_MEMORY, "内存") MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, - "Movie file is not a valid BSV1 file.") + "视频不是有效的BSV1文件。") MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, - "Movie format seems to have a different serializer version. Will most likely fail.") + "视频格式看起来使用了不同的序列化版本。很有可能失败。") MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, "视频回放结束.") MSG_HASH(MSG_MOVIE_RECORD_STOPPED, - "Stopping movie record.") + "停止视频录制。") MSG_HASH(MSG_NETPLAY_FAILED, - "Failed to initialize netplay.") + "初始化联机游戏失败。") MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, - "No content, starting dummy core.") + "没有内容,启动虚拟核心。") MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, - "No save state has been overwritten yet.") + "未覆盖任何存档。") MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, - "No state has been loaded yet.") + "没有加载任何存档。") MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, - "Error saving overrides.") + "保存覆盖错误。") MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Overrides saved successfully.") + "覆盖保存成功。") MSG_HASH(MSG_PAUSED, "暂停。") MSG_HASH(MSG_PROGRAM, @@ -2094,9 +2094,9 @@ MSG_HASH(MSG_READING_FIRST_DATA_TRACK, MSG_HASH(MSG_RECEIVED, "接收完毕") MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, - "Recording terminated due to resize.") + "录制因改变大小而停止。") MSG_HASH(MSG_RECORDING_TO, - "Recording to") + "录制到") MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, "重定向金手指文件至") MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, @@ -2112,9 +2112,9 @@ MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, MSG_HASH(MSG_RESET, "重置") MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, - "Restarting recording due to driver reinit.") + "重启录制由于驱动器重新初始化。") MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, - "Restored old save state.") + "重载旧的存档。") MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, "Shaders: restoring default shader preset to") MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, @@ -2140,15 +2140,15 @@ MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, "成功保存至") MSG_HASH(MSG_SAVING_RAM_TYPE, - "Saving RAM type") + "保存 RAM 类型") MSG_HASH(MSG_SAVING_STATE, - "Saving state") + "存档中") MSG_HASH(MSG_SCANNING, "扫描中") MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, "已完成对文件夹的扫描") MSG_HASH(MSG_SENDING_COMMAND, - "Sending command") + "发送指令") MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, "Several patches are explicitly defined, ignoring all...") MSG_HASH(MSG_SHADER, @@ -2156,7 +2156,7 @@ MSG_HASH(MSG_SHADER, MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, "Shader preset saved successfully.") MSG_HASH(MSG_SKIPPING_SRAM_LOAD, - "Skipping SRAM load.") + "跳过 SRAM 加载。") MSG_HASH(MSG_SLOW_MOTION, "慢动作。") MSG_HASH(MSG_SLOW_MOTION_REWIND, @@ -2172,9 +2172,9 @@ MSG_HASH(MSG_STATE_SIZE, MSG_HASH(MSG_STATE_SLOT, "状态存档槽") MSG_HASH(MSG_TAKING_SCREENSHOT, - "Taking screenshot.") + "截屏。") MSG_HASH(MSG_TO, - "to") + "到") MSG_HASH(MSG_UNDID_LOAD_STATE, "已撤销加载状态。") MSG_HASH(MSG_UNDOING_SAVE_STATE, @@ -2184,15 +2184,15 @@ MSG_HASH(MSG_UNKNOWN, MSG_HASH(MSG_UNPAUSED, "取消暂停。") MSG_HASH(MSG_UNRECOGNIZED_COMMAND, - "Unrecognized command") + "无法识别的指令") MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, "Using core name for new config.") MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, - "Using libretro dummy core. Skipping recording.") + "使用libretro虚拟核心。跳过录制。") MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, "Connect device from a valid port.") MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, - "Disconnecting device from port") + "从端口断开设备") MSG_HASH(MSG_VALUE_REBOOTING, "正在重启……") MSG_HASH(MSG_VALUE_SHUTTING_DOWN, @@ -2206,7 +2206,7 @@ MSG_HASH(MSG_VIRTUAL_DISK_TRAY, MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, "Desired audio latency in milliseconds. Might not be honored if the audio driver can't provide given latency.") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "Mute/unmute audio.") + "禁音/取消禁音。") MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, "Helps smooth out imperfections in timing when synchronizing audio and video at the same time. Be aware that if disabled, proper synchronization is nearly impossible to obtain." @@ -2237,7 +2237,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "Synchronize audio. Recommended." + "同步音频。推荐。" ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, @@ -2363,38 +2363,38 @@ MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, "游戏、图片、音乐和视频历史记录的数量限制。") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "Unified Menu Controls") + "统一菜单控制") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, "Use the same controls for both the menu and the game. Applies to the keyboard.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "Show onscreen messages.") + "显示屏幕消息。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, - "User %d Remote Enable") + "用户 %d 远程允许") MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Display battery level") + "显示电池电量") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, - "Select File") + "选择文件") MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, - "Select From Collection") + "从收藏中选择") MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, - "Filter") + "过滤器") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, - "Scale") + "刻度") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "Netplay will start when content is loaded.") + "联机游戏将在内容加载后开始。") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, - "Couldn't find a suitable core or content file, load manually.") + "无法找到合适的核心或内容文件,手动加载。") MSG_HASH( MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "Browse URL" + "浏览URL" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "URL Path" + "URL路径" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BROWSE_START, - "Start" + "开始" ) MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, "Bokeh") From e98fac204629ecc1f50db1599b311efde8188e1c Mon Sep 17 00:00:00 2001 From: rootfather Date: Mon, 6 Feb 2017 11:45:27 +0100 Subject: [PATCH 33/90] Rewrite German translation (part 2) --- intl/msg_hash_de.h | 2089 +++++++++++++++++++++++++++++++------------- 1 file changed, 1500 insertions(+), 589 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 2de7f39702..5eb4fa1331 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1,113 +1,436 @@ -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Passwort") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Benutzername") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, - "Konten") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Errungenschaften") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Errungenschaften (Hardcore)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ADD_TAB, - "Hinzufügen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, - "Verknüpfte Aktion bei Archivdateien") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, - "Nachfragen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Assets-Verzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, - "Warte auf Audio-Frames") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, - "Soundkarte") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, - "Audiotreiber") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, - "Audio-DSP-Plugin") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, - "Aktiviere Audio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Audiofilterverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - "Audiolatenz (ms)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, - "Maximaler Audioversatz") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, - "Stumm") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, - "Audiofrequenzrate (kHz)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, - "Audio Rate Control Delta") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, - "Audio-Resampler-Treiber") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Audioeinstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, - "Synchronisiere Audio") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "Lautstärke (dB)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "Automatischespeicherungsintervall") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, - "Override-Dateien automatisch laden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, - "Remap-Dateien automatisch laden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, - "Blockiere SRAM-Überschreibung") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - "Buildbot-Assets-URL") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, /* FIXME/UPDATE */ - "Entpackverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, - "Erlaube Kamera-Zugriff") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Kameratreiber") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT, - "Cheat") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, - "Änderungen übernehmen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, - "Cheat-Dateiverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Cheat-Datei laden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Speichere Cheat-Datei unter...") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, - "Cheat-Durchgänge") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, - "Überprüfe Firmware vor dem Laden.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Aktiviere Errungenschaften") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Hardcore-Modus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, - "Teste unoffizielle Errungenschaften") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "Schließen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "Konfigurationsdatei laden") /* FIXME/UPDATE */ -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "Konfigurationseinstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, - "Konfigurationen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, - "Speichere Konfiguration beim Beenden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, - "Inhalt laden") /* FIXME/TODO - rewrite */ -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "Inhaltsdatenbankverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, +MSG_HASH( + MSG_COMPILER, + "Compiler" + ) +MSG_HASH( + MSG_UNKNOWN_COMPILER, + "Unbekannter Compiler" + ) +MSG_HASH( + MSG_DEVICE_DISCONNECTED_FROM_PORT, + "Gerät nicht mit dem Anschluss verbunden" + ) +MSG_HASH( + MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, + "Unbekannter Netplay-Befehl empfangen" + ) +MSG_HASH( + MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, + "Datei existiert bereits. Speichern im Backup-Puffer" + ) +MSG_HASH( + MSG_GOT_CONNECTION_FROM, + "Verbindung erhalten von" + ) +MSG_HASH( + MSG_PUBLIC_ADDRESS, + "Öffentliche Addresse" + ) +MSG_HASH( + MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, + "Es wurden keine Argumente übergeben, außerdem ist kein Menü vorhanden - zeige Hilfe an..." + ) +MSG_HASH( + MSG_NETPLAY_USERS_HAS_FLIPPED, + "Netplay-Benutzer wurden vertauscht" + ) +MSG_HASH( + MSG_SETTING_DISK_IN_TRAY, + "Lege Datenträger in Laufwerksschublade ein" + ) +MSG_HASH( + MSG_WAITING_FOR_CLIENT, + "Warte auf Client ..." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, + "Gibt Hardware-gerenderten Cores einen eigenen privaten Kontext. Vermeidet, dass der Hardware-Status zwischen den Frames geschätzt werden muss." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_SETTINGS, + "Legt die Einstellungen für das Aussehen des Menübildschirms fest." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, + "'Harte' Synchronisation der CPU und der GPU. Reduziert Latenz, braucht aber mehr Leistung." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_THREADED, + "Verbessert die Leistung, führt aber zu größerer Latenz und Videoproblemen. " + "Verwende dies nur, wenn Du sonst die gewünschte Leistung nicht erreichst." + ) +MSG_HASH( + MSG_AUDIO_VOLUME, + "Audio-Lautstärke" + ) +MSG_HASH( + MSG_AUTODETECT, + "Automatisch erkennen" + ) +MSG_HASH( + MSG_AUTOLOADING_SAVESTATE_FROM, + "Lade Spielstände automatisch von" + ) +MSG_HASH( + MSG_CAPABILITIES, + "Fähikeiten" + ) +MSG_HASH( + MSG_CONNECTING_TO_NETPLAY_HOST, + "Verbinde zu Netplay-Host" + ) +MSG_HASH( + MSG_CONNECTING_TO_PORT, + "Verbinde zu Port" + ) +MSG_HASH( + MSG_CONNECTION_SLOT, + "Verbindungs-Slot" + ) +MSG_HASH( + MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, + "Entschuldigung, nicht implementiert: Cores, die keinen Inhalt verlangen, können nicht an Netplay teilnehmen." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, + "Passwort" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, + "Cheevos-Benutzerkonten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, + "Benutzername" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, + "Benutzerkonten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST_END, + "Endpunkt der Benutzerkonten-Liste" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Retro-Errungenschaften" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, + "Errungenschaften" + ) + +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, + "Errungenschaften (Hardcore)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, + "Inhalt durchsuchen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS_LIST, + "Konfigurationen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ADD_TAB, + "Inhalt importieren" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, + "Verknüpfte Aktion bei Archivdateien" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, + "Nachfragen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, + "Assets-Verzeichnis" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, + "Warte auf Audio-Frames" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DEVICE, + "Soundkarte" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DRIVER, + "Audiotreiber" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_DSP_PLUGIN, + "Audio-DSP-Plugin" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_ENABLE, + "Aktiviere Audio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, + "Audiofilter-Verzeichnis" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, + "Turbo/Deadzone" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, + "Audiolatenz (ms)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MAX_TIMING_SKEW, + "Maximaler Audioversatz" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_MUTE, + "Stumm" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_OUTPUT_RATE, + "Audiofrequenzrate (KHz)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RATE_CONTROL_DELTA, + "Dynamische Audio-Ratenkontrolle" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_RESAMPLER_DRIVER, + "Audio-Resampling-Treiber" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, + "Audio-Einstellungen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, + "Synchronisiere Audio" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, + "Lautstärke (dB)" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, + "Intervall für automatisches Speichern des SaveRAM" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, + "Override-Dateien automatisch laden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE, + "Remap-Dateien automatisch laden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, + "Shader-Vorlagen automatisch laden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, + "Zurück" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, + "Bestätigen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, + "Info" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, + "Beenden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, + "Nach unten scrollen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, + "Nach oben scrollen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, + "Start" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, + "Tastatur ein-/ausschalten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, + "Menü ein-/ausschalten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, + "Grundlegende Menüsteuerung" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, + "Bestätigen/OK" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, + "Info" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, + "Beenden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, + "Nach oben scrollen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, + "Standardwerte" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, + "Tastatur ein-/ausschalten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, + "Menü ein-/ausschalten" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, + "Überschreibe SaveRAM nicht, wenn ein Savestate geladen wird" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, + "Bluetooth aktivieren" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, + "Buildbot-Assets-URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CACHE_DIRECTORY, + "Temporäre Dateien" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_ALLOW, + "Erlaube Kamera-Zugriff" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, + "Kamera-Treiber" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT, + "Cheat" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_APPLY_CHANGES, + "Änderungen übernehmen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_DATABASE_PATH, + "Cheat-Datei" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE, + "Cheat-Date" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, + "Cheat-Datei laden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, + "Speichere Cheat-Datei unter..." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, + "Cheat-Durchläufe" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_DESCRIPTION, + "Beschreibung" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, + "Hardcore-Modus" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, + "Gesperrte Errungenschaften:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, + "Gesperrt" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, + "Retro-Errungenschaften" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, + "Teste inoffizielle Errungenschaften" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, + "Entsperrte Errungenschaften:" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, + "Entsperrt" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, + "Schließen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG, + "Konfiguration" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, + "Konfgurationsdatei laden" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, + "Konfigurations-Einstellungen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, + "Einstellungen beim Beenden speichern" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, + "Vor dem Beenden nachfragen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, + "Sammlungen" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, + "Inhalts-Datenbank" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_DIR, + "Inhalt" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, "Länge der Verlaufsliste") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Inhaltseinstellungen") /* FIXME */ + "Inhaltseinstellungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, + "Core-Assets") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, - "Core-Assets-Verzeichnis") /* FIXME/UPDATE */ + "Downloads") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, "Cheats") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, "Core-Zähler") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, - "Zeige Core-Namen") + "Core-Namen anzeigen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, "Core-Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, @@ -115,7 +438,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_AUTHORS, MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CATEGORIES, "Kategorien") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_LABEL, - "Core-Beschriftung") + "Core-Bezeichnung") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_CORE_NAME, "Core-Name") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_FIRMWARE, @@ -125,101 +448,115 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_LICENSES, MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_PERMISSIONS, "Berechtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SUPPORTED_EXTENSIONS, - "Unterstütze Erweiterungen") + "Unterstützte Erweiterungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, "System-Hersteller") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, "System-Name") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, /* UPDATE/FIXME */ - "Core-Input-Optionen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, + "Core-Eingabeoptionen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, "Core laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, "Optionen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, "Core-Einstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, /* TODO/FIXME */ - "Cores nicht automatisch starten") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, + "Cores automatisch starten") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, "Heruntergeladene Archive automatisch entpacken") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, "Buildbot-Cores-URL") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, - "Aktualisiere Core") + "Cores aktualisieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, - "Core-Aktualisierungseinstellungen") /* UPDATE/FIXME */ + "Aktualisierungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, + "CPU-Architektur:") MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, - "Prozessorkerne:") + "CPU-Kerne:") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor-Verzeichnis") + "Cursor") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Zeiger-Manager") + "Mauszeiger-Manager") MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, "Benutzerdefiniertes Verhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, "Datenbank-Manager") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, + "Datenbank-Auswahl") MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, "Von der Wiedergabeliste löschen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, - "Lesezeichen") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, "") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, - "") + "") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, "") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, - "Ordner nicht gefunden.") + "Verzeichnis nicht gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Verzeichniseinstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISABLED, - "Deaktiviert") + "Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, - "Datenträgerstatus") + "Datentägerstatus") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, "Füge Datenträgerabbild hinzu") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_INDEX, "Datenträger-Nummer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, /* UPDATE/FIXME */ +MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_OPTIONS, "Datenträger-Optionen") MSG_HASH(MENU_ENUM_LABEL_VALUE_DONT_CARE, - "Mir egal") + "Ignorieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOADED_FILE_DETECT_CORE_LIST, + "Downloads") MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, "Core herunterladen...") MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, - "Inhalt Downloader") + "Inhalt herunterladen") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, "Aktiviere DPI-Override") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, "DPI-Override") MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, - "Treibereinstellungen") + "Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, - "Dummy bei Core-Abschaltung") + "Dummy laden, wenn Core beendet wird") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHECK_FOR_MISSING_FIRMWARE, + "Vor dem Laden nach fehlender Firmware suchen") MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, - "Dynamischer Hintergrund") + "Dynamisches Hintergrundbild") MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, - "Dynamischehintergrundbilderverzeichnis") + "Dynamische Hintergrundbilder") +MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, + "Aktiviere Errungenschaften") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, - "Hover-Farbe für Menü-Einträge") + "Farbe für gewählte Menü-Einträge") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, - "Normale Farbe für Menü-Einträge") + "Farbe für nicht gewählte Menü-Einträge") MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, - "False") + "Aus") MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, - "Maximale Ausführungsgeschwindigkeit") + "Maximale Ausführgeschwindigkeit") MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, "Zeige Bildwiederholrate") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, - "Begrenze maximale Ausführungsgeschwindigkeit") + "Begrenze maximale Ausführgeschwindigkeit") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, + "Bildgeschwindigkeit") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, - "Frontendzähler") + "Frontend-Zähler") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, + "Lade inhaltsspezifische Core-Einstellungen automatisch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, + "Erstelle Datei für Spieloptionen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, + "Spieloptionen") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, "Hilfe") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Audio/Video Fehlerbehebung") + "Audio/Video-Fehlerbehebung") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "Ändere das Virtual Gamepad Overlay") + "Ändere virtuelles Gamepad-Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, "Grundlegende Menüsteuerung") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, @@ -231,45 +568,61 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT, MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_WHAT_IS_A_CORE, "Was ist ein Core?") MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_LIST_ENABLE, - "Aktiviere Verlaufsliste") + "Verlaufliste aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_HISTORY_TAB, "Verlauf") -MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, /* Don't change. Breaks everything. (Would be, "Horizontales Menu") */ - "Horizontal Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_HORIZONTAL_MENU, + "Horizontales Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_IMAGES_TAB, "Bilder") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION, + "Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INFORMATION_LIST, "Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE, "Analog-zu-Digital-Typ") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ALL_USERS_CONTROL_MENU, - "Jeder Nutzer kann das Menü steuern") + "Alle Benutzer können das Menü steuern") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X, "Linker Analogstick X") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_MINUS, "Linker Analogstick X- (links)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_X_PLUS, - "Linker Analogstick X+ (Rechts)") + "Linker Analogstick X+ (rechts)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y, "Linker Analogstick Y") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_MINUS, - "Linker Analogstick Y- (hoch)") + "Linker Analogstick Y- (nach oben)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_LEFT_Y_PLUS, - "Linker Analogstick Y+ (runter)") + "Linker Analogstick Y+ (nach unten)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X, + "Rechter Analogstick X") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_MINUS, + "Rechter Analogstick X- (links)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_X_PLUS, + "Rechter Analogstick X+ (rechts)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y, + "Rechter Analogstick Y") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_MINUS, + "Rechter Analogstick Y- (nach oben)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ANALOG_RIGHT_Y_PLUS, + "Rechter Analogstick Y+ (nach unten)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, "Automatische Konfiguration aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, - "Schwellwert der Eingabe-Achsen") + "Schwellenwert der Analogsticks") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, + "Vertausche OK- und Zurück-Tasten im Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, - "Binde alle") + "Alle zuordnen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, - "Binde alle Standard") /* @TODO: What is this */ + "Standard-Belegung wiederherstellen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_TIMEOUT, - "Bindeunterbrechung") + "Zeitlimit für Belegung") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_HIDE_UNBOUND, - "Verstecke nicht zugewiesene Core-Eingabe-Beschriftungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, /* TODO/FIXME */ - "Zeige Core-Eingabe-Beschriftungen") + "Verstecke nicht zugewiesene Eingabe-Beschriftungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DESCRIPTOR_LABEL_SHOW, + "Zeige Eingabe-Beschriftungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_INDEX, "Geräteindex") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, @@ -277,87 +630,93 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, "Eingabetreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Auslastungsgrad") + "Haltedauer") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, + "Hotkeys belegen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, + "Gamepad-Eingabe auf Tastatur legen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_A, "A-Knopf (rechts)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_B, - "B-Knopf (unten)") + "B-Knopf (nach unten)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_DOWN, - "Steuerkreuz unten") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, - "L-Knopf (Schultertaste)") + "Steuerkreuz nach unten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L2, "L2-Knopf (Abzug)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L3, "L3-Knopf (Daumen)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_L, + "L-Knopf (Schultertaste)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_LEFT, - "Steuerkreuz links") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, - "R-Knopf (Schultertaste)") + "Steuerkreuz nach links") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R2, "R2-Knopf (Abzug)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R3, "R3-Knopf (Daumen)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_R, + "R-Knopf (Schultertaste)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_RIGHT, - "Steuerkreuz rechts") + "Steuerkreuz nach rechts") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_SELECT, "Select-Knopf") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_START, - "Startknopf") + "Start-Knopf") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_UP, - "Steuerkreuz oben") + "Steuerkreuz nach oben") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_X, "X-Knopf (oben)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_JOYPAD_Y, "Y-Knopf (links)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEY, + "(Taste: %s)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_KEYBOARD_GAMEPAD_MAPPING_TYPE, + "Typ der Keyboard-Gamepad-Abbildung") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MAX_USERS, "Maximale Benutzeranzahl") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Gamepad-Menükombination") + "Gamepad-Tastenkombination für Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_MINUS, "Cheat-Index -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_INDEX_PLUS, "Cheat-Index +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_CHEAT_TOGGLE, - "Cheat ein/aus") + "Cheat ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_EJECT_TOGGLE, - "Disk ein-/auswerfen") + "Datenträger einlegen/auswerfen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_NEXT, - "Nächste Disk") + "Nächster Datenträger") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_DISK_PREV, - "Vorherige Disk") + "Vorheriger Datenträger") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, - "Hotkeys ein/aus") + "Hotkeys aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_HOLD_KEY, - "Zeitraffer") + "Zeitraffer (halten)") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FAST_FORWARD_KEY, - "Zeitraffer ein/aus") + "Zeitraffer ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, - "Bildervorlauf") /* @TODO: I don't know what this is */ + "Einzelbildvorlauf") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_FULLSCREEN_TOGGLE_KEY, - "Vollbild ein/aus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, - "Spielfokus ein/aus") + "Vollbildmodus ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, - "Maus greiffen ein/aus") + "Mauszeiger einfangen/loslassen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, + "Spielfokus ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "Lade Speicherstand") + "Savestate laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, - "Menü ein/aus") + "Menü aufrufen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, - "Videoaufzeichnung ein/aus") + "Videoaufzeichnung starten/beenden") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, - "Stumm ein/aus") + "Audio stumm-/lautschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, - "Netplay wechsle Benutzer") /* @TODO What does flip mean in this context? */ -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, - "Netplay Zuschauermodus ein/aus") + "Netplay-Benutzer vertauschen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, - "Bildschirmtastatus ein/aus") + "Bildschirmtastatur ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, "Nächstes Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_PAUSE_TOGGLE, - "Pause ein/aus") + "Pause/weiter") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_QUIT_KEY, "RetroArch beenden") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, @@ -365,63 +724,69 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, "Zurückspulen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Erstelle Speicherstand") + "Erstelle Savestate") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, "Erstelle Bildschirmfoto") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, "Nächster Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, - "Verheriger Shader") + "Vorheriger Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, "Zeitlupe") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Speicherstandplatz -") + "Savestate-Slot -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Speicherstandplatz +") + "Savestate-Slot +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, "Lautstärke -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, "Lautstärke +") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OSK_OVERLAY_ENABLE, - "Zeige Tastatur-Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_ENABLE, "Aktiviere Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_OVERLAY_HIDE_IN_MENU, "Overlay im Menü nicht anzeigen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR, - "Eingabeabfrageverhalten") + "Abfrageverhalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY, "Früh") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE, "Spät") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, "Normal") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, /* UPDATE/FIXME */ - "Eingabebelegungsverzeichnis") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, + "Touch-Eingabe auf der Vorderseite bevorzugen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, + "Eingabe-Belegungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, - "Bind-Remapping aktivieren") + "Tasten-Umbelegung aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, - "Speichere Autokonfigurationen") + "Speichere Autokonfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Eingabeeinstellungen") + "Eingabe-Einstellungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, + "Kleine Tastatur aktivieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, + "Touch-Eingabe aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, "Turbo aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, "Turbo-Dauer") -MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, - "Einheitliche Menüsteuerung") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, - "Spieler %u Tastenbelegung") + "Belegungen für Benutzer %u") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, + "Status des internen Speichers") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Eingabegerät-Autoconfig-Verzeichnis") + "Eingabe-Autokonfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, "Joypad-Treiber") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, + "Services") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_SIMPLIFIED, - "Chinesisch (Vereinfacht)") + "Chinesisch (vereinfacht)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_CHINESE_TRADITIONAL, - "Chinesisch (Traditionell)") + "Chinesisch (traditionell)") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_DUTCH, - "Niederländisch") + "Niederlöndisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ENGLISH, "Englisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_ESPERANTO, @@ -436,132 +801,140 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_JAPANESE, "Japanisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_KOREAN, "Koreanisch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_POLISH, + "Polnisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_PORTUGUESE, "Portugiesisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_RUSSIAN, "Russisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_SPANISH, "Spanisch") +MSG_HASH(MENU_ENUM_LABEL_VALUE_LANG_VIETNAMESE, + "Vietnamesisch") MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, "Linker Analogstick") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, - "Core-Verzeichnis") + "Core") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Core-Info-Verzeichnis") + "Core-Infos") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, - "Core-Logging-Stufe") + "Core-Loglevel") MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, "Linear") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_ARCHIVE, "Archiv laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, - "Inhalt laden (Verlauf)") /* FIXME/UPDATE */ + "Inhalt aus Verlauf laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, "Inhalt laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Spielstand laden") + "Savestate laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, - "Erlaube Standort-Lokalisierung") + "Standortbestimmung erlauben") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, - "Standorttreiber") + "Standort-Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, "Logging-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, - "Log-Ausführlichkeit") + "Logs auf Kommandozeile ausgeben") MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, "Hauptmenü") MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Datenbankeinstellungen") + "Datenbank-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, - "Menüfarbschema") + "Menü-Farbschema") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, + "Blau") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE_GREY, + "Blau/Grau") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_DARK_BLUE, + "Dunkelblau") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_GREEN, + "Grün") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_NVIDIA_SHIELD, + "Shield") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_RED, + "Rot") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_YELLOW, + "Gelb") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY, + "Footer-Transparenz") +MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_HEADER_OPACITY, + "Header-Transparenz") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, "Menütreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, - "Drossle Menübildwiederholrate") + "Bildwiederholrate im Menü begrenzen") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Einstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Wechsle Ok & Zurück Tasten im Menü") + "Dateibrowser") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, - "Linearer Filter") + "Linearer Filter für Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, - "Menüeinstellungen") + "Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER, - "Menühintergrund") + "Menü-Hintergrundbild") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_WALLPAPER_OPACITY, - "Hintergrundtransparenz") + "Hintergrundbild-Transparenz") MSG_HASH(MENU_ENUM_LABEL_VALUE_MISSING, "Fehlt") MSG_HASH(MENU_ENUM_LABEL_VALUE_MORE, "...") MSG_HASH(MENU_ENUM_LABEL_VALUE_MOUSE_ENABLE, - "Mausunterstützung") + "Maus-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_MULTIMEDIA_SETTINGS, - "Multimediaeinstellungen") + "Multimedia") MSG_HASH(MENU_ENUM_LABEL_VALUE_MUSIC_TAB, "Musik") MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, - "Bekannte Dateiendungen filtern") /* TODO/FIXME - rewrite */ + "Unbekannte Dateierweiterungen filtern") MSG_HASH(MENU_ENUM_LABEL_VALUE_NAVIGATION_WRAPAROUND, "Navigation umbrechen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, "Nächster") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, "Netplay") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, /* TODO: What actually does this? The translation might be odd. */ - "Netplay Bildübetragungsrate prüfen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, /* TODO, Original string changed */ - "Tausche Netplay-Eingabe") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, + "Netplay-Frames prüfen") /* TODO: What does this setting do? Need more context. */ +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, + "Netplay-Spieler 2 verwendet Client 1") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Verzögere Netplay-Frames") + "Netplay-Verzögerungsframes") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, "Verbindung trennen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, "Aktiviere Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT, - "Verbinde zu einem Netplay Host") + "Verbinde zu einem Netplay-Host") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_HOST, - "Starte Host") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, /* TODO, Original string changed */ - "IP-Addresse für Netplay") + "Starte Hosting") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_IP_ADDRESS, + "Server-Adresse") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LAN_SCAN_SETTINGS, - "Durchsuche lokales Netzwerk") + "Lokales Netzwerk durchsuchen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, - "Aktiviere Netplay-Client") + "Netplay-Client aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, "Benutzername") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, - "Server Passwort") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, - "Aktualisiere Lobby-Liste") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Netplay settings") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, - "Server Passwort für Zuschauer") + "Netplay-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Aktiviere Netplay-Zuschauermodus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, - "Netplay wird gestartet sobald ein Inhalt geladen wurde.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, /* TODO: What is this actually? */ - "Zustandsloser Netplay-Modus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, - "Netplay Lobbies") + "Netplay-Zuschauermodus aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, - "TCP/UDP-Port für Netplay") + "Netplay TCP/UDP-Port") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, - "Netplay NAT Traversal") + "Netplay NAT-Traversal") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_ENABLE, - "Netzwerkbefehle") + "Netzwerk-Befehle") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_CMD_PORT, - "Port für Netzwerkbefehle") + "Port für Netzwerk-Befehle") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_INFORMATION, - "Netzwerkinformationen") + "Netzwerk-Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_ENABLE, - "Network Gamepad") + "Netzwerk-Gamepad aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_REMOTE_PORT, - "Network Remote Base Port") + "Netzwerk-Remote-Port") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_SETTINGS, - "Netzwerkeinstellungen") + "Netzwerk") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO, "Nein") MSG_HASH(MENU_ENUM_LABEL_VALUE_NONE, @@ -579,45 +952,49 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_INFORMATION_AVAILABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_CORE_OPTIONS_AVAILABLE, "Keine Core-Optionen verfügbar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ENTRIES_TO_DISPLAY, - "No entries to display.") + "Keine Einträge.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_HISTORY_AVAILABLE, - "No history available.") + "Kein Verlauf verfügbar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_INFORMATION_AVAILABLE, "Keine Informationen verfügbar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_ITEMS, "Keine Einträge.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETPLAY_HOSTS_FOUND, - "Kein Netplay Host gefunden.") + "Keine Netplay-Hosts gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_NETWORKS_FOUND, - "No networks found.") + "Kein Netzwerk gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PERFORMANCE_COUNTERS, "Keine Leistungszähler.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLISTS, "Keine Wiedergabelisten.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_PLAYLIST_ENTRIES_AVAILABLE, - "Keine Einträge verfügbar.") + "Keine Wiedergabelisten-Einträge verfügbar.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SETTINGS_FOUND, "Keine Einstellungen gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_NO_SHADER_PARAMETERS, - "Keine Shaderparameter") + "Keine Shader-Parameter.") MSG_HASH(MENU_ENUM_LABEL_VALUE_OFF, - "AN") -MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, "AUS") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ON, + "EIN") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE, + "Online") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, - "Online-Aktualisierung") + "Online-Aktualisierungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, "OSD-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, "Bildschirm-Overlay") +MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, + "Bildschirm-Benachrichtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_OPEN_ARCHIVE, - "Öffne Archiv") /* TODO/FIXME */ + "Öffne Archiv als Ordner") MSG_HASH(MENU_ENUM_LABEL_VALUE_OPTIONAL, "Optional") -MSG_HASH(MENU_ENUM_LABEL_VALUE_OSK_OVERLAY_DIRECTORY, - "OSK-Overlay-Verzeichnis") +MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, + "Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, - "Automatisch bevorzuges Overlay laden") + "Bevorzugtes Overlay automatisch laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, "Overlay-Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, @@ -633,17 +1010,17 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, "Übergeordnetes Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_LIBRETRO, - "Pausiere wenn das Menü aktiv ist") + "Pausiere, wenn das Menü aktiv ist") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAUSE_NONACTIVE, - "Nicht im Hintergrund laufen") + "Nicht im Hintergrund ausführen") MSG_HASH(MENU_ENUM_LABEL_VALUE_PERFCNT_ENABLE, "Leistungsindikatoren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB, + "Wiedergabelisten") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_DIRECTORY, - "Wiedergabelistenverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, - "Löschen von Einträgen erlauben") + "Wiedergabelisten") MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_SETTINGS, - "Wiedergabelisteneinstellungen") + "Wiedergabelisten") MSG_HASH(MENU_ENUM_LABEL_VALUE_POINTER_ENABLE, "Touch-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, @@ -651,51 +1028,85 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, "Vorhanden") MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privatsphäreeinstellungen") + "Privatsphären-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, "RetroArch beenden") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, + "Analog unterstützt") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_BBFC_RATING, + "BBFC-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CERO_RATING, + "CERO-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_COOP, + "Co-op unterstützt") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_CRC32, "CRC32") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DESCRIPTION, "Beschreibung") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_DEVELOPER, "Entwickler") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_ISSUE, + "Edge Magazine-Ausgabe") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_RATING, + "Edge Magazine-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_EDGE_MAGAZINE_REVIEW, + "Edge Magazine-Testbericht") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ELSPA_RATING, + "ELSPA-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ENHANCEMENT_HW, + "Hardware-Erweiterungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ESRB_RATING, + "ESRB-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FAMITSU_MAGAZINE_RATING, + "Famitsu Magazine-Bewertung") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_FRANCHISE, "Franchise") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_GENRE, + "Genre") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_MD5, "MD5") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME, "Name") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ORIGIN, "Herkunft") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PEGI_RATING, + "PEGI-Bewertung") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_PUBLISHER, "Publisher") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_MONTH, "Veröffentlichungsmonat") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RELEASE_YEAR, "Veröffentlichungsjahr") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_RUMBLE, + "Rumble unterstützt") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SERIAL, + "Seriennummer") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_SHA1, "SHA1") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_START_CONTENT, "Starte Inhalt") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, + "TGDB-Bewertung") MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, "Neustart") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Aufnahme-Konfigurationsverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Aufnahme-Ausgabeverzeichnis") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, - "Aufnahmeeinstellungen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, "Aufnahme-Konfiguration") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, + "Aufnahme-Verzeichnis") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, + "Aufnahme") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, + "Lade Aufnahme-Konfiguration...") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Aufnahmetreiber") + "Aufnahme-Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, "Aktiviere Aufnahmefunktion") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, /* FIXME/UPDATE */ - "Aufnahmepfad") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, + "Speichere Aufnahme als...") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, - "Verwende Aufnahme-Ausgabeverzeichnis") + "Speichere Aufname im Ausgabeverzeichnis") +MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE, + "Remap-Datei") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, "Remap-Datei laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, @@ -705,107 +1116,131 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, "Notwendig") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, - "Neustarten") + "Neu starten") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_RETROARCH, "RetroArch neustarten") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME, "Fortsetzen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESUME_CONTENT, "Fortsetzen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, - "Errungenschaften") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROKEYBOARD, "RetroKeyboard") MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD, "RetroPad") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETROPAD_WITH_ANALOG, + "RetroPad mit Analogsticks") +MSG_HASH(MENU_ENUM_LABEL_VALUE_RETRO_ACHIEVEMENTS_SETTINGS, + "Errungenschaften") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_ENABLE, "Zurückspulen (Rewind) aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, "Genauigkeit des Zurückspulens (Rewind)") MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, - "Zurückspuleinstellungen") + "Zurückspulen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "Dateibrowserverzeichnis") + "File Browser") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Konfigurationsverzeichnis") + "Dateibrowser-Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, "Zeige Startbildschirm") MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, "Rechter Analogstick") MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, "Starten") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, + "SAMBA aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Spielstandverzeichnis") + "Speicherdaten-Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, "Automatische Indexierung von Spielständen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, - "Automatisches Laden von Spielständen") + "Spielstand automatisch laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, - "Automatisch Spielstände speichern") + "Spielstand automatisch speichern") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Spielstandverzeichnis") + "Spielstand-Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Spielstandminiaturansichten") + "Spielstand-Vorschaubilder") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, - "Aktuelle Konfigurationen speichern") + "Speichere aktuelle Konfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, "Speichere Core-Überschreibungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, - "Speichere Spieleüberschreibungen") + "Speichere Spiel-Überschreibungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_NEW_CONFIG, - "Neue Konfigurationen speichern") + "Speichere neue Konfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_STATE, "Spielstand speichern") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVING_SETTINGS, - "Spielstandeinstellungen") + "Speichern") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_DIRECTORY, - "Verzeichnis Durchsuchen") + "Verzeichnis durchsuchen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_FILE, - "Datei Durchsuchen") + "Datei durchsuchen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCAN_THIS_DIRECTORY, - "<- Durchsuchen ->") + "") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREENSHOT_DIRECTORY, - "Bildschirmfotoverzeichnis") + "Bildschirmfotos") MSG_HASH(MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION, - "Bildschirmauflösung") + "Bildschirm-Auflösung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SEARCH, + "Suchen:") MSG_HASH(MENU_ENUM_LABEL_VALUE_SECONDS, "Sekunden") MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS, "Einstellungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SETTINGS_TAB, + "Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER, "Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_APPLY_CHANGES, "Änderungen übernehmen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_OPTIONS, - "Shaders") + "Shader") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON, + "Band") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_RIBBON_SIMPLIFIED, + "Band (vereinfacht)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SIMPLE_SNOW, + "Schnee (vereinfacht)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOW, + "Schnee") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_ADVANCED_SETTINGS, - "Zeige erweitere Einstellungen") + "Zeige erweiterte Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_HIDDEN_FILES, - "Zeige versteckte Ordner und Dateien") + "Zeige versteckte Dateien und Ordner") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHUTDOWN, + "Beenden") MSG_HASH(MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO, "Zeitlupen-Verhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVEFILES_ENABLE, - "Sortiere Speicherdateien per Ordner") + "Sortiere Speicherdaten in Ordnern") MSG_HASH(MENU_ENUM_LABEL_VALUE_SORT_SAVESTATES_ENABLE, - "Sortiere Spielstände per Ordner") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, - "Spielstand Feld") -MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, - "Status") + "Sortiere Spielstände in Ordnern") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SSH_ENABLE, + "SSH aktivieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_START_CORE, + "Core starten") MSG_HASH(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD, "Starte Remote-RetroPad") MSG_HASH(MENU_ENUM_LABEL_VALUE_START_VIDEO_PROCESSOR, "Starte Videoprozessor") +MSG_HASH(MENU_ENUM_LABEL_VALUE_STATE_SLOT, + "Spielstand-Speicherplatz") +MSG_HASH(MENU_ENUM_LABEL_VALUE_STATUS, + "Status") MSG_HASH(MENU_ENUM_LABEL_VALUE_STDIN_CMD_ENABLE, "stdin-Befehle") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES, + "Unterstützte Cores") MSG_HASH(MENU_ENUM_LABEL_VALUE_SUSPEND_SCREENSAVER_ENABLE, "Bildschirmschoner ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_BGM_ENABLE, "Aktiviere System-BGM") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_DIRECTORY, - "System/BIOS-Verzeichnis") + "System/BIOS") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFORMATION, - "Systeminformationen") + "System-Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_7ZIP_SUPPORT, "7zip-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ALSA_SUPPORT, @@ -831,7 +1266,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DISPLAY_METRIC_MM_WIDTH, MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, "DirectSound-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, - "Dynamic-Library-Unterstützung") + "Unterstützung für dynamische Bibliotheken") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, "EGL-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, @@ -866,6 +1301,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETPLAY_SUPPORT, "Netplay-Unterstützung (Peer-to-Peer)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_COMMAND_IFACE_SUPPORT, "Netzwerk-Befehlsinterface-Unterstützung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_NETWORK_REMOTE_SUPPORT, + "Unterstützung für Netzwerk-Gamepads") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENAL_SUPPORT, "OpenAL-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_OPENGLES_SUPPORT, @@ -889,25 +1326,33 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_CHARGING, MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_DISCHARGING, "Entlädt") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_POWER_SOURCE_NO_SOURCE, - "Keine Quelle") + "Keine Stromquelle") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PULSEAUDIO_SUPPORT, "PulseAudio-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_PYTHON_SUPPORT, "Python-Unterstützung (Script-Unterstützung in Shadern)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RBMP_SUPPORT, + "BMP-Unterstützung (RBMP)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RETRORATING_LEVEL, "RetroRating-Stufe") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RJPEG_SUPPORT, + "JPEG-Unterstützung (RJPEG)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ROARAUDIO_SUPPORT, "RoarAudio-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RPNG_SUPPORT, "PNG-Unterstützung (RPNG)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RSOUND_SUPPORT, "RSound-Unterstützung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_RTGA_SUPPORT, + "TGA-Unterstützung (RTGA)") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL2_SUPPORT, "SDL2-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_IMAGE_SUPPORT, "SDL-Image-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SDL_SUPPORT, "SDL1.2-Unterstützung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_SLANG_SUPPORT, + "Slang-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_THREADING_SUPPORT, "Threading-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, @@ -915,7 +1360,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_UDEV_SUPPORT, MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_V4L2_SUPPORT, "Video4Linux2-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VIDEO_CONTEXT_DRIVER, - "Video-Context-Treiber") + "Video-Kontext-Treiber") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_VULKAN_SUPPORT, + "Vulkan-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_WAYLAND_SUPPORT, "Wayland-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_X11_SUPPORT, @@ -927,27 +1374,29 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_XVIDEO_SUPPORT, MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_ZLIB_SUPPORT, "Zlib-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_TAKE_SCREENSHOT, - "Bildschirmfoto") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, /* TODO/FIXME - update */ - "Threaded Datenschlaufe") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, - "Boxart") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, - "Bildschirmfoto") -MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, - "Titelbildschrim") + "Bildschirmfoto anfertigen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, + "Multithreading") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, "Miniaturansichten") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "Miniaturansichtenverzeichnis") + "Miniaturansichten-Verzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, - "Aktualisiere Miniaturansichten") + "Miniaturansichten aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, + "Boxarts") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_SCREENSHOTS, + "Bildschirmfoto") +MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_TITLE_SCREENS, + "Titelbildschirm") MSG_HASH(MENU_ENUM_LABEL_VALUE_TIMEDATE_ENABLE, - "Zeige Uhrzeit / Datum") + "Uhrzeit / Datum anzeigen") MSG_HASH(MENU_ENUM_LABEL_VALUE_TITLE_COLOR, - "Menü-Titel-Farbe") + "Menü-Titelfarbe") MSG_HASH(MENU_ENUM_LABEL_VALUE_TRUE, - "True") + "An") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_ENABLE, + "UI-Companion aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_COMPANION_START_ON_BOOT, "UI-Companion beim Hochfahren starten") MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, @@ -955,69 +1404,73 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_UI_MENUBAR_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_UNABLE_TO_READ_COMPRESSED_FILE, "Komprimiertes Archiv kann nicht gelesen werden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_LOAD_STATE, - "Spielstand laden rückgängig machen") + "Laden des Spielstandes rückgängig machen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, + "Speichern des Spielstandes rückgängig machen") MSG_HASH(MENU_ENUM_LABEL_VALUE_UNKNOWN, "Unbekannt") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UNDO_SAVE_STATE, - "Spielstand speichern rückgängig machen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, - "Aktualisiere Assets") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, - "Aktualisiere Autoconfig-Profile") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, - "Aktualisiere CG-Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, - "Aktualisiere Cheats") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, - "Aktualisiere Core Info Dateien") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, - "Aktualisiere Datenbanken") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, - "Aktualisiere GLSL-Shader") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, - "Aktualisiere Lakka") -MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, - "Aktualisiere Overlays") MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATER_SETTINGS, - "Aktualisierungen") + "Online-Aktualisierungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_ASSETS, + "Assets aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_AUTOCONFIG_PROFILES, + "Profile f. automatische Konfiguration aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CG_SHADERS, + "CG-Shader aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CHEATS, + "Cheats aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_CORE_INFO_FILES, + "Core-Infodateien aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_DATABASES, + "Datenbanken aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_GLSL_SHADERS, + "GLSL-Shader aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_LAKKA, + "Lakka aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_OVERLAYS, + "Overlays aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_UPDATE_SLANG_SHADERS, + "Slang-Shader aktualisieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER, "Benutzer") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_INTERFACE_SETTINGS, - "Benutzeroberflächeneinstellungen") + "Benutzeroberfläche") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_LANGUAGE, "Sprache") MSG_HASH(MENU_ENUM_LABEL_VALUE_USER_SETTINGS, - "Benutzereinstellungen") + "Benutzer") +MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER, + "Verwende eingebauten Bildbetrachter") MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_BUILTIN_PLAYER, - "Verwende integrierten Player") /* FIXME/UPDATE */ + "Verwende eingebauten Medienplayer") MSG_HASH(MENU_ENUM_LABEL_VALUE_USE_THIS_DIRECTORY, - "") + "") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ALLOW_ROTATE, "Erlaube Bildrotation") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_AUTO, "Automatisches Bildseitenverhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ASPECT_RATIO_INDEX, - "Video-Seitenverhältnis") + "Bildseitenverhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_BLACK_FRAME_INSERTION, - "Setze schwarzes Bild zwischen Frames ein") + "Schwarzes Bild zwischen Einzelbildern einfügen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Bildränder (Overscan) zuschneiden (Neustart erforderlich)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, - "Deaktiviere Desktop-Komposition") + "Deaktiviere Desktop-Gestaltung") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Grafiktreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, - "Videofilter") + "Grafikfilter") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, - "Grafikfilter-Verzeichnis") + "Grafikfilter") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_FLICKER, - "Aktiviere Flacker-Filter") + "Flacker-Filter aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_ENABLE, - "Zeige OSD-Nachrichten") + "Bildschirm-Benachrichtigungen aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_PATH, - "Schriftart der OSD-Nachrichten") + "Schriftart für Bildschirm-Benachrichtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FONT_SIZE, - "Schriftgröße der OSD-Nachrichten") + "Schritftgröße der Bildschirm-Benachrichtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, "Erzwinge Bildseitenverhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_SRGB_DISABLE, @@ -1029,23 +1482,23 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GAMMA, "Gamma") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_RECORD, - "Aktiviere GPU-Aufnahmefunktion") + "Verwende GPU für Aufnahme") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, - "Aktiviere GPU-Bildschirmfotos") + "Verwende GPU für Bildschirmfotos") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, "Synchronisiere GPU und CPU") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC_FRAMES, - "Synchronisiere Frames fest mit GPU") + "Anzahl der Frames für GPU-CPU-Sync") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Maximale Anzahl der Wechselkettenbilder") + "Maximale Anzahl von Zwischenbildern") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_X, - "X-Position der OSD-Nachrichten") + "X-Position der Bildschirm-Benachrichtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MESSAGE_POS_Y, - "Y-Position der OSD-Nachrichten") + "Y-Position der Bildschirm-Benachrichtigungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_MONITOR_INDEX, - "Monitorindex") + "Monitor-Index") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_POST_FILTER_RECORD, - "Aktiviere Aufnahme von Post-Filtern") + "Wende Filter auf Aufnahme an") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE, "Bildwiederholrate") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, @@ -1053,289 +1506,747 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_REFRESH_RATE_AUTO, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_ROTATION, "Rotation") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, - "Fenterskalierung") + "Skalierung im Fenstermodus") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, "Ganzzahlige Bildskalierung") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Videoeinstellungen") + "Video-Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, - "Grafikshader-Verzeichnis") + "Video-Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, - "Shader-Durchgänge") /* FIXME */ + "Shader-Durchläufe") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, - "Momentane Shaderparameter") /* FIXME/UPDATE */ + "Vorschau der Shader-Parameter") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, "Shader-Voreinstellung laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_PARAMETERS, - "Menü Shaderparameter (Menü)") + "Shader-Parameter für Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, - "Speichere Shader-Voreinstellung unter...") + "Shader-Voreinstellung speichern unter...") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, + "Core-Voreinstellung speichern") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_GAME, + "Spiel-Voreinstellung speichern") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHARED_CONTEXT, - "HW-Shared-Context aktivieren") + "Gemeinsamen Hardware-Kontext aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SMOOTH, - "Bilineare Filterung (HW)") + "Bilineare Filterung") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SOFT_FILTER, - "Aktiviere Soft-Filter") + "Soft-Filter aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, "VSync-Intervall") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_TAB, - "Videos") + "Video") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_THREADED, - "Threaded Video") + "Video in separatem Thread") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VFILTER, - "Bild entflackern") + "Entflackern") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_HEIGHT, - "Bildchirmauflösung Höhe") + "Bildhöhe") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_WIDTH, - "Bildchirmauflösung Breite") + "Bildbreite") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_X, - "Bildchirmauflösung X") + "X-Position des Bildes") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VIEWPORT_CUSTOM_Y, - "Bildchirmauflösung Y") + "Y-Position des Bildes") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VI_WIDTH, - "Kalibriere VI-Bildbreite") + "VI-Bildgröße") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, - "Vertikale Synchronisation (VSync)") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, - "Fensterhöhe") + "Vertikale Synchronisation (Vsync)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, + "Unechter Vollbildmodus (Windowed Fullscreen)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_WIDTH, "Fensterbreite") -MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOWED_FULLSCREEN, - "Unechter Vollbild-Modus (Windowed Fullscreen)") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_HEIGHT, + "Fensterhöhe") MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_DRIVER, "WLAN-Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "WLAN") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, - "Menüalphafaktor") + "Menü-Transparenz") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, - "Menüschriftart") + "Menü-Schriftart") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, + "Benutzerdefiniert") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, + "FlatUI") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, + "Monochrome") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, + "NeoActive") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, + "Pixel") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, + "RetroActive") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, + "Menü-Farbschema") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, + "Apple Green") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK, + "Dark") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_DARK_PURPLE, + "Dark Purple") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_ELECTRIC_BLUE, + "Electric Blue") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_GOLDEN, + "Golden") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_LEGACY_RED, + "Legacy Red") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_MIDNIGHT_BLUE, + "Midnight Blue") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_PLAIN, + "Plain") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_UNDERSEA, + "Undersea") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_VOLCANIC_RED, + "Volcanic Red") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_RIBBON_ENABLE, - "Menü-Shaderpipeline") + "Menü-Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR, - "Menüskalierungsfaktor") + "Menü-Skalierungsfaktor") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, - "Bild Schatten") -MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_ADD, - "Zeige Inhalte importieren Tab") + "Icon-Schatten aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY, - "Zeige Verlauf Tab") + "Zeige Tab 'Verlauf'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES, - "Zeige Bilder Tab") + "Zeige Tab 'Bilder'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC, - "Zeige Musik Tab") + "Zeige Tab 'Musik'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_SETTINGS, - "Zeige Einstellungen Tab") + "Zeige Tab 'Einstellungen'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_VIDEO, - "Zeige Videos Tab") + "Zeige Tab 'Video'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_THEME, - "Menüdesign") + "Menü-Design") MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, "Ja") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_ENABLE, - "Aktiviert den Audioausgang.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, - "Gewünschte Audiolatenz in Millisekunden. Je nach Audiotreiber kann die gewünschte Latenz nicht erzielt werden.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "Die maximale Änderung der Audioeingangsleistung. " - "Wenn du PAL Cores auf NTSC Monitoren spielen willst, kannst du diesen Wert erhöhen um bessere Timings zu erreichen, " - "als Nebeneffekt kann es zu unechten Tonhöhen kommen.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, - "Audio Stummschalten.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Hilft Fehler bei der Audio- und Videosynchronisierung auszubügeln. " - "Wenn deaktiviert, ist eine brauchbare Synchronisation nahezu unmöglich.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Einstellungen zur Audioausgabe.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SYNC, - "Synchronisiert Audio. Empfohlen.") -MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "Lautstärkeverstärkung in dB.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, - "Überprüfe benötigte Firmware bevor versucht wird einen Core zu laden.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, - "Aktiviert Errungenschaften. " - "Für weitere Informationen, besuche http://retroachievements.org") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, + "Shader-Voreinstellungen") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, - "Deaktiviert Spielstände, Cheats, Zurückspulen, Zeitraffer, Pause, und Zeitlupe für alle Spiele.") -MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, - "Aktiviere unoffizielle Errungenschaften und/oder Beta-Features zu Testzwecken.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Speichert Änderungen in die Konfigurationsdatei beim Beenden.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, - "Ändere die Standardeinstellungen für Konfigurationsdateien.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, - "Verwalte und erstelle Konfigurationsdateien.") -MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, - "Limitiert die Anzahl der Einträge in der Verlaufsliste.") + "Deaktiviert Spielstände, Cheats, Zurückspulen, Zeitraffer, Pause und Zeitlupe für alle Spiele.") +MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, + "Ändere die Treiber für dieses System.") +MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, + "Ändere die Einstellungen für Errungenschaften.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, "Ändere die Einstellungen der Cores.") -MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "Ändere das Standardverzeichis für dieses System.") -MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Ändere Treiber für dieses System.") -MSG_HASH(MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, - "Einige Cores haben ein Herunterfahren-Feature. " - "Wenn aktive, wird der Core davon abgehalten RetroArch herunterzufahren. " - "Stattdessen lädt es einen Dummy-Core.") +MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, + "Ändere die Einstellungen für die Aufnahme-Funktion.") +MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, + "Ändere die Einstellungen für Bildschirm-Overlays, Bildschirmtastatur und Bildschirmbenachrichtigung.") MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "Ändere die Einstellungen für Rückspulen, Zeitraffer, und Zeitlupe.") /* This does not sound like a correct sentence. Suggestions are appreciated. */ + "Ändere die Einstellungen für Zurückspulen, Zeitraffer und Zeitlupe.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, + "Ändere die Einstellungen der Speicherfunktion.") +MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, + "Ändere die Log-Einstellungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, + "Ändere die Einstellungen für die Benutzeroberläche.") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, + "Konten, Benutzername, Sprache.") +MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, + "Ändere deine Privatsphären-Einstellungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, + "Ändere die Standard-Verzeichnisse für dieses System") +MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, + "Ändere die Einstellungen für die Wiedergabelisten.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, + "Ändere die Einstellungen für das Netzwerk.") +MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, + "Sucht nach Inhalten und fügt diese zur Datenbank hinzu.") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, + "Ändert die Einstellungen der Audio-Ausgabe.") +MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, + "Aktiviert oder deaktiviert Bluetooth.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, + "Speichert Änderungen in die Konfigurationsdatei beim Beenden.") +MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, + "Anzahl der verfügbaren CPU-Kerne.") MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, "Zeigt die aktuelle Bildwiederholrate auf dem Bildschirm an.") -MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "Erfahre mehr derüber wie Retroarch funktioniert.") -MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, - "Aktiviere Wiedergabeliste für kürzlich geöffnete Medien.") -MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Zeigt Informationen über Core, Netzwerk, und des Systems an. Anzeigen-Manager für Datenbank und Zeiger.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, - "Ermöglicht jedem Spieler das Menü zu benutzen. Wenn deaktiviert, kann nur Spieler 1 das Menü benutzen.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, - "Wie weit ein Analog-Stick bewegt werden muss bis er reagiert.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, - "Anzahl Sekunden bis der nächste Bind abgehandelt wird.") /* @TODO: What is a Bind? */ -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, - "Anzahl Bilder wie lange ein Durchlauf während dem Turbomodus dauert.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, - "Einstellungen der Hotkeys.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, - "Maximale Anzahl Benutzer welche von RetroArch unterstützt werden.") + "Konfiguriere Hotkey-Einstellungen.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, - "Gamepad-Tastenkombination um ins Menü zu gelangen.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, - "Hat Einwirkungen auf die Art wie Eingabeabfragen in RetroArch abgehandelt werden. " - "Werte 'Früh' und 'Spät' kann die Latenz verringern, je nach Konfiguration.") + "Gamepad-Tastenkombination, mit der das Menü aufgerufen wird.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, "Einstellungen für Joypads, Tastaturen und Mäuse.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Anzahl Bilder wie lange der Turbomodus anhält.") -MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, - "Verwende die selbe Steuerung für Menü und Spiele. Betrifft nur Tastatur.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, - "Bedienungseinstellungen dieses Spielers.") + "Steuerung für diesen Benutzer konfigurieren.") MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, "Aktiviere Logging im Terminal.") -MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Ändere die Logging-Einstellungen.") -MSG_HASH(MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Stellt die Einstellungen für das Aussehen des Menübildschirms ein.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, - "Hoste eine Netplay Session oder trete einer bei.") + "Hoste eine Netplay-Sitzung oder trete einer bei.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, - "Suche und verbinde mit Netplay Hosts in deinem lokalen Netzwerk.") -MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, - "Ändere die Netzwerkeinstellungen.") + "Suche und verbinde mit Netplay-Hosts in deinem lokalen Netzwerk.") +MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, + "Zeigt Informationen über Core, Netzwerk und das Systems an.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "Lade Add-Ons, Komponenten und Inhalte für RetroArch herunter.") -MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "Ändere die Einstellungen des Display-Overlays, Bildschirmtastatur und Bildschirmbenachrichtigung.") /* There is no Translation for display overlay. */ -MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Spiel pausieren wenn das Fenster den Fokus verliert.") -MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Ändere die Einstellungen der Wiedergabelisten.") -MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, - "Ändere deine Privatsphäreneinstellungen.") -MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Ändere die Einstellungen der Errungenschaften.") -MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "Ändere die Einstellungen der Spielstände.") + "Lade Erweiterungen, Komponenten und Inhalte für RetroArch herunter.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, + "Aktiviere die Netzwerkfreigabe deiner Ordner.") +MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, + "Verwalte Service-Einstellungen deines Betriebssystems.") MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_HIDDEN_FILES, - "Zeigt versteckte Dateien und Ordner im Dateimanager an.") + "Zeige versteckte Dateien und Ordner im Dateimanager an.") +MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, + "Aktiviere Fernzugriff auf die Kommandozeile.") MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, - "Haltet dein System davon ab den Bildschirmschoner zu aktivieren.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "Ändere die Einstellungen der Benutzeroberfläche.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, - "Ändere die Sprache der Oberfläche.") -MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, - "Ändere das Konto, Benutzername, und die Sprache.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, - "Erlaubt Cores die Rotation zu setzen. Wenn deaktiviert, Rotationsanfragen werden ignoriert. Nützlich für Geräte bei denen man die Rotation manuell wählt.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "Zeigt ein schwarzes Bild zwischen Frames an. Nützlich für 120 Hz Monitore welche 60 Hz mit weniger 'ghosting' möchten.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, - "Deaktiviere Desktop-Komposition. (Nur bei Windows)") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, - "Zeige Bildschirmbenachrichtigungen an.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "Reduziert Latenz, kann aber zu Anzeigefehlern führen. Fügt einen Unterbruch bei V-Sync hinzu (in ms).") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Hartsynchronisierung des CPU und der GPU. Reduziert Latenz, braucht aber mehr Leistung.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "Anzahl Bilder welche die CPU der GPU voraus sein darf wenn die 'Hartsynchronisierung' verwendet wird.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, - "Zwingt den Videotreiber explizit einen bestimmten Puffer zu verwenden.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, - "Wählt den Monitor aus welcher RetroArch anzeigen soll.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Vertikale Bildwiederholrate des Monitors. " - "Wird verwendet um die passende Audioinputrate zu berechnen. " - "WICHTIG: Diese Option wird ignoriert wenn du 'Threaded Video' aktiviert hast.") /* TODO: Any way to inject the reference in the .h file? */ -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, - "Die genau geschätzte Bildwiederholrate des Monitors in Hz.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "Einstellungen zur Videoausgabe.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, - "Gibt hardware-gerendered Cores einen eigenen privaten Kontext. Vermeided den Hardware-State anzunehmen zwischen den Frames.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Verbessert die Leistung, führt aber zu grösserer Latenz und Videoproblemen. " - "Verwende dies nur wenn du sonst die gewünschte Leistung erbringst.") -MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VSYNC, - "Synchronisiert den Video-Output der Grafikkarte zu der Bildwiederholrate des Monitors. Empfohlen.") + "Hält dein System davon ab, den Bildschirmschoner zu aktivieren.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, - "Setzt die Fenstergrösse relativ zu der Core-Fenstergrösse. " - "Alternativ kannst du die Fenstergrösse weiter unten setzten für eine konstante Grösse.") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Zurück") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Bestätigen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Info") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "Runter Scrollen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "Hoch Scrollen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Starten") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Tastatur ein/aus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "Menü ein/aus") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Beenden") -MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, - "Batteriestand anzeigen") -MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Lade inhaltsspezifische Core-Optionen automatisch") -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, - "Browse URL" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_URL, - "URL Path" - ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_BROWSE_START, - "Start" - ) -MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, - "Bokeh") + "Legt die Fenstergröße relativ zu der Core-Bildgröße fest. Alternativ kannst Du weiter unten die Höhe und Breite des Bildes selbst anpassen.") +MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, + "Legt die Sprache der Benutzeroberfläche fest.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, + "Fügt ein schwarzes Bild zwischen Einzelbildern ein. Nützlich für Benutzer von 120Hz-Monitoren, die 60Hz mit weniger 'ghosting' wünschen.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, + "Reduziert Latenz, kann aber zu Anzeigefehlern führen. Fügt eine Verzögerung bei V-Sync hinzu (in ms).") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, + "Anzahl der Bilder, die die CPU der GPU voraus sein darf, wenn die CPU/GPU-Synchronisation aktiviert ist.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + "Zwingt den Videotreiber dazu, einen bestimmten Framebuffer zu verwenden.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, + "Wält den Bildschirm aus, der für RetroArch verwendet wird.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, + "Die geschätzte Bildwiederholrate des Bildschirms in Hz.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, + "Einstellungen für die Videoausgabe anpassen.") +MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, + "Sucht nach drahtlosen Netzwerken und stellt eine Verbindung her.") +MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, + "Erfahre mehr darüber, wie Retroarch funktioniert.") +MSG_HASH(MSG_APPENDED_DISK, + "Datenträger hinzufügen") +MSG_HASH(MSG_APPLICATION_DIR, + "Anwendungs-Verzeichnis") +MSG_HASH(MSG_APPLYING_CHEAT, + "Änderungen übernehmen.") +MSG_HASH(MSG_APPLYING_SHADER, + "Shader anwenden") +MSG_HASH(MSG_AUDIO_MUTED, + "Audio stummgeschaltet.") +MSG_HASH(MSG_AUDIO_UNMUTED, + "Audio laut.") +MSG_HASH(MSG_AUTOCONFIG_FILE_ERROR_SAVING, + "Speichern der Autokonfigurations-Datei fehlgeschlagen.") +MSG_HASH(MSG_AUTOCONFIG_FILE_SAVED_SUCCESSFULLY, + "Autokonfigurations-Datei erfolgreich gespeichert.") +MSG_HASH(MSG_AUTOSAVE_FAILED, + "Initialisierung der Autospeichern-Funktion fehlgeschlagen.") +MSG_HASH(MSG_AUTO_SAVE_STATE_TO, + "Spielstand automatisch speichern in") +MSG_HASH(MSG_BLOCKING_SRAM_OVERWRITE, + "Überschreiben des SRAM blockieren") +MSG_HASH(MSG_BRINGING_UP_COMMAND_INTERFACE_ON_PORT, + "Starte Befehlsinterface auf Port") +MSG_HASH(MSG_BYTES, + "Bytes") +MSG_HASH(MSG_CANNOT_INFER_NEW_CONFIG_PATH, + "Kann neuen Konfigurationspfad nicht ableiten. Verwende aktuelle Zeit.") /* huh?*/ +MSG_HASH(MSG_CHEEVOS_HARDCORE_MODE_ENABLE, + "Hardcore-Modus aktiviert. Spielstände & die Rückspul-Funktion wurden ausgeschaltet.") +MSG_HASH(MSG_COMPARING_WITH_KNOWN_MAGIC_NUMBERS, + "Vergleiche mit bekannten Magic Numbers...") +MSG_HASH(MSG_COMPILED_AGAINST_API, + "Kompiliert gegen API") +MSG_HASH(MSG_CONFIG_DIRECTORY_NOT_SET, + "Konfigurations-Verzeichnis nicht definiert. Kann neue Konfiguration nicht speichern.") +MSG_HASH(MSG_CONNECTED_TO, + "Verbunden mit") +MSG_HASH(MSG_CONTENT_CRC32S_DIFFER, + "CRC32-Prüfsummen des Inhalts weichen ab. Andere Spiele können nicht verwendet werden.") +MSG_HASH(MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT, + "Laden des Inhalts übersprungen. Die Implementierung wird ihn selbst laden.") +MSG_HASH(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES, + "Core unterstützt keine Spielstände.") +MSG_HASH(MSG_CORE_OPTIONS_FILE_CREATED_SUCCESSFULLY, + "Core-Optionsdatei wurde erfolgreich erstellt.") +MSG_HASH(MSG_COULD_NOT_FIND_ANY_NEXT_DRIVER, + "Konnte keinen nächsten Treiber finden") +MSG_HASH(MSG_COULD_NOT_FIND_COMPATIBLE_SYSTEM, + "Konnte kein kompatibles System finden") +MSG_HASH(MSG_COULD_NOT_FIND_VALID_DATA_TRACK, + "Konnte keinen gültigen Daten-Track finden") +MSG_HASH(MSG_COULD_NOT_OPEN_DATA_TRACK, + "Konnte Daten-Track nicht öffnen") +MSG_HASH(MSG_COULD_NOT_READ_CONTENT_FILE, + "Konnte Inhalts-Datei nicht lesen") +MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, + "Konnte Film-Header nicht lesen.") +MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, + "Konnte Status der Filmdatei nicht lesen.") +MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, + "CRC32-Prüfsumme des Inhalts und die gespeicherte Prüfsumme der Replay-Datei stimmen nicht überein. Wird die Aufzeichnung wiedergegeben, wird sie sehr wahrscheinlich asynchron.") +MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, + "Benutzerdefiniertes Timing gefunden") +MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, + "Dekompression läuft bereits.") +MSG_HASH(MSG_DECOMPRESSION_FAILED, + "Dekompression fehlgeschlagen.") +MSG_HASH(MSG_DETECTED_VIEWPORT_OF, + "Erkannte Bildbereich von") +MSG_HASH(MSG_DID_NOT_FIND_A_VALID_CONTENT_PATCH, + "Kein gültiger Patch für diesen Inhalt gefunden.") +MSG_HASH(MSG_DISCONNECT_DEVICE_FROM_A_VALID_PORT, + "Gerät von einem gültigen Anschluss trennen.") +MSG_HASH(MSG_DISK_CLOSED, + "Geschlossen") +MSG_HASH(MSG_DISK_EJECTED, + "Ausgeworfen") MSG_HASH(MSG_DOWNLOADING, - "Herunterladen") + "Herunterladen von") MSG_HASH(MSG_DOWNLOAD_FAILED, "Herunterladen fehlgeschlagen") MSG_HASH(MSG_ERROR, "Fehler") +MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT, + "Libretro-Core benötigt Inhalt, es wurde jedoch keiner bereitgestellt.") +MSG_HASH(MSG_ERROR_LIBRETRO_CORE_REQUIRES_SPECIAL_CONTENT, + "Libretro-Core benötigt speziellen Inhalt, es wurde jedoch keiner bereitgestellt.") +MSG_HASH(MSG_ERROR_PARSING_ARGUMENTS, + "Fehler beim Verarbeiten der Argumente.") +MSG_HASH(MSG_ERROR_SAVING_CORE_OPTIONS_FILE, + "Fehler beim Speichern der Core-Optionen") +MSG_HASH(MSG_ERROR_SAVING_REMAP_FILE, + "Fehler beim Speichern der Tasten-Umbelegung.") +MSG_HASH(MSG_ERROR_SAVING_SHADER_PRESET, + "Fehler beim Speichern der Shader-Voreinstellungen.") +MSG_HASH(MSG_EXTERNAL_APPLICATION_DIR, + "Externe Anwendungen") MSG_HASH(MSG_EXTRACTING, - "Extrahiere") + "Entpacke") MSG_HASH(MSG_EXTRACTING_FILE, - "Extrahiere Datei") + "Entpacke Datei") +MSG_HASH(MSG_FAILED_SAVING_CONFIG_TO, + "Fehler beim Speichern der Konfiguration in") +MSG_HASH(MSG_FAILED_TO, + "Fehler beim") +MSG_HASH(MSG_FAILED_TO_ACCEPT_INCOMING_SPECTATOR, + "Ankommender Beobachter konnte nicht akzeptiert werden.") +MSG_HASH(MSG_FAILED_TO_ALLOCATE_MEMORY_FOR_PATCHED_CONTENT, + "Fehler beim zuweisen des Arbeitsspeichers für den gepatchten Inhalt...") +MSG_HASH(MSG_FAILED_TO_APPLY_SHADER, + "Fehler beim Anwenden des Shaders.") +MSG_HASH(MSG_FAILED_TO_BIND_SOCKET, + "Fehler beim binden des Sockets.") +MSG_HASH(MSG_FAILED_TO_CREATE_THE_DIRECTORY, + "Fehler beim Erstellen des Verzeichnisses.") +MSG_HASH(MSG_FAILED_TO_EXTRACT_CONTENT_FROM_COMPRESSED_FILE, + "Fehler beim Entpacken des Inhalts aus dem Archiv") +MSG_HASH(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT, + "Benutzername konnte vom Client nicht gelesen werden.") +MSG_HASH(MSG_FAILED_TO_LOAD, + "Laden fehlgeschlagen") +MSG_HASH(MSG_FAILED_TO_LOAD_CONTENT, + "Laden des Inhalts fehlgeschlagen") +MSG_HASH(MSG_FAILED_TO_LOAD_MOVIE_FILE, + "Laden der Filmdatei fehlgeschlagen") +MSG_HASH(MSG_FAILED_TO_LOAD_OVERLAY, + "Laden des Overlays fehlgeschlagen.") +MSG_HASH(MSG_FAILED_TO_LOAD_STATE, + "Fehler beim Laden des Spielstands von") +MSG_HASH(MSG_FAILED_TO_OPEN_LIBRETRO_CORE, + "Öffnen des Libretro-Cores fehlgeschlagen") +MSG_HASH(MSG_FAILED_TO_PATCH, + "Patch fehlgeschlagen") +MSG_HASH(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT, + "Header konnte nicht vom Client empfangen werden.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME, + "Empfangen des Nickname fehlgeschlagen.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST, + "Empfangen des Nickname vom Host fehlgeschlagen.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_NICKNAME_SIZE_FROM_HOST, + "Länge des Nickname wurde vom Host nicht empfangen.") +MSG_HASH(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST, + "SRAM-Daten wurden vom Host nicht empfangen.") +MSG_HASH(MSG_FAILED_TO_REMOVE_DISK_FROM_TRAY, + "Auswerfen des Datenträgers fehlgeschlagen.") +MSG_HASH(MSG_FAILED_TO_REMOVE_TEMPORARY_FILE, + "Fehler beim entfernen der temporären Datei") +MSG_HASH(MSG_FAILED_TO_SAVE_SRAM, + "Fehler beim Speichern des SRAM") +MSG_HASH(MSG_FAILED_TO_SAVE_STATE_TO, + "Fehler beim Speichern des Spielstands in") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME, + "Fehler beim Senden des Nickname.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_SIZE, + "Fehler beim Senden der Nickname-Länge.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT, + "Fehler beim Senden des Nickname zum Client.") +MSG_HASH(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST, + "Fehler beim Senden des Nickname zum Host.") +MSG_HASH(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT, + "Fehler beim Senden der SRAM-Daten zum Client.") +MSG_HASH(MSG_FAILED_TO_START_AUDIO_DRIVER, + "Audiotreiber konnte nicht gestartet werden. Fahre ohne Audio fort.") +MSG_HASH(MSG_FAILED_TO_START_MOVIE_RECORD, + "Konnte Film-Aufzeichnung nicht starten.") +MSG_HASH(MSG_FAILED_TO_START_RECORDING, + "Konnte Aufzeichnung nicht starten.") +MSG_HASH(MSG_FAILED_TO_TAKE_SCREENSHOT, + "Konnte Bildschirmfoto nicht erstellen.") +MSG_HASH(MSG_FAILED_TO_UNDO_LOAD_STATE, + "Laden des Spielstands konnte nicht rückgängig gemacht werden.") +MSG_HASH(MSG_FAILED_TO_UNDO_SAVE_STATE, + "Speichern des Spielstands konnte nicht rückgängig gemacht werden.") +MSG_HASH(MSG_FAILED_TO_UNMUTE_AUDIO, + "Audio konnte nicht lautgeschaltet werden.") +MSG_HASH(MSG_FATAL_ERROR_RECEIVED_IN, + "Fataler Fehler in") +MSG_HASH(MSG_FILE_NOT_FOUND, + "Datei nicht gefunden") +MSG_HASH(MSG_FOUND_AUTO_SAVESTATE_IN, + "Spielstand gefunden in") +MSG_HASH(MSG_FOUND_DISK_LABEL, + "Datenträger-Label gefunden") +MSG_HASH(MSG_FOUND_FIRST_DATA_TRACK_ON_FILE, + "Ersten Daten-Track in der Datei gefunden") +MSG_HASH(MSG_FOUND_LAST_STATE_SLOT, + "Letzten Speicherplatz gefunden") +MSG_HASH(MSG_FOUND_SHADER, + "Shader gefunden") +MSG_HASH(MSG_FRAMES, + "Bilder") +MSG_HASH(MSG_GAME_SPECIFIC_CORE_OPTIONS_FOUND_AT, + "Spieloptionen: Spielspezifische Core-Optionen gefunden in") +MSG_HASH(MSG_GOT_INVALID_DISK_INDEX, + "Ungültiger Datenträger-Index.") +MSG_HASH(MSG_GRAB_MOUSE_STATE, + "Maus-Status") +MSG_HASH(MSG_GAME_FOCUS_ON, + "Spielfokus ein") +MSG_HASH(MSG_GAME_FOCUS_OFF, + "Spielfokus aus") +MSG_HASH(MSG_HW_RENDERED_MUST_USE_POSTSHADED_RECORDING, + "Der Libretro-Core ist Hardware-gerendert. GPU-Aufzeichnung muss ebenfalls aktiviert werden.") +MSG_HASH(MSG_INFLATED_CHECKSUM_DID_NOT_MATCH_CRC32, + "Prüfsumme entspricht nicht CRC32.") +MSG_HASH(MSG_INPUT_CHEAT, + "Cheat eingeben") +MSG_HASH(MSG_INPUT_CHEAT_FILENAME, + "Cheat-Dateiname") +MSG_HASH(MSG_INPUT_PRESET_FILENAME, + "Vorlagen-Dateiname") +MSG_HASH(MSG_INTERFACE, + "Benutzeroberläche") +MSG_HASH(MSG_INTERNAL_STORAGE, + "Interner Speicher") +MSG_HASH(MSG_REMOVABLE_STORAGE, + "Wechseldatenträger") +MSG_HASH(MSG_INVALID_NICKNAME_SIZE, + "Ungültige Nickname-Länge.") +MSG_HASH(MSG_IN_BYTES, + "in Bytes") +MSG_HASH(MSG_IN_GIGABYTES, + "in Gigabyte") +MSG_HASH(MSG_IN_MEGABYTES, + "in Megabyte") +MSG_HASH(MSG_LIBRETRO_ABI_BREAK, + "ist gegen eine andere libretro-Version als diese kompiliert.") +MSG_HASH(MSG_LIBRETRO_FRONTEND, + "Frontend für libretro") +MSG_HASH(MSG_LOADED_STATE_FROM_SLOT, + "Spielstand aus Speicherplatz #%d geladen.") +MSG_HASH(MSG_LOADED_STATE_FROM_SLOT_AUTO, + "Spielstand aus Speicherplatz #-1 (auto) geladen.") +MSG_HASH(MSG_LOADING, + "Laden...") +MSG_HASH(MSG_FIRMWARE, + "Eine oder mehrere Firmware-Dateien fehlen") +MSG_HASH(MSG_LOADING_CONTENT_FILE, + "Lade Inhalts-Datei") +MSG_HASH(MSG_LOADING_HISTORY_FILE, + "Lade Verlaufs-Datei") +MSG_HASH(MSG_LOADING_STATE, + "Lade Spielstand") +MSG_HASH(MSG_MEMORY, + "Speicher") +MSG_HASH(MSG_MOVIE_FILE_IS_NOT_A_VALID_BSV1_FILE, + "Filmdatei ist keine gültige BSV1-Datei.") +MSG_HASH(MSG_MOVIE_FORMAT_DIFFERENT_SERIALIZER_VERSION, + "Filmdatei besitzt offenbar eine andere Serializer-Version. Wird höchstwahrscheinlich fehlschlagen.") +MSG_HASH(MSG_MOVIE_PLAYBACK_ENDED, + "Film-Wiedergabe beendet.") +MSG_HASH(MSG_MOVIE_RECORD_STOPPED, + "Beende Film-Aufzeichnung.") +MSG_HASH(MSG_NETPLAY_FAILED, + "Netplay-Initialisierung fehlgeschlagen.") +MSG_HASH(MSG_NO_CONTENT_STARTING_DUMMY_CORE, + "Kein Inhalt, starte Dummy-Core.") +MSG_HASH(MSG_NO_SAVE_STATE_HAS_BEEN_OVERWRITTEN_YET, + "Kein Spielstand wurde bis jetzt überschrieben.") +MSG_HASH(MSG_NO_STATE_HAS_BEEN_LOADED_YET, + "Kein Spielstand wurde bis jetzt geladen.") MSG_HASH(MSG_OVERRIDES_ERROR_SAVING, "Fehler beim Speichern der Überschreibungen.") MSG_HASH(MSG_OVERRIDES_SAVED_SUCCESSFULLY, - "Überschreibungen wurden erfolgreich gespeichert.") + "Überschreibungen erfolgreich gespeichert.") +MSG_HASH(MSG_PAUSED, + "Pausiert.") +MSG_HASH(MSG_PROGRAM, + "RetroArch") +MSG_HASH(MSG_READING_FIRST_DATA_TRACK, + "Lese ersten Daten-Track...") +MSG_HASH(MSG_RECEIVED, + "empfangen") +MSG_HASH(MSG_RECORDING_TERMINATED_DUE_TO_RESIZE, + "Aufzeichnung wurde wegen Größenänderung beendet.") +MSG_HASH(MSG_RECORDING_TO, + "Aufzeichen in") +MSG_HASH(MSG_REDIRECTING_CHEATFILE_TO, + "Cheat-Datei umleiten in") +MSG_HASH(MSG_REDIRECTING_SAVEFILE_TO, + "Speicherdaten umleiten in") +MSG_HASH(MSG_REDIRECTING_SAVESTATE_TO, + "Spielstand umleiten in") +MSG_HASH(MSG_REMAP_FILE_SAVED_SUCCESSFULLY, + "Remap-Datei wurde erfolgreich gespeichert.") +MSG_HASH(MSG_REMOVED_DISK_FROM_TRAY, + "Datenträger aus Laufwerk entfernt.") +MSG_HASH(MSG_REMOVING_TEMPORARY_CONTENT_FILE, + "Entferne temporäre Inhalts-Datei") +MSG_HASH(MSG_RESET, + "Zurücksetzen") +MSG_HASH(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT, + "Starte Aufzeichnung neu, da Treiber reinitialisiert wurde.") +MSG_HASH(MSG_RESTORED_OLD_SAVE_STATE, + "Alter Spielstand wiederhergestellt") +MSG_HASH(MSG_RESTORING_DEFAULT_SHADER_PRESET_TO, + "Shader: Standard-Shader-Voreinstellung wiederhergestellt zu") +MSG_HASH(MSG_REVERTING_SAVEFILE_DIRECTORY_TO, + "Setze Speicherdaten-Verzeichnis zurück auf") +MSG_HASH(MSG_REVERTING_SAVESTATE_DIRECTORY_TO, + "Setze Spielstand-Verzeichnis zurück auf") +MSG_HASH(MSG_REWINDING, + "Zurückspulen.") +MSG_HASH(MSG_REWIND_INIT, + "Initialisiere Rückspul-Puffer mit Größe") +MSG_HASH(MSG_REWIND_INIT_FAILED, + "Fehler beim Initialisieren des Rückspul-Puffers. Zurückspulen wird deaktiviert.") +MSG_HASH(MSG_REWIND_INIT_FAILED_THREADED_AUDIO, + "Implementierung verwendet separaten Audio-Thread. Zurückspulen kann nicht verwendet werden.") +MSG_HASH(MSG_REWIND_REACHED_END, + "Ende des Rückspul-Puffers erreicht.") +MSG_HASH(MSG_SAVED_NEW_CONFIG_TO, + "Neue Konfiguration gespeichert in") +MSG_HASH(MSG_SAVED_STATE_TO_SLOT, + "Spielstand in Speicherplatz #%d gespeichert.") +MSG_HASH(MSG_SAVED_STATE_TO_SLOT_AUTO, + "Spielstand in Speicherplatz #-1 (auto) gespeichert.") +MSG_HASH(MSG_SAVED_SUCCESSFULLY_TO, + "Erfolgreich gespeichert in") +MSG_HASH(MSG_SAVING_RAM_TYPE, + "Speichere RAM-Typ") +MSG_HASH(MSG_SAVING_STATE, + "Speichere Spielstand") /* more context needed */ MSG_HASH(MSG_SCANNING, - "Durchsuche") /* Used for displaying progress */ + "Durchsuchen") MSG_HASH(MSG_SCANNING_OF_DIRECTORY_FINISHED, - "Durchsuchen des Verzeichnisses wurde beendet.") \ No newline at end of file + "Durchsuchen des Verzeichnisses beendet") +MSG_HASH(MSG_SENDING_COMMAND, + "Sende Befehl") +MSG_HASH(MSG_SEVERAL_PATCHES_ARE_EXPLICITLY_DEFINED, + "Mehrere Patches wurden explizit definiert, ignoriere alle...") +MSG_HASH(MSG_SHADER, + "Shader") +MSG_HASH(MSG_SHADER_PRESET_SAVED_SUCCESSFULLY, + "Shader-Voreinstellung erfolgreich gespeichert.") +MSG_HASH(MSG_SKIPPING_SRAM_LOAD, + "Überspringe Laden des SRAM.") +MSG_HASH(MSG_SLOW_MOTION, + "Zeitlupe.") +MSG_HASH(MSG_SLOW_MOTION_REWIND, + "In Zeitlupe zurückspulen.") +MSG_HASH(MSG_SRAM_WILL_NOT_BE_SAVED, + "SRAM wird nicht gespeichert.") +MSG_HASH(MSG_STARTING_MOVIE_PLAYBACK, + "Starte Film-Wiedergabe.") +MSG_HASH(MSG_STARTING_MOVIE_RECORD_TO, + "Starte Film-Aufzeichnung in") +MSG_HASH(MSG_STATE_SIZE, + "Spielstand-Größe") +MSG_HASH(MSG_STATE_SLOT, + "Spielstand-Speicherplatz") +MSG_HASH(MSG_TAKING_SCREENSHOT, + "Erstelle Bildschirmfoto.") +MSG_HASH(MSG_TO, + "nach") +MSG_HASH(MSG_UNDID_LOAD_STATE, + "Laden des Spielstands wurde rückgängig gemacht.") +MSG_HASH(MSG_UNDOING_SAVE_STATE, + "Speichern des Spielstands wurde rückgängig gemacht.") +MSG_HASH(MSG_UNKNOWN, + "Unbekannt") +MSG_HASH(MSG_UNPAUSED, + "Nicht pausiert.") +MSG_HASH(MSG_UNRECOGNIZED_COMMAND, + "Unbekannter Befehl") +MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, + "Verwende Core-Namen für neue Konfiguration.") +MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, + "Verwende libretro-Dumy-Core. Überspringe Aufzeichnung.") +MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, + "Verbinde Gerät von einem gültigen Anschluss.") /* sounds odd, maybe improper translation*/ +MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, + "Trenne Gerät von Anschluss") +MSG_HASH(MSG_VALUE_REBOOTING, + "Neustart...") +MSG_HASH(MSG_VALUE_SHUTTING_DOWN, + "Beenden...") +MSG_HASH(MSG_VERSION_OF_LIBRETRO_API, + "Version der libretro-API") +MSG_HASH(MSG_VIEWPORT_SIZE_CALCULATION_FAILED, + "Berechnung der Bildgröße fehlgeschlagen! Wird unter Verwendung von Rohdaten fortfahren. Dies wird wahrscheinlich nicht richtig funktionieren ...") +MSG_HASH(MSG_VIRTUAL_DISK_TRAY, + "Virtuelle Laufwerksschublade.") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_LATENCY, + "Gewünschte Audiolatenz in Millisekunden. Je nach Audiotreiber kann die gewünschte Latenz nicht erzielt werden; diese Einstellung wird dann ignoriert.") +MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, + "Audio stumm-/lautschalten.") +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, + "Hilft Fehler bei der Audio- und Videosynchronisierung auszubügeln. " + "Wenn deaktiviert, ist eine brauchbare Synchronisation nahezu unmöglich.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_ALLOW, + "Erlaube oder verbiete den Cores Zugriff auf die Kamera." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_ALLOW, + "Erlaube oder verbiete den Cores Zugriff auf Ortsdienste." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_MAX_USERS, + "Maximale Anzahl von Benutzern, die von RetroArch unterstützt werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_POLL_TYPE_BEHAVIOR, + "Beeinflusst, wie die Eingabe in RetroArch abgefragt wird. Wird dieser Wert auf 'Früh' oder 'Spät' gesetzt, kann sich je nach Konfiguration die Latenz verringern." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_ALL_USERS_CONTROL_MENU, + "Ermöglicht jedem Benutzer das Menü zu benutzen. Wenn deaktiviert, kann nur Benutzer 1 das Menü benutzen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_VOLUME, + "Lautstärkeverstärkung in dB. 0 dB ist die normale Lautstärke, es erfolgt eine Verstärkung." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_SYNC, + "Synchronisiere Audio. Empfohlen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AXIS_THRESHOLD, + "Wie weit ein Analog-Stick bewegt werden muss, bis er reagiert." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_BIND_TIMEOUT, + "Zeitdauer in Sekunden, nach der die nächste Tastenbelegung abgefragt wird." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, + "Beschreibt, nach wie vielen Einzelbildern eine Taste mit aktiviertem Turbo-Modus erneut gedrückt wird." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, + "Beschreibt, wie lange eine Taste mit aktivierem Turbo-Modus 'gedrückt' wird. Dieser Wert wird in der Anzahl der Einzelbilder angegeben." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_VSYNC, + "Synchronisiert die Video-Ausgabe der Grafikkarte mit der Bildwiederholrate des Bildschirms. Empfohlen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ALLOW_ROTATE, + "Erlaubt Cores, die Bildrotation zu setzen. Wenn deaktiviert, werden Anfragen nach der Bildrotation deaktiviert. Nützlich für Bildschirme, die manuell gedreht werden sollen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DUMMY_ON_CORE_SHUTDOWN, + "Einige Cores haben eine eigene Abschalt-Funktion. Wenn aktiviert, wird der Core daran gehindert, RetroArch zu beenden. Stattdessen wird ein Dummy-Core geladen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHECK_FOR_MISSING_FIRMWARE, + "Überprüft, ob eventuell benötigte Firmware vorhanden ist, bevor versucht wird, Inhalte zu laden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, + "Vertikale Bildwiederholrate des Bildschirms. Wird verwendet, um eine geeignete Audio-Eingangsrate zu berechnen. Hinweis: Diese Einstellung wird ignoriert, wenn 'Video in separatem Thread' aktiviert ist." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_ENABLE, + "Aktiviere Audio-Ausgabe." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, + "Maximale Änderung der Audio-Eingangsrate. Dieser Wert kann erhöht werden, wenn sehr große Änderungen im Timing aktiviert werden sollen, (beispielsweise um einen PAL-Core auf einem NTSC-Bildschirm darzustellen), verursacht jedoch fehlerhafte Tonhöhen." + ) +MSG_HASH( + MSG_FAILED, + "fehlgeschlagen" + ) +MSG_HASH( + MSG_SUCCEEDED, + "erfolgreich" + ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED, + "nicht konfiguriert" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, + "Datenbank-Zeiger" /* might be inaccurate */ + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, + "Datenbank - Filter : Entwickler" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PUBLISHER, + "Datenbank - Filter : Publisher" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DISABLED, + "Deaktiviert" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_ENABLED, + "Aktiviert" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_PATH, + "Pfad zur Verlaufsliste" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ORIGIN, + "Datenbank - Filter : Herkunft") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_FRANCHISE, + "Datenbank - Filter : Franchise") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ESRB_RATING, + "Datenbank - Filter : ESRB-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_ELSPA_RATING, + "Datenbank - Filter : ELSPA-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_PEGI_RATING, + "Datenbank - Filter : PEGI-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_CERO_RATING, + "Datenbank - Filter : CERO-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_BBFC_RATING, + "Datenbank - Filter : BBFC-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_MAX_USERS, + "Datenbank - Filter : Max. Spieler") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_MONTH, + "Datenbank - Filter : Veröffentlichungsdatum nach Monat") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_RELEASEDATE_BY_YEAR, + "Datenbank - Filter : Veröffentlichungsdatum nach Jahr") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_ISSUE, + "Datenbank - Filter : Edge Magazine-Ausgabe") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_EDGE_MAGAZINE_RATING, + "Datenbank - Filter : Edge Magazine-Bewertung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DATABASE_INFO, + "Datenbank-Informationen") +MSG_HASH(MSG_WIFI_SCAN_COMPLETE, + "Suche nach WLAN-Netzwerken abgeschlossen.") +MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, + "Suche nach WLAN-Netzwerken...") +MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, + "Netplay-Suche abgeschlossen.") +MSG_HASH(MSG_NETPLAY_LAN_SCANNING, + "Suche nach Netplay-Hosts...") \ No newline at end of file From aa77d688ec3728a8dc75976557a895acf1e2f57c Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Mon, 6 Feb 2017 13:45:58 -0500 Subject: [PATCH 34/90] Make announcing netplay on the public lobby optional. --- config.def.h | 3 +++ configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 ++ intl/msg_hash_us.c | 7 +++++++ intl/msg_hash_us.h | 6 ++++++ menu/cbs/menu_cbs_sublabel.c | 4 ++++ menu/menu_displaylist.c | 4 ++++ menu/menu_setting.c | 15 +++++++++++++++ msg_hash.h | 1 + network/netplay/netplay_frontend.c | 20 ++++++++++++++++---- 11 files changed, 60 insertions(+), 4 deletions(-) diff --git a/config.def.h b/config.def.h index 0866e35bda..6b01bc9e59 100644 --- a/config.def.h +++ b/config.def.h @@ -815,6 +815,9 @@ static const bool pause_nonactive = true; * It is measured in seconds. A value of 0 disables autosave. */ static const unsigned autosave_interval = 0; +/* Publicly announce netplay */ +static const bool netplay_public_announce = true; + /* Netplay without savestates/rewind */ static const bool netplay_stateless_mode = false; diff --git a/configuration.c b/configuration.c index 0954be6433..1266640cbe 100644 --- a/configuration.c +++ b/configuration.c @@ -728,6 +728,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("all_users_control_menu", &settings->input.all_users_control_menu, true, all_users_control_menu, false); SETTING_BOOL("menu_swap_ok_cancel_buttons", &settings->input.menu_swap_ok_cancel_buttons, true, menu_swap_ok_cancel_buttons, false); #ifdef HAVE_NETWORKING + SETTING_BOOL("netplay_public_announce", &settings->netplay.public_announce, true, netplay_public_announce, false); SETTING_BOOL("netplay_stateless_mode", &settings->netplay.stateless_mode, false, netplay_stateless_mode, false); SETTING_BOOL("netplay_client_swap_input", &settings->netplay.swap_input, true, netplay_client_swap_input, false); #endif diff --git a/configuration.h b/configuration.h index b851db61c0..a8f1e20e64 100644 --- a/configuration.h +++ b/configuration.h @@ -403,6 +403,7 @@ typedef struct settings #ifdef HAVE_NETWORKING struct { + bool public_announce; char server[255]; unsigned port; bool stateless_mode; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 9df3b15d90..277d837046 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -611,6 +611,8 @@ MSG_HASH(MENU_ENUM_LABEL_NETPLAY_PASSWORD, "netplay_password") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SETTINGS, "menu_netplay_settings") +MSG_HASH(MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, + "netplay_public_announce") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SPECTATE_PASSWORD, "netplay_spectate_password") MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SPECTATOR_MODE_ENABLE, diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 1f4f1c8339..dfd157ff38 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1535,6 +1535,13 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) { "Increasing this value will increase \n" "performance, but introduce more latency."); break; + case MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE: + snprintf(s, len, + "Whether to announce netplay games publicly. \n" + " \n" + "If set to false, clients must manually connect \n" + "rather than using the public lobby."); + break; case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: snprintf(s, len, "Whether to run netplay in a mode not requiring\n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 5e20c7a319..a501071b04 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -990,6 +990,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, "Username") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, "Server Password") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + "Publicly Announce Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, "Netplay settings") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, @@ -2619,6 +2621,10 @@ MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, "The password for connecting to the netplay host. Used only in host mode." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, + "Whether to announce netplay games publicly. If unset, clients must manually connect rather than using the public lobby." + ) MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, "The password for connecting to the netplay host with only spectator privileges. Used only in host mode." diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 9360d9ad40..e57e66043e 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -184,6 +184,7 @@ default_sublabel_macro(action_bind_sublabel_overlay_opacity, MENU_ default_sublabel_macro(action_bind_sublabel_overlay_scale, MENU_ENUM_SUBLABEL_OVERLAY_SCALE) default_sublabel_macro(action_bind_sublabel_overlay_enable, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE) default_sublabel_macro(action_bind_sublabel_overlay_preset, MENU_ENUM_SUBLABEL_OVERLAY_PRESET) +default_sublabel_macro(action_bind_sublabel_netplay_public_announce, MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE) default_sublabel_macro(action_bind_sublabel_netplay_ip_address, MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS) default_sublabel_macro(action_bind_sublabel_netplay_tcp_udp_port, MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT) default_sublabel_macro(action_bind_sublabel_netplay_password, MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD) @@ -736,6 +737,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_STDIN_CMD_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_stdin_cmd_enable); break; + case MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_public_announce); + break; case MENU_ENUM_LABEL_NETPLAY_NAT_TRAVERSAL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_nat_traversal); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 14142c15da..a1a2b319fb 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4793,6 +4793,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) unsigned user; unsigned count = 0; + if (menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, + PARSE_ONLY_BOOL, false) != -1) + count++; if (menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_NETPLAY_IP_ADDRESS, PARSE_ONLY_STRING, false) != -1) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 428c725bf7..07983f0e81 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5590,6 +5590,21 @@ static bool setting_append_list( #if defined(HAVE_NETWORK_CMD) unsigned user; #endif + CONFIG_BOOL( + list, list_info, + &settings->netplay.public_announce, + MENU_ENUM_LABEL_NETPLAY_PUBLIC_ANNOUNCE, + MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + true, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE); + CONFIG_STRING( list, list_info, settings->netplay.server, diff --git a/msg_hash.h b/msg_hash.h index c73d676756..510eac16c8 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1017,6 +1017,7 @@ enum msg_hash_enums MENU_LABEL(BLUETOOTH_ENABLE), MENU_LABEL(NETPLAY_CLIENT_SWAP_INPUT), MENU_LABEL(NETPLAY_DELAY_FRAMES), + MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE), MENU_LABEL(NETPLAY_STATELESS_MODE), MENU_LABEL(NETPLAY_CHECK_FRAMES), MENU_LABEL(NETPLAY_INPUT_LATENCY_FRAMES_MIN), diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 8e40d92403..eddf830df9 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -652,11 +652,22 @@ static void netplay_frontend_paused(netplay_t *netplay, bool paused) bool netplay_pre_frame(netplay_t *netplay) { bool sync_stalled; - reannounce ++; - if (netplay->is_server && (reannounce % 3600 == 0)) - netplay_announce(); + settings_t *settings = config_get_ptr(); + retro_assert(netplay); + if (settings->netplay.public_announce) + { + reannounce ++; + if (netplay->is_server && (reannounce % 3600 == 0)) + netplay_announce(); + } + else + { + /* Make sure that if announcement is turned on mid-game, it gets announced */ + reannounce = -1; + } + /* FIXME: This is an ugly way to learn we're not paused anymore */ if (netplay->local_paused) netplay_frontend_paused(netplay, false); @@ -1027,7 +1038,8 @@ bool init_netplay(void *direct_host, const char *server, unsigned port) msg_hash_to_str(MSG_WAITING_FOR_CLIENT), 0, 180, false); - netplay_announce(); + if (settings->netplay.public_announce) + netplay_announce(); } netplay_data = (netplay_t*)netplay_new( From c9015aa9ba5bd76028f72d1da9a086d52a61765d Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 5 Feb 2017 14:24:34 -0500 Subject: [PATCH 35/90] attempt autoconf fallback for android --- intl/msg_hash_chs.h | 4 ++++ intl/msg_hash_fr.h | 4 ++++ intl/msg_hash_it.h | 4 ++++ intl/msg_hash_ja.h | 4 ++++ intl/msg_hash_nl.h | 4 ++++ intl/msg_hash_ru.h | 4 ++++ intl/msg_hash_us.h | 4 ++++ msg_hash.h | 1 + tasks/task_autodetect.c | 13 ++++++++++++- 9 files changed, 41 insertions(+), 1 deletion(-) diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 605e24f2a0..2247b51f46 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -2295,6 +2295,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "未配置" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "数据库 Cursor List" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 0819baaaa7..6456e79004 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -2148,6 +2148,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "not configured" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "Database Cursor List" diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index bb768530fd..4d3be0310f 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -2170,6 +2170,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "not configured" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "Database Cursor List" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index f484af982c..01bb610aec 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -2291,6 +2291,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "設定されていない" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "データベースのカーソル表" diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index eaf3eaa27b..6ce92a9aa5 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -2182,6 +2182,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "not configured" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "Database Cursor List" diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index fe85a54dfe..c6beb03f93 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -2181,6 +2181,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "not configured" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "Database Cursor List" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a501071b04..0f6acfa3e9 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2288,6 +2288,10 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "not configured" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "not configured, using fallback" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, "Database Cursor List" diff --git a/msg_hash.h b/msg_hash.h index 510eac16c8..fba5261515 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -168,6 +168,7 @@ enum msg_hash_enums MSG_CAPABILITIES, MSG_DEVICE_CONFIGURED_IN_PORT, MSG_DEVICE_NOT_CONFIGURED, + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, MSG_DEVICE_DISCONNECTED_FROM_PORT, MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN, MSG_COMPILER, diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 50459adb9b..0021a742ac 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -306,14 +306,25 @@ static void input_autoconfigure_connect_handler(retro_task_t *task) char msg[255]; msg[0] = '\0'; - +#ifndef ANDROID RARCH_LOG("Autodetect: no profiles found for %s (%d/%d).\n", params->name, params->vid, params->pid); snprintf(msg, sizeof(msg), "%s (%ld/%ld) %s.", params->name, (long)params->vid, (long)params->pid, msg_hash_to_str(MSG_DEVICE_NOT_CONFIGURED)); +#else + strlcpy(params->name, "Android Gamepad", sizeof(params->name)); + if(!input_autoconfigure_joypad_from_conf_internal(params, task)) + { + RARCH_LOG("Autodetect: no profiles found for %s (%d/%d). Using fallback\n", + params->name, params->vid, params->pid); + snprintf(msg, sizeof(msg), "%s (%ld/%ld) %s.", + params->name, (long)params->vid, (long)params->pid, + msg_hash_to_str(MSG_DEVICE_NOT_CONFIGURED_FALLBACK)); + } +#endif task_set_title(task, strdup(msg)); } From ee6d76e932bca753c4f860cc21a8d1cde758287d Mon Sep 17 00:00:00 2001 From: radius Date: Mon, 6 Feb 2017 22:58:02 -0500 Subject: [PATCH 36/90] fix message --- tasks/task_autodetect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 0021a742ac..be79f38c95 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -315,7 +315,7 @@ static void input_autoconfigure_connect_handler(retro_task_t *task) msg_hash_to_str(MSG_DEVICE_NOT_CONFIGURED)); #else strlcpy(params->name, "Android Gamepad", sizeof(params->name)); - if(!input_autoconfigure_joypad_from_conf_internal(params, task)) + if(input_autoconfigure_joypad_from_conf_internal(params, task)) { RARCH_LOG("Autodetect: no profiles found for %s (%d/%d). Using fallback\n", params->name, params->vid, params->pid); From 46797c982b68cf007cc5f6e0d71c0ba4da9d90d0 Mon Sep 17 00:00:00 2001 From: Mico Chopitea Date: Tue, 7 Feb 2017 14:39:17 +0800 Subject: [PATCH 37/90] Updated menu sublabels and others --- intl/msg_hash_us.h | 99 +++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a501071b04..4a8e845abd 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -36,7 +36,7 @@ MSG_HASH( ) MSG_HASH( MSG_NETPLAY_USERS_HAS_FLIPPED, - "Netplay users has flipped" + "Netplay users have flipped" ) MSG_HASH( MSG_SETTING_DISK_IN_TRAY, @@ -112,7 +112,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Adjusts settings related to the appearance of the menu screen." + "Adjusts menu screen appearance settings." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, @@ -182,7 +182,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, "Achievement List" ) - MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, "Achievement List (Hardcore)" @@ -449,7 +448,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, - "Close Application" + "Close Content" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG, @@ -619,7 +618,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, "Game-options file") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, - "help") + "Help") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, "Audio/Video Troubleshooting") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, @@ -1719,41 +1718,41 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, "Enable or disable savestates, cheats, rewind, fast-forward, pause, and slow-motion for all games.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Change drivers for this system.") + "Change drivers used by the system.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, - "Change settings for the achievements.") + "Change achievement settings.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, - "Change settings for the core.") + "Change core settings.") MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_SETTINGS, - "Change settings for the recording.") + "Change recording settings.") MSG_HASH(MENU_ENUM_SUBLABEL_ONSCREEN_DISPLAY_SETTINGS, - "Change settings for display overlay, keyboard overlay and onscreen notifications.") + "Change display overlay and keyboard overlay, and onscreen notification settings.") MSG_HASH(MENU_ENUM_SUBLABEL_FRAME_THROTTLE_SETTINGS, - "Change settings for rewinding, fast-forwarding, and slow-motion.") + "Change rewind, fast-forward, and slow-motion settings.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVING_SETTINGS, - "Change settings for the saving.") + "Change saving settings.") MSG_HASH(MENU_ENUM_SUBLABEL_LOGGING_SETTINGS, - "Change settings for the logging.") + "Change logging settings.") MSG_HASH(MENU_ENUM_SUBLABEL_USER_INTERFACE_SETTINGS, - "Change settings for the user interface.") + "Change user interface settings.") MSG_HASH(MENU_ENUM_SUBLABEL_USER_SETTINGS, - "Change accounts, username, and language.") + "Change account, username, and language settings.") MSG_HASH(MENU_ENUM_SUBLABEL_PRIVACY_SETTINGS, "Change your privacy settings.") MSG_HASH(MENU_ENUM_SUBLABEL_DIRECTORY_SETTINGS, - "Change default directories for this system.") + "Change default directories where files are located.") MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_SETTINGS, - "Change settings for the playlists.") + "Change playlist settings.") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, "Configure server and network settings.") MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, - "Scan contents and add to the database.") + "Scan content and add to the database.") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Adjusts settings for audio output.") + "Change audio output settings.") MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, "Enable or disable bluetooth.") MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Saves changes to configuration file on exit.") + "Saves changes to the configuration file on exit.") MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, "Change default settings for configuration files.") MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, @@ -1767,7 +1766,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_HOTKEY_BINDS, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_MENU_ENUM_TOGGLE_GAMEPAD_COMBO, "Gamepad button combination to toggle menu.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_SETTINGS, - "Adjusts settings for joypads, keyboard and mouse.") + "Change joypad, keyboard, and mouse settings.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_USER_BINDS, "Configure controls for this user.") MSG_HASH(MENU_ENUM_SUBLABEL_LOG_VERBOSITY, @@ -1777,9 +1776,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, "Search for and connect to netplay hosts on the local network.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Display core, network and system information.") + "Display core, network, and system information.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, - "Download add-ons, components and contents for RetroArch.") + "Download add-ons, components, and content for RetroArch.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, "Enable or disable network sharing of your folders.") MSG_HASH(MENU_ENUM_SUBLABEL_SERVICES_SETTINGS, @@ -1795,9 +1794,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, "Sets the language of the interface.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, - "Inserts a black frame inbetween frames. Useful for users of 120 Hz screens who want to play 60 Hz material with eliminated ghosting.") + "Inserts a black frame inbetween frames. Useful for users with 120Hz screens who want to play 60Hz content to eliminate ghosting.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, - "Reduces latency at the cost of higher risk of video stuttering. Adds a delay after V-Sync (in ms).") + "Reduces latency at the cost of a higher risk of video stuttering. Adds a delay after V-Sync (in ms).") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, "Sets how many frames the CPU can run ahead of the GPU when using 'Hard GPU Sync'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, @@ -1807,11 +1806,11 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO, "The accurate estimated refresh rate of the screen in Hz.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SETTINGS, - "Adjusts settings for video output.") + "Change video output settings.") MSG_HASH(MENU_ENUM_SUBLABEL_WIFI_SETTINGS, "Scans for wireless networks and establishes connection.") MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, - "Learn more about how it works.") + "Learn more about how the program works.") MSG_HASH(MSG_APPENDED_DISK, "Appended disk") MSG_HASH(MSG_APPLICATION_DIR, @@ -1873,7 +1872,7 @@ MSG_HASH(MSG_COULD_NOT_READ_MOVIE_HEADER, MSG_HASH(MSG_COULD_NOT_READ_STATE_FROM_MOVIE, "Could not read state from movie.") MSG_HASH(MSG_CRC32_CHECKSUM_MISMATCH, - "CRC32 checksum mismatch between content file and saved content checksum in replay file header) replay highly likely to desync on playback.") + "CRC32 checksum mismatch between content file and saved content checksum in replay file header. Replay highly likely to desync on playback.") MSG_HASH(MSG_CUSTOM_TIMING_GIVEN, "Custom timing given") MSG_HASH(MSG_DECOMPRESSION_ALREADY_IN_PROGRESS, @@ -2202,7 +2201,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, "Mute/unmute audio.") MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Helps smooth out imperfections in timing when synchronizing audio and video at the same time. Be aware that if disabled, proper synchronization is nearly impossible to obtain." + "Helps smooth out imperfections in timing when synchronizing audio and video. Be aware that if disabled, proper synchronization is nearly impossible to obtain." ) MSG_HASH( MENU_ENUM_SUBLABEL_CAMERA_ALLOW, @@ -2242,7 +2241,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_TURBO_PERIOD, - "Describes the period of which turbo-enabled buttons toggle. Numbers are described in frames." + "Describes the period when turbo-enabled buttons are toggled. Numbers are described in frames." ) MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_DUTY_CYCLE, @@ -2274,7 +2273,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_MAX_TIMING_SKEW, - "The maximum change in audio input rate. You may want to increase this to enable very large changes in timing, for example running PAL cores on NTSC displays, at the cost of inaccurate audio pitch." + "The maximum change in audio input rate. Increasing this enables very large changes in timing at the cost of an inaccurate audio pitch (e.g., running PAL cores on NTSC displays)." ) MSG_HASH( MSG_FAILED, @@ -2348,7 +2347,7 @@ MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, MSG_HASH(MSG_NETPLAY_LAN_SCANNING, "Scanning for netplay hosts...") MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, - "Pause gameplay when window focus is lost.") + "Pause gameplay when RetroArch is not the active window.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, "Enable or disable composition (Windows only).") MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, @@ -2398,9 +2397,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, "Compatible content found") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, - "Cuts off a few pixels around the edges of the image that were customarily left blank by developers and sometimes contain garbage pixels.") + "Cuts off a few pixels around the edges of the image customarily left blank by developers which sometimes also contain garbage pixels.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, - "Add a slight blur to the image to take the edge off of the hard pixel edges. This option has very little impact on performance.") + "Adds a slight blur to the image to take the edge off of the hard pixel edges. This option has very little impact on performance.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FILTER, "Apply a CPU-powered video filter. NOTE: Might come at a high performance cost. Some video filters might only work for cores that use 32bit or 16bit color.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, @@ -2408,13 +2407,13 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, "Input the password of your Retro Achievements account.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, - "Input your user name here. This will be used for netplay sessions among other things.") + "Input your user name here. This will be used for netplay sessions, among other things.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, "Capture the image after filters (but not shaders) are applied. Your video will look as fancy as what you see on your screen.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_LIST, - "Select which application we wish to use.") + "Select which core to use.") MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, - "Select the content we want to start.") + "Select which content to start.") MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, "Show network interface(s) and associated IP addresses.") MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, @@ -2432,10 +2431,10 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, "Specify the font size in points.") MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, - "Hide the overlay while we are inside the menu, and show it again when exiting the menu.") + "Hide the overlay while inside the menu, and show it again when exiting the menu.") MSG_HASH( MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, - "Content which has been scanned will appear here." + "Scanned content will appear here." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, @@ -2467,7 +2466,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, - "When saving a savestate, save state index is automatically increased before it is saved. Also, when loading content, the index will be set to the highest existing index." + "When making a savestate, save state index is automatically increased before it is saved. When loading content, the index will be set to the highest existing index." ) MSG_HASH( MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, @@ -2475,11 +2474,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "The maximum rate at which content will be run when using fast forward (E.g. 5x for 60 fps content => 300 fps cap). If this is set at 0x, then fastforward ratio is unlimited (no FPS cap)." + "The maximum rate at which content will be run when using fast forward (E.g. 5x for 60 fps content => 300 fps cap). If set at 0x, fastforward ratio is unlimited (no FPS cap)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "When slowmotion, content will slow down by a factor." + "When in slowmotion, content will slow down by a factor." ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_ENABLE, @@ -2487,7 +2486,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, - "When rewinding defined number of frames, you can rewind several frames at a time, increasing the rewind speed." + "When rewinding a defined number of frames, you can rewind several frames at a time, increasing the rewind speed." ) MSG_HASH( MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, @@ -2527,7 +2526,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, - "If disabled, the content will keep running in the background when we are in the menu." + "If disabled, the content will keep running in the background when RetroArch's menu is toggled." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_DRIVER, @@ -2697,7 +2696,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, "URL to assets updater directory on the Libretro buildbot.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, - "After downloading, automatically extract archives that the downloads are contained inside." + "After downloading, automatically extract files contained in the downloaded archives." ) MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, "Scan for new rooms.") @@ -2758,7 +2757,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, - "Manage currently configured accounts." + "Manages currently configured accounts." ) MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_REWIND, "Manages rewind settings.") @@ -2791,14 +2790,14 @@ MSG_HASH( "Usually set by developers who bundle libretro/RetroArch apps to point to assets." ) MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, - "The place to store the wallpapers dynamically loaded by the menu depending on context.") + "Directory to store wallpapers dynamically loaded by the menu depending on context.") MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, "Supplementary thumbnails (boxarts/misc. images, etc.) are stored here." ) MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, "Sets start directory for menu configuration browser.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, - "The number of frames of input latency for netplay to use to hide network latency. This reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag.") + "The number of frames of input latency for netplay to use to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of noticeable input lag.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, "The range of frames of input latency that may be used to hide network latency. Reduces jitter and makes netplay less CPU-intensive, at the expense of unpredictable input lag.") MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, @@ -2838,7 +2837,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_HISTORY, MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_ADD, "Show the import content tab inside the main menu.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, - "Show startup screen in menu. Is automatically set to false after we have started up the program for the first time.") + "Show startup screen in menu. This is automatically set to false after the program starts for the first time.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, "Modify the opacity of the header graphic.") MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, @@ -2852,7 +2851,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, "Save all remapped controls to this directory.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, - "A directory for where to search for applications/cores.") + "Directory where the program searches for content/cores.") MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, "Application/core information files are stored here.") MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, From c3701783b19c207536da4932f92b6c96eec25016 Mon Sep 17 00:00:00 2001 From: rootfather Date: Tue, 7 Feb 2017 12:32:28 +0100 Subject: [PATCH 38/90] Rewrite German translation (part 2.1/fixes) Improve consistency and fix some errors. Intermediate release in preparation of part 3. --- intl/msg_hash_de.c | 109 +++++++++++++++++++++++---------------------- intl/msg_hash_de.h | 58 ++++++++++++------------ 2 files changed, 85 insertions(+), 82 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 87a2270323..fe682892d0 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -25,16 +25,14 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) { - uint32_t driver_hash = 0; - settings_t *settings = config_get_ptr(); + uint32_t driver_hash = 0; + settings_t *settings = config_get_ptr(); if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && - msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) - { - unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; + msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) { + unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; - switch (idx) - { + switch (idx) { case RARCH_FAST_FORWARD_KEY: snprintf(s, len, "Schaltet zwischen schnellem Vorlauf und \n" @@ -43,7 +41,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case RARCH_FAST_FORWARD_HOLD_KEY: snprintf(s, len, - "Halte den Taste gedrückt, um vorzuspulen.\n" + "Halte die Taste gedrückt, um vorzuspulen.\n" " \n" "Beim Loslassen wird der schnelle Vorlauf beendet." ); @@ -54,15 +52,15 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case RARCH_FRAMEADVANCE: snprintf(s, len, - "Einzelbildwiedergabe, wenn der Inhalt pausiert ist."); + "Einzelbildvorlauf, wenn der Inhalt pausiert ist."); break; case RARCH_SHADER_NEXT: snprintf(s, len, - "Wendet nächsten Shader im Verzeichnis an."); + "Wendet den nächsten Shader im Verzeichnis an."); break; case RARCH_SHADER_PREV: snprintf(s, len, - "Wendet vorherigen Shader im Verzeichnis an."); + "Wendet den vorherigen Shader im Verzeichnis an."); break; case RARCH_CHEAT_INDEX_PLUS: case RARCH_CHEAT_INDEX_MINUS: @@ -90,9 +88,13 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Netplay-Spieler tauschen."); break; + case RARCH_NETPLAY_GAME_WATCH: + snprintf(s, len, + "Im Netplay zwischen Spiel- und Beobachter-Modus wechseln."); + break; case RARCH_SLOWMOTION: snprintf(s, len, - "Halte den Taste gedrückt, um die Zeitlupe einzuschalten."); + "Halte die Taste gedrückt, um die Zeitlupe einzuschalten."); break; case RARCH_ENABLE_HOTKEY: snprintf(s, len, @@ -128,7 +130,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Datenträger einbinden/auswerfen. \n" " \n" - "Verwendet für Inhalt, der auf mehreren Datenträgern ausgeliefert wird. "); + "Wird für Inhalt verwendet, der auf mehreren Datenträgern ausgeliefert wird. "); break; case RARCH_DISK_NEXT: case RARCH_DISK_PREV: @@ -180,11 +182,11 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Speicherplätze. \n" " \n" - "Wenn der Speicherplatz auf 0 gesetzt wird, ist der Name des Spielstands \n" + "Wenn der Speicherplatz 0 ausgewählt wird, ist der Name des Spielstands \n" "*.state (oder was entsprechend auf der Kommandozeile definiert wurde). \n" " \n" - "Wenn der Speicherplatz nicht auf 0 gesetzt wird, wird das Verzeichnis \n" - "gewählt, wobei die Nummer des Speicherplatzes ist."); + "Wenn ein anderer Speicherplatz als 0 gewählt wird, wird das Verzeichnis \n" + "verwendet, wobei die Nummer des Speicherplatzes ist."); break; case RARCH_SAVE_STATE_KEY: snprintf(s, len, @@ -192,7 +194,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case RARCH_REWIND: snprintf(s, len, - "Haltee die Taste zum Zurückspulen gedrückt. \n" + "Halte die Taste zum Zurückspulen gedrückt. \n" " \n" "Die Zurückspulfunktion muss eingeschaltet sein."); break; @@ -212,7 +214,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) switch (msg) { case MENU_ENUM_LABEL_ACCOUNTS_RETRO_ACHIEVEMENTS: - snprintf(s, len, "Anmelde-Daten für Ihr \n" + snprintf(s, len, "Anmelde-Daten für dein \n" "Retro Achievements-Konto. \n" " \n" "Besuche retroachievements.org und eröffne \n" @@ -255,7 +257,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Eingabebelegungsdateien automatisch laden."); break; case MENU_ENUM_LABEL_SORT_SAVESTATES_ENABLE: - snprintf(s, len, "Speichert Savestate-Dateien in Ordnern, \n" + snprintf(s, len, "Speichert Spielstand-Dateien in Ordnern, \n" "die nach dem verwendeten libretro-Core benannt sind."); break; case MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE: @@ -274,12 +276,12 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Speicher."); break; case MENU_ENUM_LABEL_UNDO_LOAD_STATE: - snprintf(s, len, "Wenn ein Savestate geladen war, wird der Inhalt \n" - "zum Status vor dem Laden des Savestates zurückkehren."); + snprintf(s, len, "Wenn ein Spielstand geladen war, wird der Inhalt \n" + "zum Status vor dem Laden des Spielstands zurückkehren."); break; case MENU_ENUM_LABEL_UNDO_SAVE_STATE: - snprintf(s, len, "Wenn ein Savestate überschrieben wurde, wird \n" - "der Inhalt zum vorherigen Savestates zurückkehren."); + snprintf(s, len, "Wenn ein Spielstand überschrieben wurde, wird \n" + "der Inhalt zum vorherigen Spielstand zurückkehren."); break; case MENU_ENUM_LABEL_TAKE_SCREENSHOT: snprintf(s, len, "Fertigt ein Bildschirmfoto an. \n" @@ -295,7 +297,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "über den Inhalt an."); break; case MENU_ENUM_LABEL_FILE_BROWSER_CONFIG: - snprintf(s, len, "Konfigurations-Datei."); + snprintf(s, len, "Konfigurationsdatei."); break; case MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE: snprintf(s, len, "Komprimierte Archivdatei."); @@ -304,7 +306,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Aufzeichnungs-Konfigurationsdatei."); break; case MENU_ENUM_LABEL_FILE_BROWSER_CURSOR: - snprintf(s, len, "Datenbank-Zeiger-Datei."); + snprintf(s, len, "Vorherige Datenbank-Suchanfragen."); /*Maybe a FIXME*/ break; case MENU_ENUM_LABEL_FILE_CONFIG: snprintf(s, len, "Konfigurationsdatei."); @@ -316,24 +318,25 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_USE_THIS_DIRECTORY: snprintf(s, len, - "Auswählen, um dies als Verzeichnis festzulegen."); + "Dieses Verzeichnis auswählen."); break; case MENU_ENUM_LABEL_CONTENT_DATABASE_DIRECTORY: snprintf(s, len, - "Verzeichnis für Inhalte-Datenbank. \n" + "Verzeichnis für Inhaltsdatenbanken. \n" " \n" - "Pfad zum Verzeichnis für die \n" - "Inhalte-Datenbank."); + "Verzeichnis, in welchem die Inhaltsdatenbanken \n" + "gespeichert werden."); break; case MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY: snprintf(s, len, - "Vorschaubild-Verzeichnis. \n" + "Verzeichnis für Vorschaubilder. \n" " \n" - "Zum Speichern von Vorschaubildern."); + "Verzeichnis, in welchem die Vorschaubilder \n" + "gespeichert werden."); break; case MENU_ENUM_LABEL_LIBRETRO_INFO_PATH: snprintf(s, len, - "Core-Info-Verzeichnis. \n" + "Verzeichnis für Core-Informationsdateien. \n" " \n" "Ein Verzeichnis, in dem nach \n" "libretro-Core-Informationen gesucht wird."); @@ -352,7 +355,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) " \n" "Wenn diese Option deaktiviert bleibt, \n" "wird RetroArch beendet, wenn die Abschalt-Funktion \n" - "ausgewählt wird. \n" + "ausgelöst wird. \n" " \n" "Wenn diese Option aktiviert ist, wird stattdessen \n" "ein 'leerer' Core geladen, sodass wir im Menü bleiben \n" @@ -430,13 +433,13 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_FILE_BROWSER_CORE_SELECT_FROM_COLLECTION: snprintf(s, len, - "Libretro-Core. \n" + "libretro-Core. \n" " \n" "Auswählen, um diesen Core dem Spiel zuzuordnen."); break; case MENU_ENUM_LABEL_FILE_BROWSER_CORE: snprintf(s, len, - "Libretro-Core. \n" + "libretro-Core. \n" " \n" "Auswählen, um diesen Core in RetroArch zu laden."); break; @@ -474,7 +477,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "das aktuelle Frame verarbeitet wird. \n" "Normal - Eingabe wird abgefragt, wenn \n" "eine Abfrage angefordert wird. \n" - "Late - Eingabe wird abgefragt, wenn \n" + "Spät - Eingabe wird abgefragt, wenn \n" "die erste Eingabe-Abfrage im Frame angefordert wird.\n" " \n" "Diese Option auf 'Früh' oder 'Spät' zu setzen kann \n" @@ -543,9 +546,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_SAVESTATE_AUTO_INDEX: snprintf(s, len, "Erhöht den Speicherplatz-Index bei jedem Speichervorgang, \n" - "sodass mehrere Savestate-Dateien erzeugt werden. \n" + "sodass mehrere Spielstand-Dateien erzeugt werden. \n" "Wenn der Inhalt geladen ist, wird der Speicherplatz-Index \n" - "auf den höchsten existierenden Wert gesetzt (neuester Savestate)."); + "auf den höchsten existierenden Wert gesetzt (neuester Spielstand)."); break; case MENU_ENUM_LABEL_FPS_SHOW: snprintf(s, len, @@ -661,7 +664,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC: snprintf(s, len, - "Um nach Inhalten zu suchen, gehee zu '%s' und\n" + "Um nach Inhalten zu suchen, gehe zu '%s' und\n" "wähle '%s' oder %s'.\n" " \n" "Die Dateien werden werden mit einer Datenbank abgeglichen.\n" @@ -747,7 +750,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Suche nach Inhalten. \n" " \n" "Um Inhalte zu laden benötigst Du den passenden \n" - "Libretro-Core und die Inhalts-Datei. \n" + "libretro-Core und die Inhalts-Datei. \n" " \n" "Um einzustellen, welcher Ordner standardmäßig \n" "geöffnet wird, um nach Inhalten zu suchen, solltest \n" @@ -783,11 +786,11 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "OpenGL-Grafiktreiber. \n" " \n" "Dieser Treiber erlaubt es, neben software- \n" - "gerenderten Cores auch Libretro-GL-Cores zu \n" + "gerenderten Cores auch libretro-GL-Cores zu \n" "verwenden. \n" " \n" "Die Leistung, sowohl bei software-gerenderten, \n" - "als auch bei Libretro-GL-Cores, hängt von dem \n" + "als auch bei libretro-GL-Cores, hängt von dem \n" "GL-Treiber deiner Grafikkarte ab."); } else if (string_is_equal(settings->video.driver, "sdl2")) @@ -936,7 +939,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_PARAMETERS: snprintf(s, len, - "Shader-Voreinstellung-Parameter. \n" + "Parameter der Shader-Voreinstellung. \n" " \n" "Verändert die Shader-Voreinstellung, die aktuell \n" "im Menü aktiv ist." @@ -1310,11 +1313,11 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_SAVESTATE_AUTO_SAVE: case MENU_ENUM_LABEL_SAVESTATE_AUTO_LOAD: snprintf(s, len, - "Erstellt einen Savestate automatisch, \n" + "Erstellt einen Spielstand automatisch, \n" "wenn RetroArch beendet wird .\n" " \n" - "RetroArch wird Savestates in diesem Pfad automatisch \n" - "nach dem Starten laden, wenn 'Savestate automatisch laden' \n" + "RetroArch wird Spielstände in diesem Pfad automatisch \n" + "nach dem Starten laden, wenn 'Spielstand automatisch laden' \n" "aktiviert ist."); break; case MENU_ENUM_LABEL_VIDEO_THREADED: @@ -1400,7 +1403,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: snprintf(s, len, "Verhindert, dass SRAM überschrieben wird, \n" - "wenn Savestates geladen werden.\n" + "wenn Spielstände geladen werden.\n" " \n" "Kann zu fehlerhaften Spielen führen."); break; @@ -1441,9 +1444,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_SAVESTATE_DIRECTORY: snprintf(s, len, - "Verzeichnis für Savestates. \n" + "Verzeichnis für Spielstände. \n" " \n" - "Speichert alle Savestates (*.state) in diesem \n" + "Speichert alle Spielstände (*.state) in diesem \n" "Verzeichnis.\n" " \n" "Explizite Optionen über die Kommandozeile überschreiben \n" @@ -1544,7 +1547,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) " \n" "Wird dieser Wert erhöht, verbessert sich \n" "die Leistung, die Latenz erhöht sich jedoch."); - case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: + case MENU_ENUM_LABEL_NETPLAY_STATELESS_MODE: /* Maybe FIXME*/ snprintf(s, len, "Legt fest, ob Netplay in einem Modus laufen soll, der keine\n" "Savestates benötigt. \n" @@ -1660,12 +1663,12 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL: snprintf(s, len, "URL zum Core-Verzeichnis auf dem \n" - "Libretro-Server."); + "libretro-Server."); break; case MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL: snprintf(s, len, "URL zum Assets-Verzeichnis auf dem \n" - "Libretro-Server."); + "libretro-Server."); break; case MENU_ENUM_LABEL_INPUT_REMAP_BINDS_ENABLE: snprintf(s, len, @@ -1895,7 +1898,7 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Damit RetroArch etwas tut, musst \n" "Du ein Programm hineinladen. \n" "\n" - "Wir nennen diese Programme 'Libretro-Core', \n" + "Wir nennen diese Programme 'libretro-Core', \n" "oder einfach nur 'Core'. \n" " \n" "Um einen Core zu laden, verwende \n" diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 5eb4fa1331..758f74476e 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -146,7 +146,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ASSETS_DIRECTORY, - "Assets-Verzeichnis" + "Assets" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_BLOCK_FRAMES, @@ -170,7 +170,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_FILTER_DIR, - "Audiofilter-Verzeichnis" + "Audiofilter" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_TURBO_DEADZONE_LIST, @@ -202,7 +202,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_SETTINGS, - "Audio-Einstellungen" + "Audio" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_SYNC, @@ -394,7 +394,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, - "Konfigurations-Einstellungen" + "Konfigurationen" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, @@ -410,7 +410,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, - "Inhalts-Datenbank" + "Inhaltsdatenbank" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DIR, @@ -460,7 +460,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, "Optionen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SETTINGS, - "Core-Einstellungen") + "Cores") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, "Cores automatisch starten") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, @@ -496,7 +496,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NONE, MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_NOT_FOUND, "Verzeichnis nicht gefunden.") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_SETTINGS, - "Verzeichnis") + "Verzeichnisse") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_CYCLE_TRAY_STATUS, "Datentägerstatus") MSG_HASH(MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND, @@ -630,7 +630,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DEVICE_TYPE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DRIVER, "Eingabetreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_DUTY_CYCLE, - "Haltedauer") + "Turbo-Haltedauer") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_HOTKEY_BINDS, "Hotkeys belegen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_ICADE_ENABLE, @@ -756,13 +756,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_PREFER_FRONT_TOUCH, "Touch-Eingabe auf der Vorderseite bevorzugen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAPPING_DIRECTORY, - "Eingabe-Belegungen") + "Tastenbelegungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_REMAP_BINDS_ENABLE, "Tasten-Umbelegung aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SAVE_AUTOCONFIG, "Speichere Autokonfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SETTINGS, - "Eingabe-Einstellungen") + "Eingabe") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_SMALL_KEYBOARD_ENABLE, "Kleine Tastatur aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, @@ -770,13 +770,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TOUCH_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_ENABLE, "Turbo aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_TURBO_PERIOD, - "Turbo-Dauer") + "Turbo-Häufigkeit") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_USER_BINDS, "Belegungen für Benutzer %u") MSG_HASH(MENU_ENUM_LABEL_VALUE_INTERNAL_STORAGE_STATUS, "Status des internen Speichers") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_AUTOCONFIG_DIR, - "Eingabe-Autokonfiguration") + "Automatische Eingabekonfigurationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_JOYPAD_DRIVER, "Joypad-Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_LAKKA_SERVICES, @@ -834,13 +834,13 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, "Standort-Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOGGING_SETTINGS, - "Logging-Einstellungen") + "Logging") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOG_VERBOSITY, "Logs auf Kommandozeile ausgeben") MSG_HASH(MENU_ENUM_LABEL_VALUE_MAIN_MENU, "Hauptmenü") MSG_HASH(MENU_ENUM_LABEL_VALUE_MANAGEMENT, - "Datenbank-Einstellungen") + "Datenbanken") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME, "Menü-Farbschema") MSG_HASH(MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_COLOR_THEME_BLUE, @@ -916,7 +916,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, "Benutzername") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Netplay-Einstellungen") + "Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, "Netplay-Zuschauermodus aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, @@ -982,7 +982,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE, MSG_HASH(MENU_ENUM_LABEL_VALUE_ONLINE_UPDATER, "Online-Aktualisierungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_DISPLAY_SETTINGS, - "OSD-Einstellungen") + "Bildschirm-Meldungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_OVERLAY_SETTINGS, "Bildschirm-Overlay") MSG_HASH(MENU_ENUM_LABEL_VALUE_ONSCREEN_NOTIFICATIONS_SETTINGS, @@ -996,7 +996,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY, MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_AUTOLOAD_PREFERRED, "Bevorzugtes Overlay automatisch laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_DIRECTORY, - "Overlay-Verzeichnis") + "Overlays") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_OPACITY, "Overlay-Transparenz") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, @@ -1004,7 +1004,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_PRESET, MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SCALE, "Overlay-Skalierung") MSG_HASH(MENU_ENUM_LABEL_VALUE_OVERLAY_SETTINGS, - "Overlay-Einstellungen") + "Overlays") MSG_HASH(MENU_ENUM_LABEL_VALUE_PAL60_ENABLE, "Verwende PAL60-Modus") MSG_HASH(MENU_ENUM_LABEL_VALUE_PARENT_DIRECTORY, @@ -1028,7 +1028,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_PORT, MSG_HASH(MENU_ENUM_LABEL_VALUE_PRESENT, "Vorhanden") MSG_HASH(MENU_ENUM_LABEL_VALUE_PRIVACY_SETTINGS, - "Privatsphären-Einstellungen") + "Privatsphäre") MSG_HASH(MENU_ENUM_LABEL_VALUE_QUIT_RETROARCH, "RetroArch beenden") MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_ANALOG, @@ -1090,9 +1090,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_TGDB_RATING, MSG_HASH(MENU_ENUM_LABEL_VALUE_REBOOT, "Neustart") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_CONFIG_DIRECTORY, - "Aufnahme-Konfiguration") + "Aufnahme-Konfigurationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_OUTPUT_DIRECTORY, - "Aufnahme-Verzeichnis") + "Aufnahmen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, "Aufnahme") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, @@ -1138,9 +1138,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_GRANULARITY, MSG_HASH(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS, "Zurückspulen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_BROWSER_DIRECTORY, - "File Browser") + "Dateibrowser") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_CONFIG_DIRECTORY, - "Dateibrowser-Verzeichnis") + "Konfigurationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_RGUI_SHOW_START_SCREEN, "Zeige Startbildschirm") MSG_HASH(MENU_ENUM_LABEL_VALUE_RIGHT_ANALOG, @@ -1150,7 +1150,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RUN, MSG_HASH(MENU_ENUM_LABEL_VALUE_SAMBA_ENABLE, "SAMBA aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVEFILE_DIRECTORY, - "Speicherdaten-Verzeichnis") + "Speicherdaten") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX, "Automatische Indexierung von Spielständen") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, @@ -1158,7 +1158,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_LOAD, MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, "Spielstand automatisch speichern") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, - "Spielstand-Verzeichnis") + "Spielstände") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, "Spielstand-Vorschaubilder") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, @@ -1380,7 +1380,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_THREADED_DATA_RUNLOOP_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS, "Miniaturansichten") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_DIRECTORY, - "Miniaturansichten-Verzeichnis") + "Miniaturansichten") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAILS_UPDATER_LIST, "Miniaturansichten aktualisieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_THUMBNAIL_MODE_BOXARTS, @@ -1510,7 +1510,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SCALE_INTEGER, "Ganzzahlige Bildskalierung") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SETTINGS, - "Video-Einstellungen") + "Video") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_DIR, "Video-Shader") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_NUM_PASSES, @@ -1718,7 +1718,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_HELP_LIST, MSG_HASH(MSG_APPENDED_DISK, "Datenträger hinzufügen") MSG_HASH(MSG_APPLICATION_DIR, - "Anwendungs-Verzeichnis") + "Anwendungen") MSG_HASH(MSG_APPLYING_CHEAT, "Änderungen übernehmen.") MSG_HASH(MSG_APPLYING_SHADER, @@ -1928,7 +1928,7 @@ MSG_HASH(MSG_INPUT_CHEAT_FILENAME, MSG_HASH(MSG_INPUT_PRESET_FILENAME, "Vorlagen-Dateiname") MSG_HASH(MSG_INTERFACE, - "Benutzeroberläche") + "Netzwerk-Karte") MSG_HASH(MSG_INTERNAL_STORAGE, "Interner Speicher") MSG_HASH(MSG_REMOVABLE_STORAGE, From 452c3529a83bbc8651c478cd385f667b7a0abbc4 Mon Sep 17 00:00:00 2001 From: Mico Chopitea Date: Tue, 7 Feb 2017 23:11:08 +0800 Subject: [PATCH 39/90] Updated a few more menu sublabels --- intl/msg_hash_us.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 2587f5f4e4..1f5425de9a 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1790,7 +1790,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SSH_ENABLE, MSG_HASH(MENU_ENUM_SUBLABEL_SUSPEND_SCREENSAVER_ENABLE, "Prevents your system's screensaver from becoming active.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_SCALE, - "Sets the window size relative to the core viewport size. Alternatively you can set a window width and height below for a fixed window size.") + "Sets the window size relative to the core viewport size. Alternatively, you can set a window width and height below for a fixed window size.") MSG_HASH(MENU_ENUM_SUBLABEL_USER_LANGUAGE, "Sets the language of the interface.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, @@ -2225,7 +2225,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_VOLUME, - "Audio volume (in dB). 0 dB is normal volume, no gain applied." + "Audio volume (in dB). 0 dB is normal volume, and no gain is applied." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_SYNC, @@ -2478,11 +2478,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "The maximum rate at which content will be run when using fast forward (E.g. 5x for 60 fps content => 300 fps cap). If set at 0x, fastforward ratio is unlimited (no FPS cap)." + "The maximum rate at which content will be run when using fast forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fastforward ratio is unlimited (no FPS cap)." ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "When in slowmotion, content will slow down by a factor." + "When in slowmotion, content will slow down by the factor specified/set." ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_ENABLE, @@ -2502,7 +2502,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, - "Automatically saves a savestate at the end of RetroArch's lifetime. RetroArch will automatically load this savestate if 'Savestate Auto Load' is set." + "Automatically makes a savestate at the end of RetroArch's runtime. RetroArch will automatically load this savestate if 'Auto Load State' is enabled." ) MSG_HASH( MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, @@ -2594,7 +2594,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, - "Audio output samplerate." + "Audio output sample rate." ) MSG_HASH( MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, @@ -2733,12 +2733,12 @@ MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, #ifdef HAVE_DYNAMIC MSG_HASH( MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Closes the current game and application. Any unsaved changes might be lost." + "Closes the current content. Any unsaved changes might be lost." ) #else MSG_HASH( MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Closes the current game. Any unsaved changes might be lost." + "Closes the current content. Any unsaved changes might be lost." ) #endif MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, @@ -2746,9 +2746,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, "Save a state to the currently selected slot.") MSG_HASH(MENU_ENUM_SUBLABEL_RESUME, - "Resume the currently running application and leave the Quick Menu.") + "Resume the currently running content and leave the Quick Menu.") MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, - "Resume the currently running application and leave the Quick Menu.") + "Resume the currently running content and leave the Quick Menu.") MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, "Changes the currently selected state slot.") MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, @@ -2778,7 +2778,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_OPTIONS, MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, "Change the controls for the currently running content.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, - "Change the options for the currently running application.") + "Change the options for the currently running content.") MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, "Show advanced settings for power users (hidden by default).") MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, @@ -2919,9 +2919,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, "Save the current shader settings as the default settings for the content.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, - "Modifies current shader directly. Will not be saved to preset file.") + "Modifies the current shader directly. Changes will not be saved to the preset file.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, - "Modifies shader preset currently in menu.") + "Modifies the shader preset itself currently used in the menu.") MSG_HASH( MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, "Increase or decrease the amount of cheats." @@ -2945,6 +2945,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, "Custom viewport width that is used if the Aspect Ratio is set to 'Custom'.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, - "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Scaled Integer' is enabled, it will be automatically centered then.") + "Custom viewport offset used for defining the X-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, - "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Scaled Integer' is enabled, it will be automatically centered then.") + "Custom viewport offset used for defining the Y-axis position of the viewport. These are ignored if 'Integer Scale' is enabled. It will be automatically centered then.") From 1ef482d6dfa88d06c585d6f1bd7a521fabf37747 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Tue, 7 Feb 2017 21:48:18 -0500 Subject: [PATCH 40/90] Apply icon scaling to the battery and clock icons --- menu/drivers/xmb.c | 52 +++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 25bdee0e3f..9ca3ea7ace 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -549,7 +549,8 @@ static void xmb_draw_icon( float rotation, float scale_factor, float *color, - float shadow_offset) + float shadow_offset, + float icon_scale) { menu_display_ctx_draw_t draw; struct video_coords coords; @@ -575,6 +576,9 @@ static void xmb_draw_icon( draw.width *= scale_factor; draw.height *= scale_factor; #endif + // Allow the icon to be scaled outside of the scale factor. + draw.width *= icon_scale; + draw.height *= icon_scale; draw.coords = &coords; draw.matrix_data = mymat; draw.texture = texture; @@ -2329,7 +2333,8 @@ static void xmb_draw_items( rotation, scale_factor, &color[0], - xmb->shadow_offset); + xmb->shadow_offset, + 1.0); } menu_display_set_alpha(color, MIN(node->alpha, xmb->alpha)); @@ -2349,7 +2354,8 @@ static void xmb_draw_items( 0, 1, &color[0], - xmb->shadow_offset); + xmb->shadow_offset, + 1.0); } menu_display_blend_end(); @@ -2674,9 +2680,6 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) if (percent > 0) { - size_t x_pos = xmb->icon.size / 6; - size_t x_pos_icon = xmb->margins.title.left; - if (coord_white[3] != 0) xmb_draw_icon( menu_disp_info, @@ -2684,22 +2687,23 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) &mymat, xmb->textures.list[charging ? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL], - width - (xmb->icon.size / 2) - x_pos_icon, - xmb->icon.size, + width - xmb->margins.title.left - (xmb->icon.size / 2), + xmb->icon.size - (xmb->icon.size / 3), width, height, 1, 0, 1, &coord_white[0], - xmb->shadow_offset); + xmb->shadow_offset, + 0.5); snprintf(msg, sizeof(msg), "%d%%", percent); percent_width = font_driver_get_message_width(xmb->font, msg, utf8len(msg), 1); xmb_draw_text(menu_disp_info, xmb, msg, - width - xmb->margins.title.left - x_pos, + width - xmb->margins.title.left - (xmb->icon.size / 2), xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT, width, height, xmb->font); } @@ -2711,26 +2715,27 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) char timedate[255]; int x_pos = 0; + // Move the timedate widget over if the battery percent is active. + if (percent_width) + x_pos = percent_width + xmb->icon.size; + if (coord_white[3] != 0) { - int x_pos = 0; - - if (percent_width) - x_pos = percent_width + (xmb->icon.size / 2.5); - xmb_draw_icon( menu_disp_info, xmb->icon.size, &mymat, xmb->textures.list[XMB_TEXTURE_CLOCK], - width - xmb->icon.size - x_pos, - xmb->icon.size,width, + width - xmb->margins.title.left - (xmb->icon.size / 2.5) - x_pos, + xmb->icon.size - (xmb->icon.size / 3), + width, height, 1, 0, 1, &coord_white[0], - xmb->shadow_offset); + xmb->shadow_offset, + 0.5); } timedate[0] = '\0'; @@ -2741,11 +2746,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) menu_display_timedate(&datetime); - if (percent_width) - x_pos = percent_width + (xmb->icon.size / 2.5); - xmb_draw_text(menu_disp_info, xmb, timedate, - width - xmb->margins.title.left - xmb->icon.size / 4 - x_pos, + width - xmb->margins.title.left - (xmb->icon.size / 2) - x_pos, xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT, width, height, xmb->font); } @@ -2770,7 +2772,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) 0, 1, &coord_white[0], - xmb->shadow_offset); + xmb->shadow_offset, + 1.0); menu_display_blend_begin(); @@ -2819,7 +2822,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) rotation, scale_factor, &item_color[0], - xmb->shadow_offset); + xmb->shadow_offset, + 1.0); } } From 0617262cd212b813e925c3a4133baa8e40f56b99 Mon Sep 17 00:00:00 2001 From: Mico Chopitea Date: Wed, 8 Feb 2017 11:06:14 +0800 Subject: [PATCH 41/90] removed ifdef --- intl/msg_hash_us.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 1f5425de9a..d370efde10 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2482,7 +2482,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, - "When in slowmotion, content will slow down by the factor specified/set." + "When in slow motion, content will slow down by the factor specified/set." ) MSG_HASH( MENU_ENUM_SUBLABEL_REWIND_ENABLE, @@ -2730,17 +2730,10 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, "View previous searches.") MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, "Captures an image of the screen.") -#ifdef HAVE_DYNAMIC MSG_HASH( MENU_ENUM_SUBLABEL_CLOSE_CONTENT, "Closes the current content. Any unsaved changes might be lost." ) -#else -MSG_HASH( - MENU_ENUM_SUBLABEL_CLOSE_CONTENT, - "Closes the current content. Any unsaved changes might be lost." - ) -#endif MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, "Load a saved state from the currently selected slot.") MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, From 373535f329ccb36abe704c06bb3bf020c5ecc242 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 8 Feb 2017 00:16:27 -0500 Subject: [PATCH 42/90] DOS: improve color accuracy and scaling, thanks to aliaspider --- gfx/drivers/vga_gfx.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index 78a14d6dd4..5f8a89c31c 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -222,14 +222,14 @@ static bool vga_gfx_frame(void *data, const void *frame, for (x = 0; x < VGA_WIDTH; x++) { /* scale incoming frame to fit the screen */ - unsigned scaled_x = (width / (float)VGA_WIDTH) * x; - unsigned scaled_y = (height / (float)VGA_HEIGHT) * y; + unsigned scaled_x = (width * x) / VGA_WIDTH; + unsigned scaled_y = (height * y) / VGA_HEIGHT; unsigned short pixel = ((unsigned short*)frame_to_copy)[width * scaled_y + scaled_x]; /* convert RGB565 to BGR332 */ - unsigned r = (7.0f / 31.0f) * ((pixel & 0xF800) >> 11); - unsigned g = (7.0f / 63.0f) * ((pixel & 0x07E0) >> 5); - unsigned b = (3.0f / 31.0f) * ((pixel & 0x001F) >> 0); + unsigned r = ((pixel & 0xF800) >> 13); + unsigned g = ((pixel & 0x07E0) >> 8); + unsigned b = ((pixel & 0x001F) >> 3); vga_frame[VGA_WIDTH * y + x] = (b << 6) | (g << 3) | r; } @@ -369,12 +369,12 @@ static void vga_set_texture_frame(void *data, for(x = 0; x < VGA_WIDTH; x++) { /* scale incoming frame to fit the screen */ - unsigned scaled_x = (width / (float)VGA_WIDTH) * x; - unsigned scaled_y = (height / (float)VGA_HEIGHT) * y; + unsigned scaled_x = (width * x) / VGA_WIDTH; + unsigned scaled_y = (height * y) / VGA_HEIGHT; unsigned short pixel = video_frame[width * scaled_y + scaled_x]; - unsigned r = (7.0f / 15.0f) * ((pixel & 0xF000) >> 12); - unsigned g = (7.0f / 15.0f) * ((pixel & 0xF00) >> 8); - unsigned b = (3.0f / 15.0f) * ((pixel & 0xF0) >> 4); + unsigned r = ((pixel & 0xF000) >> 13); + unsigned g = ((pixel & 0xF00) >> 9); + unsigned b = ((pixel & 0xF0) >> 6); vga_menu_frame[VGA_WIDTH * y + x] = (b << 6) | (g << 3) | r; } } From 962cf6b07655f8ad1da507633cd4d451eca300a9 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 8 Feb 2017 20:02:26 +0100 Subject: [PATCH 43/90] Revert "Allow normal Battery/Clock icon sizes [WIP]" --- menu/drivers/xmb.c | 52 +++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 9ca3ea7ace..25bdee0e3f 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -549,8 +549,7 @@ static void xmb_draw_icon( float rotation, float scale_factor, float *color, - float shadow_offset, - float icon_scale) + float shadow_offset) { menu_display_ctx_draw_t draw; struct video_coords coords; @@ -576,9 +575,6 @@ static void xmb_draw_icon( draw.width *= scale_factor; draw.height *= scale_factor; #endif - // Allow the icon to be scaled outside of the scale factor. - draw.width *= icon_scale; - draw.height *= icon_scale; draw.coords = &coords; draw.matrix_data = mymat; draw.texture = texture; @@ -2333,8 +2329,7 @@ static void xmb_draw_items( rotation, scale_factor, &color[0], - xmb->shadow_offset, - 1.0); + xmb->shadow_offset); } menu_display_set_alpha(color, MIN(node->alpha, xmb->alpha)); @@ -2354,8 +2349,7 @@ static void xmb_draw_items( 0, 1, &color[0], - xmb->shadow_offset, - 1.0); + xmb->shadow_offset); } menu_display_blend_end(); @@ -2680,6 +2674,9 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) if (percent > 0) { + size_t x_pos = xmb->icon.size / 6; + size_t x_pos_icon = xmb->margins.title.left; + if (coord_white[3] != 0) xmb_draw_icon( menu_disp_info, @@ -2687,23 +2684,22 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) &mymat, xmb->textures.list[charging ? XMB_TEXTURE_BATTERY_CHARGING : XMB_TEXTURE_BATTERY_FULL], - width - xmb->margins.title.left - (xmb->icon.size / 2), - xmb->icon.size - (xmb->icon.size / 3), + width - (xmb->icon.size / 2) - x_pos_icon, + xmb->icon.size, width, height, 1, 0, 1, &coord_white[0], - xmb->shadow_offset, - 0.5); + xmb->shadow_offset); snprintf(msg, sizeof(msg), "%d%%", percent); percent_width = font_driver_get_message_width(xmb->font, msg, utf8len(msg), 1); xmb_draw_text(menu_disp_info, xmb, msg, - width - xmb->margins.title.left - (xmb->icon.size / 2), + width - xmb->margins.title.left - x_pos, xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT, width, height, xmb->font); } @@ -2715,27 +2711,26 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) char timedate[255]; int x_pos = 0; - // Move the timedate widget over if the battery percent is active. - if (percent_width) - x_pos = percent_width + xmb->icon.size; - if (coord_white[3] != 0) { + int x_pos = 0; + + if (percent_width) + x_pos = percent_width + (xmb->icon.size / 2.5); + xmb_draw_icon( menu_disp_info, xmb->icon.size, &mymat, xmb->textures.list[XMB_TEXTURE_CLOCK], - width - xmb->margins.title.left - (xmb->icon.size / 2.5) - x_pos, - xmb->icon.size - (xmb->icon.size / 3), - width, + width - xmb->icon.size - x_pos, + xmb->icon.size,width, height, 1, 0, 1, &coord_white[0], - xmb->shadow_offset, - 0.5); + xmb->shadow_offset); } timedate[0] = '\0'; @@ -2746,8 +2741,11 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) menu_display_timedate(&datetime); + if (percent_width) + x_pos = percent_width + (xmb->icon.size / 2.5); + xmb_draw_text(menu_disp_info, xmb, timedate, - width - xmb->margins.title.left - (xmb->icon.size / 2) - x_pos, + width - xmb->margins.title.left - xmb->icon.size / 4 - x_pos, xmb->margins.title.top, 1, 1, TEXT_ALIGN_RIGHT, width, height, xmb->font); } @@ -2772,8 +2770,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) 0, 1, &coord_white[0], - xmb->shadow_offset, - 1.0); + xmb->shadow_offset); menu_display_blend_begin(); @@ -2822,8 +2819,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info) rotation, scale_factor, &item_color[0], - xmb->shadow_offset, - 1.0); + xmb->shadow_offset); } } From 3785fc45245bf0ee8d1caca72c15187898c4d084 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Wed, 8 Feb 2017 19:45:01 +0000 Subject: [PATCH 44/90] Fixed crash in cheevos_get_description --- cheevos/cheevos.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 39be2afb93..8469e4622c 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -3225,15 +3225,23 @@ void cheevos_populate_menu(void *data, bool hardcore) bool cheevos_get_description(cheevos_ctx_desc_t *desc) { - cheevo_t *cheevos = cheevos_locals.core.cheevos; - - if (desc->idx >= cheevos_locals.core.count) + if (cheevos_loaded) { - cheevos = cheevos_locals.unofficial.cheevos; - desc->idx -= cheevos_locals.unofficial.count; - } + cheevo_t *cheevos = cheevos_locals.core.cheevos; - strlcpy(desc->s, cheevos[desc->idx].description, desc->len); + if (desc->idx >= cheevos_locals.core.count) + { + cheevos = cheevos_locals.unofficial.cheevos; + desc->idx -= cheevos_locals.unofficial.count; + } + + strlcpy(desc->s, cheevos[desc->idx].description, desc->len); + } + else + { + *desc->s = 0; + } + return true; } From 9993435cf94f4f389b7f0807a39df5121f942fd5 Mon Sep 17 00:00:00 2001 From: Nicolas Adenis-Lamarre Date: Wed, 8 Feb 2017 22:31:26 +0100 Subject: [PATCH 45/90] sdl2 renderer: remove the random flashing black borders on the batocera linux distribution (https://github.com/nadenislamarre/batocera.linux), retroarch gives some flashing black borders sometimes when running a game. It looks like sometimes the rendering is done without clearing the screen causing this flashing effect. Signed-off-by: Nicolas Adenis-Lamarre --- gfx/drivers/sdl2_gfx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index de65f8ffff..f8275ffd49 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -505,6 +505,7 @@ static bool sdl2_gfx_frame(void *data, const void *frame, unsigned width, { static struct retro_perf_counter sdl_copy_frame = {0}; + SDL_RenderClear(vid->renderer); sdl_refresh_input_size(vid, false, vid->video.rgb32, width, height, pitch); performance_counter_init(sdl_copy_frame, "sdl_copy_frame"); From 1c2e97b0c17ca74b655673324ee86f1541b7afcf Mon Sep 17 00:00:00 2001 From: rootfather Date: Thu, 9 Feb 2017 12:21:30 +0100 Subject: [PATCH 46/90] Rewrite German translation (Part 2.9) --- intl/msg_hash_de.h | 358 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 314 insertions(+), 44 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 758f74476e..9fa43afabb 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -8,19 +8,23 @@ MSG_HASH( ) MSG_HASH( MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Gerät nicht mit dem Anschluss verbunden" + "Gerät von Anschluss getrennt" ) MSG_HASH( MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, - "Unbekannter Netplay-Befehl empfangen" + "Unbekannter Netplay-Befehl wurde empfangen" ) MSG_HASH( MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER, - "Datei existiert bereits. Speichern im Backup-Puffer" + "Datei existiert bereits. Speichere im Backup-Puffer" ) MSG_HASH( MSG_GOT_CONNECTION_FROM, - "Verbindung erhalten von" + "Verbindung mit \"%s\" hergestellt" + ) +MSG_HASH( + MSG_GOT_CONNECTION_FROM_NAME, + "Verbindung mit \"%s (%s)\" hergestellt" ) MSG_HASH( MSG_PUBLIC_ADDRESS, @@ -42,6 +46,66 @@ MSG_HASH( MSG_WAITING_FOR_CLIENT, "Warte auf Client ..." ) +MSG_HASH( + MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME, + "Du hast das Spiel verlassen" + ) +MSG_HASH( + MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N, + "Du bist als Spieler %d beigetreten" + ) +MSG_HASH( + MSG_NETPLAY_IMPLEMENTATIONS_DIFFER, + "Unterschiedliche Implementierungen. Stelle sicher, dass Du die gleiche Version von RetroArch und dem Core verwendest." + ) +MSG_HASH( + MSG_NETPLAY_ENDIAN_DEPENDENT, + "Dieser Core unterstützt kein Netplay zwischen diesen Systemen" + ) +MSG_HASH( + MSG_NETPLAY_PLATFORM_DEPENDENT, + "Dieser Core unterstützt kein Netplay zwischen verschiedenen Systemen" + ) +MSG_HASH( + MSG_NETPLAY_ENTER_PASSWORD, + "Gib das Server-Passwort ein:" + ) +MSG_HASH( + MSG_NETPLAY_INCORRECT_PASSWORD, + "Falsches Passwort" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_NAMED_HANGUP, + "\"%s\" wurde getrennt" + ) +MSG_HASH( + MSG_NETPLAY_SERVER_HANGUP, + "Die Verbindung mit einem Netplay-Client wurde getrennt" + ) +MSG_HASH( + MSG_NETPLAY_CLIENT_HANGUP, + "Verbindung mit Netplay getrennt" + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, + "Du hast nicht die Berechtigung, an diesem Spiel teilzunehmen" + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, + "Es gibt keine freien Spieler-Plätze mehr" + ) +MSG_HASH( + MSG_NETPLAY_CANNOT_PLAY, + "Konnte nicht zum Spieler-Modus wechseln" + ) +MSG_HASH( + MSG_NETPLAY_PEER_PAUSED, + "Netplay-Teilnehmer \"%s\" pausiert" + ) +MSG_HASH( + MSG_NETPLAY_CHANGED_NICK, + "Dein Nickname wurde zu \"%s\" geändert" + ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, "Gibt Hardware-gerenderten Cores einen eigenen privaten Kontext. Vermeidet, dass der Hardware-Status zwischen den Frames geschätzt werden muss." @@ -56,8 +120,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Verbessert die Leistung, führt aber zu größerer Latenz und Videoproblemen. " - "Verwende dies nur, wenn Du sonst die gewünschte Leistung nicht erreichst." + "Verbessert die Leistung, führt aber zu größerer Latenz und Videoproblemen. Verwende dies nur, wenn Du sonst die gewünschte Leistung nicht erreichst." ) MSG_HASH( MSG_AUDIO_VOLUME, @@ -73,7 +136,7 @@ MSG_HASH( ) MSG_HASH( MSG_CAPABILITIES, - "Fähikeiten" + "Fähigkeiten" ) MSG_HASH( MSG_CONNECTING_TO_NETPLAY_HOST, @@ -119,7 +182,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, "Errungenschaften" ) - MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, "Errungenschaften (Hardcore)" @@ -136,9 +198,13 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_ADD_TAB, "Inhalt importieren" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_NETPLAY_TAB, + "Netplay-Räume" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ARCHIVE_MODE, - "Verknüpfte Aktion bei Archivdateien" + "Verknüpfte Aktion für Archivdateien" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ASK_ARCHIVE, @@ -342,7 +408,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Speichere Cheat-Datei unter..." + "Speichere Cheat-Datei unter ..." ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, @@ -400,10 +466,6 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG_SAVE_ON_EXIT, "Einstellungen beim Beenden speichern" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CONFIRM_ON_EXIT, - "Vor dem Beenden nachfragen" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_COLLECTION_LIST, "Sammlungen" @@ -419,8 +481,10 @@ MSG_HASH( MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, "Länge der Verlaufsliste") +MSG_HASH(MENU_ENUM_LABEL_VALUE_PLAYLIST_ENTRY_REMOVE, + "Erlaube, Einträge zu entfernen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, - "Inhaltseinstellungen") + "Spielmenü") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, "Core-Assets") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, @@ -454,7 +518,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_MANUFACTURER, MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFO_SYSTEM_NAME, "System-Name") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INPUT_REMAPPING_OPTIONS, - "Core-Eingabeoptionen") + "Steuerung") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_LIST, "Core laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_OPTIONS, @@ -466,7 +530,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_SET_SUPPORTS_NO_CONTENT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, "Heruntergeladene Archive automatisch entpacken") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - "Buildbot-Cores-URL") + "Buildbot-Core-URL") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_LIST, "Cores aktualisieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_UPDATER_SETTINGS, @@ -476,17 +540,19 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_ARCHITECTURE, MSG_HASH(MENU_ENUM_LABEL_VALUE_CPU_CORES, "CPU-Kerne:") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_DIRECTORY, - "Cursor") + "Suchanfragen") MSG_HASH(MENU_ENUM_LABEL_VALUE_CURSOR_MANAGER, - "Mauszeiger-Manager") + "Suchanfragen verwalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, "Benutzerdefiniertes Verhältnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, - "Datenbank-Manager") + "Datenbanken verwalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, "Datenbank-Auswahl") MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Von der Wiedergabeliste löschen") + "Von der Liste löschen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, + "Startverzeichnis") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, "") MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_DEFAULT, @@ -514,9 +580,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE, MSG_HASH(MENU_ENUM_LABEL_VALUE_DOWNLOAD_CORE_CONTENT, "Inhalt herunterladen") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_ENABLE, - "Aktiviere DPI-Override") + "Aktiviere DPI-Überschreibung") MSG_HASH(MENU_ENUM_LABEL_VALUE_DPI_OVERRIDE_VALUE, - "DPI-Override") + "DPI-Überschreibung") MSG_HASH(MENU_ENUM_LABEL_VALUE_DRIVER_SETTINGS, "Treiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_DUMMY_ON_CORE_SHUTDOWN, @@ -702,7 +768,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GRAB_MOUSE_TOGGLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_GAME_FOCUS_TOGGLE, "Spielfokus ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_LOAD_STATE_KEY, - "Savestate laden") + "Spielstand laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MENU_TOGGLE, "Menü aufrufen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE, @@ -711,6 +777,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, "Audio stumm-/lautschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, "Netplay-Benutzer vertauschen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, + "Zwischen Spieler- und Beobachter-Modus wechseln") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, "Bildschirmtastatur ein-/ausschalten") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT, @@ -724,7 +792,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_RESET, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_REWIND, "Zurückspulen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SAVE_STATE_KEY, - "Erstelle Savestate") + "Erstelle Spielstand") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, "Erstelle Bildschirmfoto") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_NEXT, @@ -734,9 +802,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SHADER_PREV, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, "Zeitlupe") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_MINUS, - "Savestate-Slot -") + "Spielstand-Speicherplatz -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_STATE_SLOT_PLUS, - "Savestate-Slot +") + "Spielstand-Speicherplatz +") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_DOWN, "Lautstärke -") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_VOLUME_UP, @@ -816,7 +884,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_LEFT_ANALOG, MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_DIR_PATH, "Core") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_INFO_PATH, - "Core-Infos") + "Core-Informationen") MSG_HASH(MENU_ENUM_LABEL_VALUE_LIBRETRO_LOG_LEVEL, "Core-Loglevel") MSG_HASH(MENU_ENUM_LABEL_VALUE_LINEAR, @@ -866,7 +934,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_DRIVER, MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_ENUM_THROTTLE_FRAMERATE, "Bildwiederholrate im Menü begrenzen") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_FILE_BROWSER_SETTINGS, - "Dateibrowser") + "Einstellungen") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_LINEAR_FILTER, "Linearer Filter für Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_SETTINGS, @@ -894,11 +962,15 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NEAREST, MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY, "Netplay") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES, - "Netplay-Frames prüfen") /* TODO: What does this setting do? Need more context. */ + "Netplay-Synchronisation prüfen") /* TODO: What does this setting do? Need more context. */ +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "Eingabeverzögerung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "Erlaubte Eingabeverzögerung") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT, "Netplay-Spieler 2 verwendet Client 1") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES, - "Netplay-Verzögerungsframes") + "Netplay-Verzögerung") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT, "Verbindung trennen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE, @@ -915,10 +987,18 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_MODE, "Netplay-Client aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NICKNAME, "Benutzername") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD, + "Server-Passwort") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE, + "Netplay öffentlich ankündigen") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS, - "Netplay") + "Netplay-Einstellungen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE, + "Netplay ohne Savestates") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATE_PASSWORD, + "Server-Passwort für Beobachter-Modus") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SPECTATOR_MODE_ENABLE, - "Netplay-Zuschauermodus aktivieren") + "Beobachtermodus aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_TCP_UDP_PORT, "Netplay TCP/UDP-Port") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_NAT_TRAVERSAL, @@ -1267,6 +1347,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DSOUND_SUPPORT, "DirectSound-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYLIB_SUPPORT, "Unterstützung für dynamische Bibliotheken") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_DYNAMIC_SUPPORT, + "Dymanisches Laden der libretro-Bilbiothek zur Laufzeit") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_EGL_SUPPORT, "EGL-Unterstützung") MSG_HASH(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FBO_SUPPORT, @@ -1573,12 +1655,16 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_FLATUI, "FlatUI") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_MONOCHROME, "Monochrome") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_SYSTEMATIC, + "Systematic") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_NEOACTIVE, "NeoActive") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_PIXEL, "Pixel") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_RETROACTIVE, "RetroActive") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_DOTART, + "Dot-Art") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME, "Menü-Farbschema") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_MENU_COLOR_THEME_APPLE_GREEN, @@ -1609,6 +1695,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHADOWS_ENABLE, "Icon-Schatten aktivieren") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_HISTORY, "Zeige Tab 'Verlauf'") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_ADD, + "Zeige Tab 'Inhalte importieren'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_IMAGES, "Zeige Tab 'Bilder'") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_SHOW_MUSIC, @@ -1623,10 +1711,14 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_YES, "Ja") MSG_HASH(MENU_ENUM_LABEL_VIDEO_SHADER_PRESET_TWO, "Shader-Voreinstellungen") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE, + "Aktiviere Errungenschaften. Für weitere Informationen, besuche http://retroachievements.org") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, + "Aktiviere inoffizielle Errungenschaften und/oder Beta-Funktionen zu Testzwecken.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, "Deaktiviert Spielstände, Cheats, Zurückspulen, Zeitraffer, Pause und Zeitlupe für alle Spiele.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, - "Ändere die Treiber für dieses System.") + "Ändere die Treiber, die von diesem System verwendet werden.") MSG_HASH(MENU_ENUM_SUBLABEL_RETRO_ACHIEVEMENTS_SETTINGS, "Ändere die Einstellungen für Errungenschaften.") MSG_HASH(MENU_ENUM_SUBLABEL_CORE_SETTINGS, @@ -1656,11 +1748,15 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_SETTINGS, MSG_HASH(MENU_ENUM_SUBLABEL_ADD_CONTENT_LIST, "Sucht nach Inhalten und fügt diese zur Datenbank hinzu.") MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_SETTINGS, - "Ändert die Einstellungen der Audio-Ausgabe.") + "Ändere die Einstellungen der Audio-Ausgabe.") MSG_HASH(MENU_ENUM_SUBLABEL_BLUETOOTH_ENABLE, - "Aktiviert oder deaktiviert Bluetooth.") + "Aktiviere oder deaktiviere Bluetooth.") MSG_HASH(MENU_ENUM_SUBLABEL_CONFIG_SAVE_ON_EXIT, - "Speichert Änderungen in die Konfigurationsdatei beim Beenden.") + "Speichere Änderungen an der Konfigurationsdatei beim Beenden.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATION_SETTINGS, + "Ändere die Standard-Einstellungen für Konfigurationsdateien.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONFIGURATIONS_LIST, + "Verwalte und erstelle Konfigurationsdateien.") MSG_HASH(MENU_ENUM_SUBLABEL_CPU_CORES, "Anzahl der verfügbaren CPU-Kerne.") MSG_HASH(MENU_ENUM_SUBLABEL_FPS_SHOW, @@ -1680,7 +1776,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY, MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_LAN_SCAN_SETTINGS, "Suche und verbinde mit Netplay-Hosts in deinem lokalen Netzwerk.") MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION_LIST_LIST, - "Zeigt Informationen über Core, Netzwerk und das Systems an.") + "Zeige Informationen über Core, Netzwerk und das System an.") MSG_HASH(MENU_ENUM_SUBLABEL_ONLINE_UPDATER, "Lade Erweiterungen, Komponenten und Inhalte für RetroArch herunter.") MSG_HASH(MENU_ENUM_SUBLABEL_SAMBA_ENABLE, @@ -2086,7 +2182,7 @@ MSG_HASH(MSG_USING_CORE_NAME_FOR_NEW_CONFIG, MSG_HASH(MSG_USING_LIBRETRO_DUMMY_CORE_RECORDING_SKIPPED, "Verwende libretro-Dumy-Core. Überspringe Aufzeichnung.") MSG_HASH(MSG_VALUE_CONNECT_DEVICE_FROM_A_VALID_PORT, - "Verbinde Gerät von einem gültigen Anschluss.") /* sounds odd, maybe improper translation*/ + "Verbinde Gerät mit einem gültigen Anschluss.") /* sounds odd, maybe improper translation*/ MSG_HASH(MSG_VALUE_DISCONNECTING_DEVICE_FROM_PORT, "Trenne Gerät von Anschluss") MSG_HASH(MSG_VALUE_REBOOTING, @@ -2105,8 +2201,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUDIO_MUTE, "Audio stumm-/lautschalten.") MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_RATE_CONTROL_DELTA, - "Hilft Fehler bei der Audio- und Videosynchronisierung auszubügeln. " - "Wenn deaktiviert, ist eine brauchbare Synchronisation nahezu unmöglich.") + "Hilft Fehler bei der Audio- und Videosynchronisierung auszubügeln. Wenn deaktiviert, ist eine brauchbare Synchronisation nahezu unmöglich." + ) MSG_HASH( MENU_ENUM_SUBLABEL_CAMERA_ALLOW, "Erlaube oder verbiete den Cores Zugriff auf die Kamera." @@ -2169,7 +2265,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE, - "Vertikale Bildwiederholrate des Bildschirms. Wird verwendet, um eine geeignete Audio-Eingangsrate zu berechnen. Hinweis: Diese Einstellung wird ignoriert, wenn 'Video in separatem Thread' aktiviert ist." + "Vertikale Bildwiederholrate des Bildschirms. Wird verwendet, um eine geeignete Audio-Eingangsrate zu berechnen. Hinweis: Wird ignoriert, wenn 'Video in separatem Thread' aktiviert ist." ) MSG_HASH( MENU_ENUM_SUBLABEL_AUDIO_ENABLE, @@ -2191,9 +2287,13 @@ MSG_HASH( MSG_DEVICE_NOT_CONFIGURED, "nicht konfiguriert" ) +MSG_HASH( + MSG_DEVICE_NOT_CONFIGURED_FALLBACK, + "nicht konfiguriert, verwende Rückfalloption" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST, - "Datenbank-Zeiger" /* might be inaccurate */ + "Datenbank-Suchanfragen" /* might be inaccurate */ ) MSG_HASH( MENU_ENUM_LABEL_VALUE_DATABASE_CURSOR_LIST_ENTRY_DEVELOPER, @@ -2249,4 +2349,174 @@ MSG_HASH(MSG_SCANNING_WIRELESS_NETWORKS, MSG_HASH(MSG_NETPLAY_LAN_SCAN_COMPLETE, "Netplay-Suche abgeschlossen.") MSG_HASH(MSG_NETPLAY_LAN_SCANNING, - "Suche nach Netplay-Hosts...") \ No newline at end of file + "Suche nach Netplay-Hosts...") +MSG_HASH(MENU_ENUM_SUBLABEL_PAUSE_NONACTIVE, + "Pausiere das Spiel, wenn RetroArch nicht das aktive Fenster ist.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_DISABLE_COMPOSITION, + "Aktiviere oder deaktiviere Desktop-Gestaltung (nur Windows).") +MSG_HASH(MENU_ENUM_SUBLABEL_HISTORY_LIST_ENABLE, + "Aktiviere Wiedergabeliste für kürzlich geöffnete Inhalte.") +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_HISTORY_SIZE, + "Begrenzt die Anzahl der Einträge in der Verlaufsliste.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_UNIFIED_MENU_CONTROLS, + "Einheitliche Menüsteuerung") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_UNIFIED_MENU_CONTROLS, + "Verwende die selbe Steuerung für das Menü und die Spiele. Betrifft nur Tastatur.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_ENABLE, + "Zeige Bildschirmbenachrichtungen an.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETWORK_USER_REMOTE_ENABLE, + "Aktiviere Fernsteuerung für Benutzer %d") +MSG_HASH(MENU_ENUM_LABEL_VALUE_BATTERY_LEVEL_ENABLE, + "Akkustand anzeigen") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FILE, + "Wähle Datei") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SELECT_FROM_COLLECTION, + "Wähle aus Sammlung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_FILTER, + "Filter") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SCALE, + "Skalierung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_WHEN_LOADED, + "Netplay wird gestartet, sobald ein Inhalt geladen wurde.") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_LOAD_CONTENT_MANUALLY, + "Konnte keinen geeigneten Core oder Inhalt finden, lade manuell.") +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL_LIST, + "Besuche URL" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_URL, + "URL-Pfad" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_BROWSE_START, + "Start" + ) +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, + "Bokeh") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, + "Aktualisieren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, + "Nickname: %s") +MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_COMPAT_CONTENT_FOUND, + "Kompatibler Inhalt gefunden") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_CROP_OVERSCAN, + "Schneidet ein paar Pixel an den Bildrändern ab, die üblicherweise von Entwicklern leer gelassen werden und manchmal auch fehlerhafte Pixel enthalten.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, + "Wendet einen leichten Weichzeichner auf das Bild an, um die Pixelkanten etwas abzurunden. Diese Option hat einen sehr geringen Einfluss auf die Leistung.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FILTER, + "Wendet einen CPU-Videofilter an. HINWEIS: Kann hohe Leistungseinbußen verursachen. Manche Videofilter funktionieren nur mit Cores, die eine Farbtiefe von 32 Bit oder 16 Bit verwenden.") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, + "Gib den Benutzernamen deines Errungenschaften-Kontos ein.") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, + "Gib das Passwort deines Errungenschaften-Kontos ein.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, + "Gib deinen Benutzernamen hier ein. Dieser wird unter anderem für Netplay-Sitzungen verwendet.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, + "Zeichnet das Bild auf, nachdem Filter (aber keine Shader) angewendet wurden. Dein Video wird genauso gut aussehen, wie das, was Du auf dem Bildschirm siehst.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_LIST, + "Wähle, welcher Core verwendet werden soll.") +MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST, + "Wähle, welcher Inhalt gestartet werden soll.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETWORK_INFORMATION, + "Zeige Netzwerk-Karten und zugewiesene IP-Adressen.") +MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION, + "Zeige Informationen über dieses Gerät an.") +MSG_HASH(MENU_ENUM_SUBLABEL_QUIT_RETROARCH, + "Verlasse das Programm.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_WIDTH, + "Wähle die Fensterbreite. Wird dieser Wert auf 0 belassen, wird versucht, das Fenster so groß wie möglich zu skalieren.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_WINDOW_HEIGHT, + "Wähle die Fensterhöhe. Wird dieser Wert auf 0 belassen, wird versucht, das Fenster so groß wie möglich zu skalieren.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_X, + "Wähle eine eigene X-Achsenposition für Bildschirmmeldungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MESSAGE_POS_Y, + "Wähle eine eigene Y-Achsenposition für Bildschirmmeldungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_SIZE, + "Wähle die Schriftgröße in Punkten.") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_OVERLAY_HIDE_IN_MENU, + "Verberge das Overlay im Menü und zeige es wieder an, wenn das Menü verlassen wird.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_COLLECTION_LIST, + "Durchsuchter Inhalt wird hier erscheinen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, + "Skaliere das Bild in ganzzahligen Schritten. Die Basisgröße hängt von der Geometrie und dem Seitenverhältnis ab, die vom System gemeldet werden. Wenn 'Seitenverhältnis erzwingen' nicht gewählt ist, werden Höhe u. Breite unabhängig skaliert." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, + "Verwende Bildmaterial nach Shaderdurchläufen für Bildschirmfotos, sofern verfügbar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_ROTATION, + "Erzwinge eine bestimmte Bildrotation. Diese Rotation wird Rotationen hinzugefügt, die vom Core vorgegeben werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE, + "Erzwinge die Deaktivierung der Unterstützung für sRGB FBO. Einige Intel OpenGL-Treiber können unter Windows Probleme verursachen, wenn sRGB FBO aktiviert ist. Diese Einstellung kann dies beheben." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN, + "Starte im Vollbildmodus. Kann zur Laufzeit geändert werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN, + "Bevorzuge einen Fenster-Vollbildmodus für den Vollbildmodus." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD, + "Verwende Bildmaterial nach Shaderdurchläufen für Aufnahmen, sofern verfügbar." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX, + "Wenn ein Spielstand erstellt wird, wird der Spielstand-Index automatisch erhöht, bevor der Spielstand gespeichert wird. Wenn Inhalt geladen wird, wird automatisch der höchste existierende Spielstand-Index gewählt." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE, + "Verhindere, dass das Save-RAM überschrieben wird, wenn ein Spielstand geladen wird. Kann zu fehlerhaften Spielen führen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, + "Die maximale Geschwindigkeit, mit der Inhalt im Vorlauf-Modus dargestellt wird (z.B. 5x für 60 Inhalt mit 60 Bildern/sek => Begrenzung auf 300 Bilder/sek). Wenn 0x gewählt ist, ist die Vorlauf-Geschwindigkeit unbegrenzt (keine Begrenzung der Bilder/sek)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, + "Im Zeitlupen-Modus wird der Inhalt um diesen Faktor verlangsamt." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_ENABLE, + "Aktiviere Zurückspulen. Kann Leistungseinbußen im Spiel verursachen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_REWIND_GRANULARITY, + "Wenn eine bestimmte Anzahl von Einzelbildern zurückgespult wird, kannst Du mehrere Einzelbilder auf einmal zurückspulen und damit die Zurückspul-Geschwindigkeit erhöhen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LIBRETRO_LOG_LEVEL, + "Setzt den Log-Level für Cores. Wenn der Log-Level, der von einem Core zurückgemeldet wird, unter diesem Wert liegt, wird er ignoriert." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PERFCNT_ENABLE, + "Aktiviere Leistungszähler für RetroArch (und Cores)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_SAVE, + "Speichere einen Spielstand automatisch, wenn RetroArch beendet wird. RetroArch wird diesen Spielstand automatisch laden, wenn 'Spielstand automatisch laden' aktiviert ist." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_LOAD, + "Lade einen Spielstand beim Start automatisch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_SAVESTATE_THUMBNAIL_ENABLE, + "Zeige Miniaturansichten von Spielständen im Menü an." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL, + "Speichere den Inhalt des nicht-flüchtigen Save-RAM in regelmäßigen Abständen. Diese Einstellung ist standardmäßig deaktiviert. Das Speicherintervall wird in Sekunden angegeben. Ein Wert von 0 deaktiviert das automatische Speichern." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, + "Wenn aktiviert, wird die Eingabebelegung mit den wiederzugewiesenen Belegungen, die für diesen Core gewählt wurden, überschrieben." + ) \ No newline at end of file From 4915f452f5399caeee1596ad70798e4ec2b3a40d Mon Sep 17 00:00:00 2001 From: xhp-creations Date: Thu, 9 Feb 2017 12:34:12 -0500 Subject: [PATCH 47/90] WiiU Initial Keyboard Support WiiU Initial Keyboard Support --- input/drivers/wiiu_input.c | 80 ++++++++++++++++++++++++++- input/input_keymaps.c | 106 ++++++++++++++++++++++++++++++++++++ input/input_keymaps.h | 1 + wiiu/include/wiiu/nsyskbd.h | 40 ++++++++++++++ wiiu/system/imports.h | 7 +++ 5 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 wiiu/include/wiiu/nsyskbd.h diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 56bbf8bbaf..4963535991 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -28,11 +28,63 @@ #include "../input_config.h" #include "../input_driver.h" #include "../input_joypad_driver.h" +#include "../input_keyboard.h" +#include "../input_keymaps.h" +#include #include "wiiu_dbg.h" #define MAX_PADS 5 +static unsigned char keyboardChannel = 0x00; +static KBDModifier keyboardModifier = 0x00; +static unsigned char keyboardCode = 0x00; +static KEYState keyboardState = KBD_WIIU_NULL; + +void kb_connection_callback(KBDKeyEvent *key) { + keyboardChannel = keyboardChannel + (key->channel + 0x01); +} + +void kb_disconnection_callback(KBDKeyEvent *key) { + keyboardChannel = keyboardChannel - (key->channel + 0x01); +} + +void kb_key_callback(KBDKeyEvent *key) { + keyboardModifier = key->modifier; + keyboardCode = key->scancode; + keyboardState = key->state; + + bool pressed = false; + + if (key->state > 0) + { + pressed = true; + } + uint16_t mod = 0; + unsigned code = input_keymaps_translate_keysym_to_rk(key->scancode); + + if (key->modifier & KBD_WIIU_SHIFT) + mod |= RETROKMOD_SHIFT; + + if (key->modifier & KBD_WIIU_CTRL) + mod |= RETROKMOD_CTRL; + + if (key->modifier & KBD_WIIU_ALT) + mod |= RETROKMOD_ALT; + + if (key->modifier & KBD_WIIU_NUM_LOCK) + mod |= RETROKMOD_NUMLOCK; + + if (key->modifier & KBD_WIIU_CAPS_LOCK) + mod |= RETROKMOD_CAPSLOCK; + + if (key->modifier & KBD_WIIU_SCROLL_LOCK) + mod |= RETROKMOD_SCROLLOCK; + + input_keyboard_event(pressed, code, (char)key->UTF16, mod, + RETRO_DEVICE_KEYBOARD); +} + typedef struct wiiu_input { bool blocked; @@ -46,7 +98,21 @@ static void wiiu_input_poll(void *data) wiiu_input_t *wiiu = (wiiu_input_t*)data; if (wiiu->joypad) - wiiu->joypad->poll(); + wiiu->joypad->poll(); +} + +static bool wiiu_key_pressed(int key) +{ + unsigned sym; + bool ret = false; + + if (key >= RETROK_LAST) + return false; + + if ((keyboardState > 0) && (keyboardChannel > 0)) + ret = keyboardCode; + + return ret; } static int16_t wiiu_input_state(void *data, @@ -59,11 +125,13 @@ static int16_t wiiu_input_state(void *data, if(!wiiu || !(port < MAX_PADS) || !binds || !binds[port]) return 0; - + switch (device) { case RETRO_DEVICE_JOYPAD: return input_joypad_pressed(wiiu->joypad, joypad_info, port, binds[port], id); + case RETRO_DEVICE_KEYBOARD: + return wiiu_key_pressed(id); case RETRO_DEVICE_ANALOG: if (binds[port]) return input_joypad_analog(wiiu->joypad, joypad_info, port, idx, id, binds[port]); @@ -79,6 +147,8 @@ static void wiiu_input_free_input(void *data) if (wiiu && wiiu->joypad) wiiu->joypad->destroy(); + + KBDTeardown(); free(data); } @@ -91,6 +161,10 @@ static void* wiiu_input_init(const char *joypad_driver) DEBUG_STR(joypad_driver); wiiu->joypad = input_joypad_init_driver(joypad_driver, wiiu); + + KBDSetup(&kb_connection_callback,&kb_disconnection_callback,&kb_key_callback); + + input_keymaps_init_keyboard_lut(rarch_key_map_wiiu); return wiiu; } @@ -107,7 +181,7 @@ static uint64_t wiiu_input_get_capabilities(void *data) { (void)data; - return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); + return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG) | (1 << RETRO_DEVICE_KEYBOARD); } static const input_device_driver_t *wiiu_input_get_joypad_driver(void *data) diff --git a/input/input_keymaps.c b/input/input_keymaps.c index eb5566b851..9bc933bf55 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -684,6 +684,112 @@ const struct rarch_key_map rarch_key_map_rwebinput[] = { }; #endif +#ifdef WIIU +const struct rarch_key_map rarch_key_map_wiiu[] = { + { 4, RETROK_a }, + { 5, RETROK_b }, + { 6, RETROK_c }, + { 7, RETROK_d }, + { 8, RETROK_e }, + { 9, RETROK_f }, + { 10, RETROK_g }, + { 11, RETROK_h }, + { 12, RETROK_i }, + { 13, RETROK_j }, + { 14, RETROK_k }, + { 15, RETROK_l }, + { 16, RETROK_m }, + { 17, RETROK_n }, + { 18, RETROK_o }, + { 19, RETROK_p }, + { 20, RETROK_q }, + { 21, RETROK_r }, + { 22, RETROK_s }, + { 23, RETROK_t }, + { 24, RETROK_u }, + { 25, RETROK_v }, + { 26, RETROK_w }, + { 27, RETROK_x }, + { 28, RETROK_y }, + { 29, RETROK_z }, + { 30, RETROK_1 }, + { 31, RETROK_2 }, + { 32, RETROK_3 }, + { 33, RETROK_4 }, + { 34, RETROK_5 }, + { 35, RETROK_6 }, + { 36, RETROK_7 }, + { 37, RETROK_8 }, + { 38, RETROK_9 }, + { 39, RETROK_0 }, + { 40, RETROK_RETURN }, + { 41, RETROK_ESCAPE }, + { 42, RETROK_BACKSPACE }, + { 43, RETROK_TAB }, + { 44, RETROK_SPACE }, + { 45, RETROK_MINUS }, + { 46, RETROK_EQUALS }, + { 47, RETROK_LEFTBRACKET }, + { 48, RETROK_RIGHTBRACKET }, + { 49, RETROK_BACKSLASH }, + { 51, RETROK_SEMICOLON }, + { 52, RETROK_QUOTE }, + { 53, RETROK_BACKQUOTE }, + { 54, RETROK_COMMA }, + { 55, RETROK_PERIOD }, + { 56, RETROK_SLASH }, + { 57, RETROK_CAPSLOCK }, + { 58, RETROK_F1 }, + { 59, RETROK_F2 }, + { 60, RETROK_F3 }, + { 61, RETROK_F4 }, + { 62, RETROK_F5 }, + { 63, RETROK_F6 }, + { 64, RETROK_F7 }, + { 65, RETROK_F8 }, + { 66, RETROK_F9 }, + { 67, RETROK_F10 }, + { 68, RETROK_F11 }, + { 69, RETROK_F12 }, + { 71, RETROK_SCROLLOCK }, + { 72, RETROK_PAUSE }, + { 73, RETROK_INSERT }, + { 74, RETROK_HOME }, + { 75, RETROK_PAGEUP }, + { 76, RETROK_DELETE }, + { 77, RETROK_END }, + { 78, RETROK_PAGEDOWN }, + { 79, RETROK_RIGHT }, + { 80, RETROK_LEFT }, + { 81, RETROK_DOWN }, + { 82, RETROK_UP }, + { 83, RETROK_NUMLOCK }, + { 84, RETROK_KP_DIVIDE }, + { 85, RETROK_KP_MULTIPLY }, + { 86, RETROK_KP_MINUS }, + { 87, RETROK_KP_PLUS }, + { 88, RETROK_KP_ENTER }, + { 89, RETROK_KP1 }, + { 90, RETROK_KP2 }, + { 91, RETROK_KP3 }, + { 92, RETROK_KP4 }, + { 93, RETROK_KP5 }, + { 94, RETROK_KP6 }, + { 95, RETROK_KP7 }, + { 96, RETROK_KP8 }, + { 97, RETROK_KP9 }, + { 98, RETROK_KP0 }, + { 99, RETROK_KP_PERIOD }, + { 224, RETROK_LCTRL }, + { 225, RETROK_LSHIFT }, + { 226, RETROK_LALT }, + { 228, RETROK_RCTRL }, + { 229, RETROK_RSHIFT }, + { 230, RETROK_RALT }, + { 0, RETROK_UNKNOWN }, +}; +#endif + #ifdef HAVE_X11 #ifndef XF68XK_Calculator diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 6d7fc99892..df3cb48790 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -58,6 +58,7 @@ extern const struct rarch_key_map rarch_key_map_apple_hid[]; extern const struct rarch_key_map rarch_key_map_android[]; extern const struct rarch_key_map rarch_key_map_qnx[]; extern const struct rarch_key_map rarch_key_map_dos[]; +extern const struct rarch_key_map rarch_key_map_wiiu[]; /** * input_keymaps_init_keyboard_lut: diff --git a/wiiu/include/wiiu/nsyskbd.h b/wiiu/include/wiiu/nsyskbd.h new file mode 100644 index 0000000000..9fae60fe0e --- /dev/null +++ b/wiiu/include/wiiu/nsyskbd.h @@ -0,0 +1,40 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _KEYState +{ + KBD_WIIU_DOWN = 0x01, + KBD_WIIU_REPEAT = 0x02, + KBD_WIIU_NULL = 0x00 +} KEYState; + +typedef enum _KBDModifier +{ + KBD_WIIU_CTRL = 0x0001, + KBD_WIIU_SHIFT = 0x0002, + KBD_WIIU_ALT = 0x0004, + KBD_WIIU_NUM_LOCK = 0x0100, + KBD_WIIU_CAPS_LOCK = 0x0200, + KBD_WIIU_SCROLL_LOCK = 0x0400, +} KBDModifier; + +typedef struct _KBDKeyEvent +{ + unsigned char channel; + unsigned char scancode; // scancode + KEYState state; // when held, value is 0x03, which is KBD_DOWN & KBD_REPEAT + KBDModifier modifier; // modifier state + unsigned short UTF16; // unicode, if any +} KBDKeyEvent; + +char KBDSetup(void *connection_callback, void *disconnection_callback, void *key_callback); +char KBDTeardown(); + +#ifdef __cplusplus +} +#endif diff --git a/wiiu/system/imports.h b/wiiu/system/imports.h index a2dfe9be99..665b6611d5 100644 --- a/wiiu/system/imports.h +++ b/wiiu/system/imports.h @@ -194,3 +194,10 @@ IMPORT(KPADRead); IMPORT_END(); +/* nsyskbd */ +IMPORT_BEGIN(nsyskbd); + +IMPORT(KBDSetup); +IMPORT(KBDTeardown); + +IMPORT_END(); From b04bf809e3cecc2fa4f0780cee0cad5e43f6a8b2 Mon Sep 17 00:00:00 2001 From: xhp-creations Date: Thu, 9 Feb 2017 14:08:27 -0500 Subject: [PATCH 48/90] WiiU Fix Keyboard Input WiiU Fix Keyboard Input --- input/drivers/wiiu_input.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 4963535991..2425640b83 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -39,7 +39,7 @@ static unsigned char keyboardChannel = 0x00; static KBDModifier keyboardModifier = 0x00; static unsigned char keyboardCode = 0x00; -static KEYState keyboardState = KBD_WIIU_NULL; +static KEYState keyboardState[256] = { KBD_WIIU_NULL }; void kb_connection_callback(KBDKeyEvent *key) { keyboardChannel = keyboardChannel + (key->channel + 0x01); @@ -52,7 +52,6 @@ void kb_disconnection_callback(KBDKeyEvent *key) { void kb_key_callback(KBDKeyEvent *key) { keyboardModifier = key->modifier; keyboardCode = key->scancode; - keyboardState = key->state; bool pressed = false; @@ -62,6 +61,7 @@ void kb_key_callback(KBDKeyEvent *key) { } uint16_t mod = 0; unsigned code = input_keymaps_translate_keysym_to_rk(key->scancode); + keyboardState[code] = key->state; if (key->modifier & KBD_WIIU_SHIFT) mod |= RETROKMOD_SHIFT; @@ -103,14 +103,13 @@ static void wiiu_input_poll(void *data) static bool wiiu_key_pressed(int key) { - unsigned sym; bool ret = false; if (key >= RETROK_LAST) return false; - if ((keyboardState > 0) && (keyboardChannel > 0)) - ret = keyboardCode; + if ((keyboardState[key] > 0) && (keyboardChannel > 0)) + ret = true; return ret; } From a33778cb8778bc8baeb5e590da533f68b4a16256 Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 9 Feb 2017 21:10:40 -0500 Subject: [PATCH 49/90] fix crashes when trying to connect with contentless cores --- tasks/task_netplay_find_content.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index adb32837a2..00ac723ceb 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -57,7 +57,8 @@ static void netplay_crc_scan_callback(void *task_data, return; fflush(stdout); - if (!string_is_empty(state->core_path) && !string_is_empty(state->content_path)) + if (!string_is_empty(state->core_path) && !string_is_empty(state->content_path) && + !string_is_equal(state->content_path, "N/A")) { command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, state->hostname); task_push_content_load_default( @@ -67,15 +68,22 @@ static void netplay_crc_scan_callback(void *task_data, CONTENT_MODE_LOAD_CONTENT_WITH_NEW_CORE_FROM_MENU, NULL, NULL); } - else if(string_is_equal(state->content_path, "N/A")) + else if (!string_is_empty(state->core_path) && !string_is_empty(state->content_path) && + string_is_equal(state->content_path, "N/A")) { printf("Content: %s Core: %s\n", state->content_path, state->core_path); task_push_content_load_default( state->core_path, NULL, - NULL, + &content_info, CORE_TYPE_PLAIN, CONTENT_MODE_LOAD_NOTHING_WITH_NEW_CORE_FROM_MENU, NULL, NULL); + task_push_content_load_default( + state->core_path, NULL, + &content_info, + CORE_TYPE_PLAIN, + CONTENT_MODE_LOAD_NOTHING_WITH_CURRENT_CORE_FROM_MENU, + NULL, NULL); } else { @@ -263,8 +271,12 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name, if(string_is_equal(info->list[i].core_name, state->core_name)) { strlcpy(state->core_path, info->list[i].path, sizeof(state->core_path)); - strlcpy(state->core_extensions, - info->list[i].supported_extensions, sizeof(state->core_extensions)); + + if (!string_is_equal(state->content_path, "N/A")) + { + strlcpy(state->core_extensions, + info->list[i].supported_extensions, sizeof(state->core_extensions)); + } break; } } From cd1792799034ca088a5707453a1ea45e91aeb1df Mon Sep 17 00:00:00 2001 From: radius Date: Thu, 9 Feb 2017 21:22:52 -0500 Subject: [PATCH 50/90] fix contentless netplay! thanks Gregor --- command.c | 9 --------- tasks/task_netplay_find_content.c | 2 +- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/command.c b/command.c index 548c75a279..86a42a3c06 100644 --- a/command.c +++ b/command.c @@ -1350,15 +1350,6 @@ static bool event_init_content(void) content_get_status(&contentless, &is_inited); - if (contentless) - { -#ifdef HAVE_NETWORKING - if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL)) - RARCH_ERR("%s\n", msg_hash_to_str(MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY)); -#endif - return true; - } - command_event_set_savestate_auto_index(); if (event_load_save_files()) diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 00ac723ceb..5a154095d9 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -71,7 +71,7 @@ static void netplay_crc_scan_callback(void *task_data, else if (!string_is_empty(state->core_path) && !string_is_empty(state->content_path) && string_is_equal(state->content_path, "N/A")) { - printf("Content: %s Core: %s\n", state->content_path, state->core_path); + command_event(CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED, state->hostname); task_push_content_load_default( state->core_path, NULL, &content_info, From 8e6df5fe85bb983a437e5eb4d4b5d1f0b3857236 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 9 Feb 2017 23:54:35 -0500 Subject: [PATCH 51/90] MSVC buildfix --- intl/msg_hash_ru.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index c6beb03f93..480252759d 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif From b2f435923439150ddfffb6d6b37c71e589a00af7 Mon Sep 17 00:00:00 2001 From: rootfather Date: Fri, 10 Feb 2017 20:08:55 +0100 Subject: [PATCH 52/90] Add some more strings to German translation --- intl/msg_hash_de.h | 134 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 5 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 9fa43afabb..db2806846f 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -384,7 +384,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CAMERA_DRIVER, - "Kamera-Treiber" + "Kameratreiber" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT, @@ -678,7 +678,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AUTODETECT_ENABLE, MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_AXIS_THRESHOLD, "Schwellenwert der Analogsticks") MSG_HASH(MENU_ENUM_LABEL_VALUE_MENU_INPUT_SWAP_OK_CANCEL, - "Vertausche OK- und Zurück-Tasten im Menü") + "Vertausche OK- und Zurück-Tasten im Menü") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_ALL, "Alle zuordnen") MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_BIND_DEFAULT_ALL, @@ -1178,7 +1178,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORDING_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_CONFIG, "Lade Aufnahme-Konfiguration...") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_DRIVER, - "Aufnahme-Treiber") + "Aufnahmetreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_ENABLE, "Aktiviere Aufnahmefunktion") MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_PATH, @@ -1540,7 +1540,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Deaktiviere Desktop-Gestaltung") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, - "Grafiktreiber") + "Videotreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, "Grafikfilter") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER_DIR, @@ -2519,4 +2519,128 @@ MSG_HASH( MSG_HASH( MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE, "Wenn aktiviert, wird die Eingabebelegung mit den wiederzugewiesenen Belegungen, die für diesen Core gewählt wurden, überschrieben." - ) \ No newline at end of file + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE, + "Aktiviere automatische Erkennung von Eingabegeräten. Wird versuchen, Gamepads automatisch zu erkennen (Plug-and-Play)." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_INPUT_SWAP_OK_CANCEL, + "Vertausche die Tasten für 'OK' und 'Abbrechen'. Wenn deaktiviert, wird die japanische Tastenbelegung verwendet; wenn aktiviert, wird die westliche Tastenbelegung verwendet." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PAUSE_LIBRETRO, + "Wenn deaktiviert, wird der Inhalt im Hintergrund weiterlaufen, wenn das RetroArch-Menü aufgerufen wird." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_DRIVER, + "Zu verwendender Videotreiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DRIVER, + "Zu verwendender Audiotreiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_DRIVER, + "Zu verwendender Eingabetreiber. Abhängig vom Videotreiber kann dieser einen anderen Eingabetreiber erzwingen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_JOYPAD_DRIVER, + "Zu verwendender Joypad-Treiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_RESAMPLER_DRIVER, + "Zu verwendender Audio-Resampling-Treiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CAMERA_DRIVER, + "Zu verwendender Kameratreiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_LOCATION_DRIVER, + "Zu verwendender Treiber für Ortsdienste." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_DRIVER, + "Zu verwendender Menütreiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_RECORD_DRIVER, + "Zu verwendender Aufnahmetreiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_WIFI_DRIVER, + "Zu verwendender WLAN-Treiber." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NAVIGATION_BROWSER_FILTER_SUPPORTED_EXTENSIONS_ENABLE, + "Zeige nur Dateien mit unterstützten Dateierweiterungen im Dateibrowser an." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MENU_WALLPAPER, + "Wähle ein Bild aus, das als Menü-Hintergrundbild verwendet werden soll." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPER, + "Lade ein neues Hintergrundbild dynamisch, abhängig vom Inhalt." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DEVICE, + "Überschreibe das standardmäßig ausgewählte Audiogerät, welches vom Audiotreiber verwendet wird. Dies ist treiberabhängig." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_DSP_PLUGIN, + "Audio-DSP-Plugin, welches die Audiodaten verarbeitet, bevor sie zum Treiber gesendet werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_OUTPUT_RATE, + "Sampling-Rate der Audio-Ausgabe." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_OPACITY, + "Transparenz aller Bedienelemente des Overlays." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_SCALE, + "Skalierung aller Bedienelemente des Overlays." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_INPUT_OVERLAY_ENABLE, + "Aktiviere das Overlay." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_OVERLAY_PRESET, + "Wähle ein Overlay mit dem Dateibrowser aus." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_IP_ADDRESS, + "Die Adresse des Hosts, mit dem eine Verbindung hergestellt werden soll." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_TCP_UDP_PORT, + "Der Port der Host-IP-Adresse. Kann entweder ein TCP- oder ein UDP-Port sein." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PASSWORD, + "Das Passwort, das für die Verbindung zum Netplay-Host verwendet werden soll. Wird nur im Host-Modus verwendet." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_PUBLIC_ANNOUNCE, + "Lege fest, ob Netplay-Spiele öffentlich angekündigt werden sollen. Wenn deaktiviert, müssen sich Clients manuell verbinden und können die öffentliche Lobby nicht verwenden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_SPECTATE_PASSWORD, + "Das Passwort, das für die Verbindung zum Netplay-Host mit Beobachter-Privilegien verwendet wird. Wird nur im Host-Modus verwendet." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_STATELESS_MODE, + "Lege fest, ob Netplay in einem Modus ohne Savestates läuft. Wenn aktiviert, ist ein sehr schnelles Netwerk nötig. Da kein Rücklauf erfolgt, läuft das Spiel flüssiger." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_CHECK_FRAMES, + "Die Häufigkeit in Einzelbildern, mit der Netplay überprüfen wird wird, ob der Host und der Client miteinander synchronisiert sind." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, + "Versuche, auf eingehende Verbindungen aus dem öffentlichen Internet zu hören. Dabei wird UPnP oder eine ähnliche Technologie benötigt, um das eigene LAN zu verlassen." + ) From 0c5fe1dd79f1baa3c667474c21dfd2f9647ef8af Mon Sep 17 00:00:00 2001 From: radius Date: Fri, 10 Feb 2017 23:58:40 -0500 Subject: [PATCH 53/90] add zip and 7z always to the list of supported extensions --- core_info.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core_info.c b/core_info.c index 2525fc5b11..b9cde94b77 100644 --- a/core_info.c +++ b/core_info.c @@ -76,6 +76,12 @@ static void core_info_list_resolve_all_extensions( core_info_list->list[i].supported_extensions, all_ext_len); strlcat(core_info_list->all_ext, "|", all_ext_len); } +#ifdef HAVE_7ZIP + strlcat(core_info_list->all_ext, "7z|", all_ext_len + 3); +#endif +#ifdef HAVE_ZLIB + strlcat(core_info_list->all_ext, "zip|", all_ext_len + 4); +#endif } static void core_info_list_resolve_all_firmware( From 5ea570c9783555ab534e2b2ee7a4f4f6d586db1a Mon Sep 17 00:00:00 2001 From: radius Date: Fri, 10 Feb 2017 23:58:40 -0500 Subject: [PATCH 54/90] add zip and 7z always to the list of supported extensions --- core_info.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core_info.c b/core_info.c index 2525fc5b11..b9cde94b77 100644 --- a/core_info.c +++ b/core_info.c @@ -76,6 +76,12 @@ static void core_info_list_resolve_all_extensions( core_info_list->list[i].supported_extensions, all_ext_len); strlcat(core_info_list->all_ext, "|", all_ext_len); } +#ifdef HAVE_7ZIP + strlcat(core_info_list->all_ext, "7z|", all_ext_len + 3); +#endif +#ifdef HAVE_ZLIB + strlcat(core_info_list->all_ext, "zip|", all_ext_len + 4); +#endif } static void core_info_list_resolve_all_firmware( From 0f1943259e18371cf85b4e208576ab12cc410cac Mon Sep 17 00:00:00 2001 From: radius Date: Sat, 11 Feb 2017 14:43:28 -0500 Subject: [PATCH 55/90] add changelog --- CHANGES.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000000..77a714f318 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,16 @@ +# 1.4.2 (future) +- COMMON: Threading fixes +- NET: Allow manual netplay content loading +- CHEEVOS: WIP leaderboards support +- LOCALIZATION: Rewrite german translation +- NET: Announcing network games to the public lobby is optional now +- LOCALIZATION: Update several english sublabels +- DOS: Improve color accuracy and scalines +- CHEEVOS: Fix crashes in the cheevos description menu +- DOS: Add keyboard driver +- Android: Autoconf fallback +- WiiU: Keyboard support +- NET: fix netplay join for contentless cores +- SCANNER: always add 7z & zip to supported extensions + +# 1.4.1 From 8783d92f2360ddd3ff930825bf8726820715e411 Mon Sep 17 00:00:00 2001 From: radius Date: Sat, 11 Feb 2017 14:45:11 -0500 Subject: [PATCH 56/90] update changelog --- CHANGES.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 77a714f318..82e3282484 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,16 +1,16 @@ # 1.4.2 (future) -- COMMON: Threading fixes -- NET: Allow manual netplay content loading -- CHEEVOS: WIP leaderboards support -- LOCALIZATION: Rewrite german translation -- NET: Announcing network games to the public lobby is optional now -- LOCALIZATION: Update several english sublabels -- DOS: Improve color accuracy and scalines +- ANDROID: Autoconf fallback - CHEEVOS: Fix crashes in the cheevos description menu +- CHEEVOS: WIP leaderboards support +- COMMON: Threading fixes - DOS: Add keyboard driver -- Android: Autoconf fallback -- WiiU: Keyboard support +- DOS: Improve color accuracy and scalines +- LOCALIZATION: Rewrite german translation +- LOCALIZATION: Update several english sublabels +- NET: Allow manual netplay content loading +- NET: Announcing network games to the public lobby is optional now - NET: fix netplay join for contentless cores - SCANNER: always add 7z & zip to supported extensions +- WIIU: Keyboard support # 1.4.1 From e0cbce96c5421357fe639aaf17e6c202749fa4f0 Mon Sep 17 00:00:00 2001 From: rootfather Date: Sat, 11 Feb 2017 22:15:25 +0100 Subject: [PATCH 57/90] Add more strings to the German translation --- intl/msg_hash_de.h | 149 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index db2806846f..53153ae766 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -896,7 +896,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY, MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST, "Inhalt laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOAD_STATE, - "Savestate laden") + "Spielstand laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_ALLOW, "Standortbestimmung erlauben") MSG_HASH(MENU_ENUM_LABEL_VALUE_LOCATION_DRIVER, @@ -1240,7 +1240,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_SAVE, MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_DIRECTORY, "Spielstände") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVESTATE_THUMBNAIL_ENABLE, - "Spielstand-Vorschaubilder") + "Spielstand-Miniaturansichten") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG, "Speichere aktuelle Konfiguration") MSG_HASH(MENU_ENUM_LABEL_VALUE_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, @@ -2644,3 +2644,148 @@ MSG_HASH( MENU_ENUM_SUBLABEL_NETPLAY_NAT_TRAVERSAL, "Versuche, auf eingehende Verbindungen aus dem öffentlichen Internet zu hören. Dabei wird UPnP oder eine ähnliche Technologie benötigt, um das eigene LAN zu verlassen." ) +MSG_HASH( + MENU_ENUM_SUBLABEL_STDIN_CMD_ENABLE, + "Aktiviere stdin-Befehlsschnittstelle." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_MOUSE_ENABLE, + "Aktiviere Maussteuerung im Menü." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_POINTER_ENABLE, + "Aktiviere Touch-Steuerung im Menü." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_THUMBNAILS, + "Art der Miniaturansichten, die verwendet werden soll." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE, + "Zeige das aktuelle Datum und/oder die Zeit im Menü an." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE, + "Zeige den aktuellen Akkustand im Menü an." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NAVIGATION_WRAPAROUND, + "Springe zum Anfang und/oder Ende, wenn die Grenzen einer Liste horizontal oder vertikal erreicht werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_HOST, + "Aktiviere Netplay im Host-Modus (Server)." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_ENABLE_CLIENT, + "Aktiviere Netplay im Client-Modus.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_DISCONNECT, + "Beendet eine aktive Netplay-Verbindung.") +MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_DIRECTORY, + "Durchsuche ein Verzeichnis nach kompatiblen Dateien und füge diese zur Sammlung hinzu.") +MSG_HASH(MENU_ENUM_SUBLABEL_SCAN_FILE, + "Untersuche eine kompatible Datei und fügt diese zur Sammlung hinzu.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL, + "Verwende ein eigenes Intervall für Vsync. Aktivieren, um die Bildschirm-Wiederholrate zu halbieren." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE, + "Speichere Speicherdaten in Ordnern ab, die nach dem verwendeten Core benannt sind." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE, + "Speichere Spielstände in Ordnern ab, die nach dem verwendeten Core benannt sind." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT, + "Verwende die Tastenbelegung für Spieler 1, wenn Du ein Client im Netplay bist.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL, + "URL zum Core-Verzeichnis auf dem libretro-Buildbot.") +MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL, + "URL zum Assets-Verzeichnis auf dem libretro-Buildbot.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_AUTO_EXTRACT_ARCHIVE, + "Entpacke Dateien, die sich in heruntergeladenen Archiven befinden, nach dem Download automatisch." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REFRESH_ROOMS, + "Suche nach neuen Räumen.") +MSG_HASH(MENU_ENUM_SUBLABEL_DELETE_ENTRY, + "Entferne diesen Eintrag aus der Sammlung.") +MSG_HASH(MENU_ENUM_SUBLABEL_INFORMATION, + "Zeige weiterführende Informationen über diesen Inhalt an.") +MSG_HASH(MENU_ENUM_SUBLABEL_RUN, + "Starte den Inhalt.") +MSG_HASH(MENU_ENUM_SUBLABEL_MENU_FILE_BROWSER_SETTINGS, + "Passe die Dateibrowser-Einstellungen an.") +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_REMAPS_ENABLE, + "Aktiviere benutzerdefinierte Tastenbelegungen beim Start automatisch." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUTO_OVERRIDES_ENABLE, + "Aktiviere benutzerdefininerte Einstellungen beim Start automatisch." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_GAME_SPECIFIC_OPTIONS, + "Aktiviere benutzerdefinierte Core-Einstellungen beim Start automatisch.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ENABLE, + "Zeige den Namen des aktuellen Cores im Menü an.") +MSG_HASH(MENU_ENUM_SUBLABEL_DATABASE_MANAGER, + "Betrachte Datenbanken.") +MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_MANAGER, + "Betrachte vorherige Suchanfragen.") /* Maybe sloppy */ +MSG_HASH(MENU_ENUM_SUBLABEL_TAKE_SCREENSHOT, + "Fertigt ein Foto des Bildschirms an.") +#ifdef HAVE_DYNAMIC +MSG_HASH( + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Schließt das aktuelle Spiel und die aktuelle Anwendung. Alle nicht gespeicherten Änderungen können verloren gehen." + ) +#else +MSG_HASH( + MENU_ENUM_SUBLABEL_CLOSE_CONTENT, + "Schließt das aktuelle Spiel. Alle nicht gespeicherten Änderungen können verloren gehen." + ) +#endif +MSG_HASH(MENU_ENUM_SUBLABEL_LOAD_STATE, + "Lade einen gespeicherten Spielstand aus dem aktuellen Speicherplatz.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_STATE, + "Speichere einen Spielstand in dem aktuellen Speicherplatz.") +MSG_HASH(MENU_ENUM_SUBLABEL_RESUME, + "Setze die aktuelle Anwendung wieder fort und verlasse das Spielmenü.") +MSG_HASH(MENU_ENUM_SUBLABEL_RESUME_CONTENT, + "Setze den aktuellen Inhalt wieder fort und verlasse das Spielmenü") +MSG_HASH(MENU_ENUM_SUBLABEL_STATE_SLOT, + "Ändert den aktuell gewählten Spielstand-Speicherplatz.") +MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_LOAD_STATE, + "Wenn ein Spielstand geladen wurde, wird der Inhalt zum Zustand vor dem Laden des Spielstandes zurückkehren.") +MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, + "Wenn ein Spielstand überschrieben wurde, wird der Inhalt des zuvor gespeicherten Spielstands wiederhergestellt.") +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, + "Retro Achievements (Errungenschaften-Dienst). Besuche http://retroachievements.org für weitere Informationen." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, + "Verwalte die aktuell konfigurierten Benutzerkonten." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_META_REWIND, + "Verwalte die Einstellungen für die Rückspul-Funktion.") +MSG_HASH(MENU_ENUM_SUBLABEL_RESTART_CONTENT, + "Starte den Inhalt vom Beginn an neu.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_CORE, + "Speichere eine überschreibende Konfiguration, die für jeden Inhalt, der mit diesem Core geladen wird, verwendet wird. Wird gegenüber der normalen Konfiguration bevorzugt.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVE_CURRENT_CONFIG_OVERRIDE_GAME, + "Speichere eine überschreibende Konfiguration, die nur für den aktuellen Inhalt verwendet wird. Wird gegenüber der normalen Konfiguration bevorzugt.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_CHEAT_OPTIONS, + "Verwende Cheat-Codes.") +MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_OPTIONS, + "Verwende Shader, um die Videodarstellung zu verbessern.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INPUT_REMAPPING_OPTIONS, + "Ändere die Steuerung für den aktuell laufenden Inhalt.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_OPTIONS, + "Ändere die Optionen für die aktuell laufende Anwendung") +MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_ADVANCED_SETTINGS, + "Zeige erweiterte Einstellungen für erfahrene Benutzer (standardmäßig ausgeblendet).") +MSG_HASH(MENU_ENUM_SUBLABEL_THREADED_DATA_RUNLOOP_ENABLE, + "Führe Aufgaben im Hintergrund aus.") +MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, + "Erlaube dem Benutzer, Einträge aus der Sammlung zu entfernen.") +MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, + "Lege das Systemverzeichnis fest. Cores können dieses Verzeichnis verwenden, um ein BIOS, system-spezifische Konfigurationen usw. zu laden.") +MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, + "Lege das Startverzeichnis für den Dateibrowser fest.") \ No newline at end of file From af7c346e23bccdc47950c0273fdfd7de6d552df5 Mon Sep 17 00:00:00 2001 From: rootfather Date: Sat, 11 Feb 2017 23:10:29 +0100 Subject: [PATCH 58/90] Fix typo in the German translation --- intl/msg_hash_de.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 53153ae766..602c8ea7d5 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1798,7 +1798,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_BLACK_FRAME_INSERTION, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FRAME_DELAY, "Reduziert Latenz, kann aber zu Anzeigefehlern führen. Fügt eine Verzögerung bei V-Sync hinzu (in ms).") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES, - "Anzahl der Bilder, die die CPU der GPU voraus sein darf, wenn die CPU/GPU-Synchronisation aktiviert ist.") + "Anzahl der Bilder, der die CPU der GPU voraus sein darf, wenn die CPU/GPU-Synchronisation aktiviert ist.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, "Zwingt den Videotreiber dazu, einen bestimmten Framebuffer zu verwenden.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX, From 77e479a8bcb90d01ad679e05c2efd260f693b2e3 Mon Sep 17 00:00:00 2001 From: Diablodiab Date: Sun, 12 Feb 2017 13:26:18 +0100 Subject: [PATCH 59/90] Adds two new parameters that can be passed to the Android version of Retroarch at launch: QUITFOCUS If enabled this will cause Retroarch to quit completely when it loses focus (eg. when the home button is pressed). This is useful when you are using an alternative launcher such as Kodi because it will make the home button function as an alternative quit key, return to the alternative launcher, and then allow for a different game to start instead of returning to the current session. HIDEMOUSE Normally it is not possible to hide the mouse cursor if you have attached an external mouse to your Android unit. This makes it difficult to implement mouse support in the Android version of Retroarch because you will end up having two mouse cursors on the screen. NVIDIA has implemented extensions on the SHIELD that allows for hiding the mouse cursor. If this parameter is provided when starting Retroarch it will check for these extensions and if available it will hide the mouse cursor. (I am almost done with adding mouse support to the Android input driver and will be submitting a suggestion for this very soon) --- .../retroactivity/RetroActivityFuture.java | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java index 19ad1290c6..dede1ed0b8 100644 --- a/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java +++ b/pkg/android/phoenix/src/com/retroarch/browser/retroactivity/RetroActivityFuture.java @@ -3,9 +3,16 @@ package com.retroarch.browser.retroactivity; import android.view.View; import android.view.WindowManager; import android.content.Intent; +import android.content.Context; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import android.hardware.input.InputManager; public final class RetroActivityFuture extends RetroActivityCamera { + // If set to true then Retroarch will completely exit when it loses focus + private boolean quitfocus = false; + @Override public void onResume() { super.onResume(); @@ -28,7 +35,7 @@ public final class RetroActivityFuture extends RetroActivityCamera { | API_SYSTEM_UI_FLAG_FULLSCREEN | API_SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - // Check for REFRESH parameter + // Check for Android UI specific parameters Intent retro = getIntent(); String refresh = retro.getStringExtra("REFRESH"); @@ -38,7 +45,40 @@ public final class RetroActivityFuture extends RetroActivityCamera { params.preferredRefreshRate = Integer.parseInt(refresh); getWindow().setAttributes(params); } + + // If QUITFOCUS parameter is provided then enable that Retroarch quits when focus is lost + quitfocus = retro.hasExtra("QUITFOCUS"); + + // If HIDEMOUSE parameters is provided then hide the mourse cursor + // This requires NVIDIA Android extensions (available on NVIDIA Shield), if they are not + // available then nothing will be done + if (retro.hasExtra("HIDEMOUSE")) hideMouseCursor(); } } + public void hideMouseCursor() { + + // Check for NVIDIA extensions and minimum SDK version + Method mInputManager_setCursorVisibility; + try { mInputManager_setCursorVisibility = + InputManager.class.getMethod("setCursorVisibility", boolean.class); + } + catch (NoSuchMethodException ex) { + return; // Extensions were not available so do nothing + } + + // Hide the mouse cursor + InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE); + try { mInputManager_setCursorVisibility.invoke(inputManager, false); } + catch (InvocationTargetException ite) { } + catch (IllegalAccessException iae) { } + } + + @Override + public void onStop() { + super.onStop(); + + // If QUITFOCUS parameter was set then completely exit Retroarch when focus is lost + if (quitfocus) System.exit(0); + } } From 4fc758799f08547aaf9499eb5f828bdfac649bd9 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 12 Feb 2017 16:18:32 +0000 Subject: [PATCH 60/90] Only compile support for leaderboards if CHEEVOS_ENABLE_LBOARDS is defined --- cheevos/cheevos.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 9422042f7f..b1e64f1f13 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1666,8 +1666,10 @@ static int cheevos_read__json_end_object(void *userdata) if (ud->in_cheevos) return cheevos_new_cheevo(ud); +#ifdef CHEEVOS_ENABLE_LBOARDS else if (ud->in_lboards) return cheevos_new_lboard(ud); +#endif return 0; } @@ -3302,7 +3304,9 @@ void cheevos_test(void) if (settings->cheevos.test_unofficial) cheevos_test_cheevo_set(&cheevos_locals.unofficial); +#ifdef CHEEVOS_ENABLE_LBOARDS cheevos_test_leaderboards(); +#endif } bool cheevos_set_cheats(void) From 0b75671c21ec1e891779031b6435ad18debe3e60 Mon Sep 17 00:00:00 2001 From: vanfanel Date: Sun, 12 Feb 2017 19:27:59 +0100 Subject: [PATCH 61/90] DISPMANX: Disable triple buffering for now, for stability reasons. --- gfx/drivers/dispmanx_gfx.c | 147 +++---------------------------------- 1 file changed, 12 insertions(+), 135 deletions(-) diff --git a/gfx/drivers/dispmanx_gfx.c b/gfx/drivers/dispmanx_gfx.c index 96abb92971..090a76ad1b 100644 --- a/gfx/drivers/dispmanx_gfx.c +++ b/gfx/drivers/dispmanx_gfx.c @@ -16,8 +16,6 @@ #include -#include - #ifdef HAVE_CONFIG_H #include "../../config.h" #endif @@ -36,10 +34,6 @@ struct dispmanx_page /* Each page contains it's own resource handler * instead of pointing to in by page number */ DISPMANX_RESOURCE_HANDLE_T resource; - bool used; - /* Each page has it's own mutex for - * isolating it's used flag access. */ - slock_t *page_used_mutex; /* This field will allow us to access the * main _dispvars struct from the vsync CB function */ @@ -57,10 +51,7 @@ struct dispmanx_surface struct dispmanx_page *pages; /* the page that's currently on screen */ struct dispmanx_page *current_page; - /*The page to wich we will dump the render. We need to know this - * already when we enter the surface update function. No time to wait - * for free pages before blitting and showing the just rendered frame! */ - struct dispmanx_page *next_page; + bool flip_page; unsigned int bpp; VC_RECT_T src_rect; @@ -102,12 +93,6 @@ struct dispmanx_video unsigned int dispmanx_width; unsigned int dispmanx_height; - /* For threading */ - scond_t *vsync_condition; - slock_t *vsync_cond_mutex; - slock_t *pending_mutex; - unsigned int pageflip_pending; - /* Menu */ bool menu_active; @@ -129,94 +114,15 @@ struct dispmanx_video float aspect_ratio; }; -/* If no free page is available when called, wait for a page flip. */ -static struct dispmanx_page *dispmanx_get_free_page(void *data, struct dispmanx_surface *surface) -{ - unsigned i; - struct dispmanx_video *_dispvars = data; - struct dispmanx_page *page = NULL; - - while (!page) - { - /* Try to find a free page */ - for (i = 0; i < surface->numpages; ++i) - { - if (!surface->pages[i].used) - { - page = (surface->pages) + i; - break; - } - } - - /* If no page is free at the moment, - * wait until a free page is freed by vsync CB. */ - if (!page) - { - slock_lock(_dispvars->vsync_cond_mutex); - scond_wait(_dispvars->vsync_condition, _dispvars->vsync_cond_mutex); - slock_unlock(_dispvars->vsync_cond_mutex); - } - } - - /* We mark the choosen page as used */ - slock_lock(page->page_used_mutex); - page->used = true; - slock_unlock(page->page_used_mutex); - - return page; -} - -static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) -{ - struct dispmanx_page *page = data; - struct dispmanx_surface *surface = page->surface; - - /* Marking the page as free must be done before the signaling - * so when update_main continues (it won't continue until we signal) - * we can chose this page as free */ - if (surface->current_page) - { - slock_lock(surface->current_page->page_used_mutex); - - /* We mark as free the page that was visible until now */ - surface->current_page->used = false; - slock_unlock(surface->current_page->page_used_mutex); - } - - /* The page on which we issued the flip that - * caused this callback becomes the visible one */ - surface->current_page = page; - - /* These two things must be isolated "atomically" to avoid getting - * a false positive in the pending_mutex test in update_main. */ - slock_lock(page->dispvars->pending_mutex); - - page->dispvars->pageflip_pending--; - scond_signal(page->dispvars->vsync_condition); - - slock_unlock(page->dispvars->pending_mutex); -} - static void dispmanx_surface_free(void *data, struct dispmanx_surface **sp) { int i; struct dispmanx_video *_dispvars = data; struct dispmanx_surface *surface = *sp; - /* What if we run into the vsync cb code after freeing the surface? - * We could be trying to get non-existant lock, signal non-existant condition.. - * So we wait for any pending flips to complete before freeing any surface. */ - slock_lock(_dispvars->pending_mutex); - if (_dispvars->pageflip_pending > 0) - scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex); - - slock_unlock(_dispvars->pending_mutex); - for (i = 0; i < surface->numpages; i++) { vc_dispmanx_resource_delete(surface->pages[i].resource); - surface->pages[i].used = false; - slock_free(surface->pages[i].page_used_mutex); } free(surface->pages); @@ -260,16 +166,12 @@ static void dispmanx_surface_setup(void *data, int src_width, int src_height, for (i = 0; i < surface->numpages; i++) { - surface->pages[i].used = false; surface->pages[i].surface = surface; surface->pages[i].dispvars = _dispvars; - surface->pages[i].page_used_mutex = slock_new(); } - /* No need to mutex this access to the "used" member because - * the flipping/callbacks are not still running */ - surface->next_page = &(surface->pages[0]); - surface->next_page->used = true; + /* We blit to page 0 first */ + surface->flip_page = 0; /* The "visible" width obtained from the core pitch. We blit based on * the "visible" width, for cores with things between scanlines. */ @@ -325,40 +227,24 @@ static void dispmanx_surface_update_async(void *data, const void *frame, static void dispmanx_surface_update(void *data, const void *frame, struct dispmanx_surface *surface) { - /* Updating is very delicate: we REALLY want to show the just rendered frame ASAP, - * so we dump and issue flip, and then we can wait for free pages, but we don't - * want to wait for free pages at the beggining of the update or we will be - * adding lag! */ - struct dispmanx_video *_dispvars = data; - + struct dispmanx_page *page = NULL; + + page = &surface->pages[surface->flip_page]; + /* Frame blitting */ - vc_dispmanx_resource_write_data(surface->next_page->resource, surface->pixformat, + vc_dispmanx_resource_write_data(page->resource, surface->pixformat, surface->pitch, (void*)frame, &(surface->bmp_rect)); - /* Dispmanx doesn't support more than one pending pageflip. Doing so would overwrite - * the page in the callback function, so we would be always freeing the same page. */ - slock_lock(_dispvars->pending_mutex); - if (_dispvars->pageflip_pending > 0) - scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex); - slock_unlock(_dispvars->pending_mutex); - /* Issue a page flip that will be done at the next vsync. */ _dispvars->update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_source(_dispvars->update, surface->element, - surface->next_page->resource); + page->resource); - vc_dispmanx_update_submit(_dispvars->update, - dispmanx_vsync_callback, (void*)(surface->next_page)); + vc_dispmanx_update_submit_sync(_dispvars->update); - slock_lock(_dispvars->pending_mutex); - _dispvars->pageflip_pending++; - slock_unlock(_dispvars->pending_mutex); - - /* Get the next page ready for our next surface_update re-entry. - * It's OK to wait now that we've issued the flip to the last produced frame! */ - surface->next_page = dispmanx_get_free_page(_dispvars, surface); + surface->flip_page = !surface->flip_page; } /* Enable/disable bilinear filtering. */ @@ -414,7 +300,6 @@ static void *dispmanx_gfx_init(const video_info_t *video, /* Setup surface parameters */ _dispvars->vc_image_ptr = 0; - _dispvars->pageflip_pending = 0; _dispvars->menu_active = false; _dispvars->rgb32 = video->rgb32; @@ -424,10 +309,7 @@ static void *dispmanx_gfx_init(const video_info_t *video, * before we get to gfx_frame(). */ _dispvars->aspect_ratio = video_driver_get_aspect_ratio(); - /* Initialize the rest of the mutexes and conditions. */ - _dispvars->vsync_condition = scond_new(); - _dispvars->vsync_cond_mutex = slock_new(); - _dispvars->pending_mutex = slock_new(); + /* Initialize the rest of video variables. */ _dispvars->core_width = 0; _dispvars->core_height = 0; _dispvars->menu_width = 0; @@ -695,11 +577,6 @@ static void dispmanx_gfx_free(void *data) vc_dispmanx_display_close(_dispvars->display); bcm_host_deinit(); - /* Destroy mutexes and conditions. */ - slock_free(_dispvars->pending_mutex); - slock_free(_dispvars->vsync_cond_mutex); - scond_free(_dispvars->vsync_condition); - free(_dispvars); } From 672add6cab85eb631fe5006a9069d060d8640f1e Mon Sep 17 00:00:00 2001 From: rootfather Date: Sun, 12 Feb 2017 22:32:24 +0100 Subject: [PATCH 62/90] Add some more strings to German translation --- intl/msg_hash_de.h | 89 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 602c8ea7d5..dd0c7b4150 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -2788,4 +2788,91 @@ MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_ENTRY_REMOVE, MSG_HASH(MENU_ENUM_SUBLABEL_SYSTEM_DIRECTORY, "Lege das Systemverzeichnis fest. Cores können dieses Verzeichnis verwenden, um ein BIOS, system-spezifische Konfigurationen usw. zu laden.") MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_BROWSER_DIRECTORY, - "Lege das Startverzeichnis für den Dateibrowser fest.") \ No newline at end of file + "Lege das Startverzeichnis für den Dateibrowser fest.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DIR, + "Wird normalerweise von Entwickler verwendet, die libretro/RetroArch-Apps paketieren." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_DYNAMIC_WALLPAPERS_DIRECTORY, + "Verzeichnis, in dem Hintergrundbilder gespeichert werden, die vom Menü je nach verwendetem Inhalt geladen.") +MSG_HASH(MENU_ENUM_SUBLABEL_THUMBNAILS_DIRECTORY, + "Ergänzende Miniaturansichte (Boxarts, Bildschirmfotos...) werden hier gespeichert." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_CONFIG_DIRECTORY, + "Legt das Verzeichnis fest, in dem das Menü mit der Suche nach Konfigurationen beginnt.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN, + "Eingabeverzögerung in Einzelbildern, die im Netplay verwendet wird, um die Netzwerklatenz zu verbergen. Reduziert Bildruckeln und CPU-Last, verursacht jedoch erkennbare Eingabeverzögerung.") +MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE, + "Der Bereich der Eingabeverzögerung in Einzelbildern, die im Netplay verwendet werden kann, um die Netzwerklatenz zu verbergen. Reduziert Bildruckeln und CPU-Last, verursacht jedoch unvorhersehbare Eingabeverzögerungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_DISK_CYCLE_TRAY_STATUS, + "Datenträger auswerfen/einlegen. Wenn der Datenträger eingelegt ist, wird er ausgeworfen. Wenn er noch nicht eingelegt wurde, wird er jetzt eingelegt. ") +MSG_HASH(MENU_ENUM_SUBLABEL_DISK_INDEX, + "Ändere den Datenträger-Index.") +MSG_HASH(MENU_ENUM_SUBLABEL_DISK_OPTIONS, + "Verwaltung von Datenträger-Abbildern.") +MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, + "Wähle ein Datenträger-Abbild, das eingelegt werden soll.") +MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, + "Stelle sicher, dass die Bildwiederholrate im Menü begrenzt wird.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, + "Wähle ein anderes Thema für das Menü aus. Änderungen werden übernommen, nachdem Du das Programm neu gestartet hast.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHADOWS_ENABLE, + "Aktiviere Schatten für alle Icons. Dies hat einen geringen Einfluss auf die Leistung.") +MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME, + "Wähle einen anderen Farbverlauf für das Hintergrundbild.") +MSG_HASH(MENU_ENUM_SUBLABEL_MENU_WALLPAPER_OPACITY, + "Ändere die Transparenz des Hintergrundbildes.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_MENU_COLOR_THEME, + "Wähle einen anderen Farbverlauf für das Hintergrundbild.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_RIBBON_ENABLE, + "Wähle einen animierten Effekt für das Hintergrundbild. Kann je nach Effekt GPU-lastig sein. Wenn die Leistung nicht ausreicht, wähle einen einfacheren Effekt oder deaktiviere diese Option.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_FONT, + "Wähle eine andere Schriftart, die im Menü verwendet werden soll.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_IMAGES, + "Zeige den Tab 'Bilder' im Hauptmenü an.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_MUSIC, + "Zeige den Tab 'Musik' im Hauptmenü an.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_VIDEO, + "Zeige den Tab 'Video' im Hauptmenü an.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_SETTINGS, + "Zeige den Tab 'Einstellungen' im Hauptmenü an") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_HISTORY, + "Zeige den Tab 'Verlauf' im Hauptmenü an.") +MSG_HASH(MENU_ENUM_SUBLABEL_XMB_SHOW_ADD, + "Zeige den Tab 'Inhalt importieren' im Hauptmenü an") +MSG_HASH(MENU_ENUM_SUBLABEL_RGUI_SHOW_START_SCREEN, + "Zeige einen Startbildschirm im Menü an. Wird automatisch deaktiviert, nachdem das Programm zum ersten Mal gestartet wurde.") +MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_HEADER_OPACITY, + "Ändere die Transparenz der Header-Grafik.") +MSG_HASH(MENU_ENUM_SUBLABEL_MATERIALUI_MENU_FOOTER_OPACITY, + "Ändere die Transparenz der Footer-Grafik.") +MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_ENABLE, + "Das Menü wird normalerweise automatisch skaliert. Wenn Du stattdessen eine bestimmte Skalierung wünschst, aktiviere diese Option.") +MSG_HASH(MENU_ENUM_SUBLABEL_DPI_OVERRIDE_VALUE, + "Lege hier die gewünschte Skalierung fest. HINWEIS: Du musst 'DPI-Überschreibung' aktivieren, damit diese Skalierung verwendet wird.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_ASSETS_DIRECTORY, + "Speichere alle heruntergeladenen Dateien in diesem Verzeichnis.") +MSG_HASH(MENU_ENUM_SUBLABEL_INPUT_REMAPPING_DIRECTORY, + "Speichere alle wiederzugewiesenen Tastenbelegungen in diesem Verzeichnis.") +MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_DIR_PATH, + "Verzeichnis, in dem das Programm nach Inhalten/Cores sucht.") +MSG_HASH(MENU_ENUM_SUBLABEL_LIBRETRO_INFO_PATH, + "Awendungs- und Core-Informationsdateien werden hier gespeichert.") +MSG_HASH(MENU_ENUM_SUBLABEL_JOYPAD_AUTOCONFIG_DIR, + "Wenn ein Gamepad eingesteckt wird, wird es automatisch konfiguriert, sofern eine passende Konfigurationsdatei in diesem Verzeichnis vorhanden ist.") +MSG_HASH(MENU_ENUM_SUBLABEL_PLAYLIST_DIRECTORY, + "Speichere alle Sammlungen in diesem Verzeichnis.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CACHE_DIRECTORY, + "Wenn ein Verzeichnis gewählt wird, wird Inhalt, der temporär entpackt wird (z.B. aus Archiven) in dieses Verzeichnis entpackt." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_CURSOR_DIRECTORY, + "Gespeicherte Suchanfragen werden in diesem Verzeichnis gespeichert.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CONTENT_DATABASE_DIRECTORY, + "Datenbanken werden in diesem Verzeichnis gespeichert." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, + "Dieser Ort wird standardmäßig durchsucht, wenn das Menü nach ladbaren Inhalten wie Assets sucht." + ) \ No newline at end of file From 28deb34742bbb0354055485f9b95120d9a2d0762 Mon Sep 17 00:00:00 2001 From: radius Date: Mon, 13 Feb 2017 01:24:48 -0500 Subject: [PATCH 63/90] fix #4625 --- configuration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.c b/configuration.c index 1266640cbe..b40de26d25 100644 --- a/configuration.c +++ b/configuration.c @@ -1672,7 +1672,7 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx) } if (string_is_equal("gl", settings->video.driver) || - string_is_equal("d3d9", settings->video.driver)) + string_is_equal("d3d", settings->video.driver)) { if (enum_idx == FILE_PATH_SLANGP_EXTENSION) return false; From c8f3c15cf525cf39c4e92d530f7dbc9754c6417f Mon Sep 17 00:00:00 2001 From: rootfather Date: Mon, 13 Feb 2017 13:27:40 +0100 Subject: [PATCH 64/90] Finish the rewrite of the German translation --- intl/msg_hash_de.h | 84 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index dd0c7b4150..27a3715b2a 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -120,7 +120,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Verbessert die Leistung, führt aber zu größerer Latenz und Videoproblemen. Verwende dies nur, wenn Du sonst die gewünschte Leistung nicht erreichst." + "Verbessert die Leistung, führt aber zu größerer Latenz und kann Videoprobleme verursachen. Verwende dies nur, wenn Du sonst die gewünschte Leistung nicht erreichst." ) MSG_HASH( MSG_AUDIO_VOLUME, @@ -292,7 +292,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Shader-Vorlagen automatisch laden" + "Shader-Voreinstellungen automatisch laden" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, @@ -1602,7 +1602,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PARAMETERS, MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET, "Shader-Voreinstellung laden") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_PARAMETERS, - "Shader-Parameter für Menü") + "Shader-Parameter anpassen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_AS, "Shader-Voreinstellung speichern unter...") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_SHADER_PRESET_SAVE_CORE, @@ -2442,7 +2442,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SCALE_INTEGER, - "Skaliere das Bild in ganzzahligen Schritten. Die Basisgröße hängt von der Geometrie und dem Seitenverhältnis ab, die vom System gemeldet werden. Wenn 'Seitenverhältnis erzwingen' nicht gewählt ist, werden Höhe u. Breite unabhängig skaliert." + "Skaliere das Bild in ganzzahligen Schritten. Die Basisgröße hängt von der vom System gemeldeten Geometrie und dem Seitenverhältnis ab. Wenn 'Seitenverhältnis erzwingen' nicht gewählt ist, werden Höhe u. Breite unabhängig skaliert." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_GPU_SCREENSHOT, @@ -2478,7 +2478,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO, - "Die maximale Geschwindigkeit, mit der Inhalt im Vorlauf-Modus dargestellt wird (z.B. 5x für 60 Inhalt mit 60 Bildern/sek => Begrenzung auf 300 Bilder/sek). Wenn 0x gewählt ist, ist die Vorlauf-Geschwindigkeit unbegrenzt (keine Begrenzung der Bilder/sek)." + "Die maximale Geschwindigkeit, mit der Inhalt im Vorlauf-Modus dargestellt wird (z.B. 5x für 60 Inhalt mit 60 Bildern/sek => Begrenzung auf 300 Bilder/sek). Wenn 0x gewählt ist, ist die Vorlauf-Geschwindigkeit unbegrenzt." ) MSG_HASH( MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO, @@ -2875,4 +2875,76 @@ MSG_HASH( MSG_HASH( MENU_ENUM_SUBLABEL_ASSETS_DIRECTORY, "Dieser Ort wird standardmäßig durchsucht, wenn das Menü nach ladbaren Inhalten wie Assets sucht." - ) \ No newline at end of file + ) +MSG_HASH(MENU_ENUM_SUBLABEL_SAVEFILE_DIRECTORY, + "Speichere alle Speicherdaten in diesem Verzeichnis. Wenn kein Verzeichnis festgelegt ist, wird versucht, die Datei im Arbeitsverzeichnis des Inhalts zu speichern.") +MSG_HASH(MENU_ENUM_SUBLABEL_SAVESTATE_DIRECTORY, + "Speichere alle Spielstände in diesem Verzeichnis. Wenn kein Verzeichnis festgelegt ist, wird versucht, die Datei im Arbeitsverzeichnis des Inhalts zu speichern.") +MSG_HASH(MENU_ENUM_SUBLABEL_SCREENSHOT_DIRECTORY, + "Verzeichnis, in dem alle Bildschirmfotos abgelegt werden.") +MSG_HASH(MENU_ENUM_SUBLABEL_OVERLAY_DIRECTORY, + "Verzeichnis, in dem alle Overlays abgelegt werden.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_DATABASE_PATH, + "Verzeichnis, in dem alle Cheat-Dateien gespeichert werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_AUDIO_FILTER_DIR, + "Verzeichnis, in dem alle Audio-DSP-Filter gespeichert werden." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_FILTER_DIR, + "Verzeichnis, in dem alle CPU-basierten Videofilter gespeichert werden." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_DIR, + "Verzeichnis, in dem alle GPU-basierten Videoshader gespeichert werden.") +MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_OUTPUT_DIRECTORY, + "Aufnahmen werden in diesem Verzeichnis abgelegt.") +MSG_HASH(MENU_ENUM_SUBLABEL_RECORDING_CONFIG_DIRECTORY, + "Aufnahme-Konfigurationen werden in diesem Verzeichnis abgelegt.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FONT_PATH, + "Wähle eine andere Schriftart für Bildschirm-Benachrichtigungen.") +MSG_HASH(MENU_ENUM_SUBLABEL_SHADER_APPLY_CHANGES, + "Änderungen an der Shader-Konfiguration werden sofort übernommen. Verwende diese Option, wenn Du die Anzahl der Shader-Durchläufe, die Filter, die FBO-Skalierung usw. geändert hast.") +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_SHADER_NUM_PASSES, + "Erhöhe oder verringere die Anzahl der Shader-Durchläufe. Du kannst für jeden Shader-Durchlauf einen eigenen Shader festlegen und dessen Skalierung und Filterung ändern." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET, + "Lade eine Shader-Voreinstellung. Die Shader-Pipeline wird automatisch konfiguriert.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_AS, + "Speichere die aktuellen Shader-Einstellungen als neue Shader-Voreinstellung ab.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_CORE, + "Speichere die aktuellen Shader-Einstellungen als Standard-Einstellung für diesen Core.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_SAVE_GAME, + "Speichere die aktuellen Shader-Einstellungen als Standard-Einstellung für diesen Inhalt.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PARAMETERS, + "Modifiziert den aktuellen Shader direkt. Änderungen werden nicht in den Shader-Voreinstellungen gespeichert.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SHADER_PRESET_PARAMETERS, + "Modizifiert die Shader-Voreinstellung, die momentan im Menü geladen ist.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_NUM_PASSES, + "Erhöhe oder verringere die Anzahl der Cheats." + ) +MSG_HASH(MENU_ENUM_SUBLABEL_CHEAT_APPLY_CHANGES, + "Änderungen an den Cheats werden sofort übernommen.") +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_LOAD, + "Lade eine Cheat-Datei." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_CHEAT_FILE_SAVE_AS, + "Speichere die aktuellen Cheats." /*TODO: More context*/ + ) +MSG_HASH(MENU_ENUM_SUBLABEL_CONTENT_SETTINGS, + "Greife schnell auf alle relevanten Spieleinstellungen zu.") +MSG_HASH(MENU_ENUM_SUBLABEL_CORE_INFORMATION, + "Zeige Informationen über diese Anwendung/diesen Core an.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_HEIGHT, + "Benutzerdefinierte Bildhöhe, die verwendet wird, wenn das Seitenverhältnis auf 'Benutzerdefiniert' eingestellt ist.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_WIDTH, + "Benutzerdefinierte Bildhöhe, die verwendet wird, wenn das Seitenverhältnis auf 'Benutzerdefiniert' eingestellt ist.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_X, + "Benutzerdefinierter Versatz, der für die Position der X-Achse des Bildes verwendet wird. Wird ignoriert, wenn 'Ganzzahlige Bildskalierung' aktiviert ist, das Bild wird dann zentriert.") +MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_VIEWPORT_CUSTOM_Y, + "Benutzerdefinierter Versatz, der für die Position der Y-Achse des Bildes verwendet wird. Wird ignoriert, wenn 'Ganzzahlige Bildskalierung' aktiviert ist, das Bild wird dann zentriert.") From b5c87b68f879a81cb36d6ddfa22ccb9c683c8cb3 Mon Sep 17 00:00:00 2001 From: rootfather Date: Mon, 13 Feb 2017 15:12:03 +0100 Subject: [PATCH 65/90] Claim copyright for msg_hash_de.c --- intl/msg_hash_de.c | 1 + 1 file changed, 1 insertion(+) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index fe682892d0..94d0bc03d6 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2017 - Lothar Serra Mari * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- From 31a62a63f6037f36c96797526fa162a5e2627831 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Mon, 13 Feb 2017 09:22:15 -0600 Subject: [PATCH 66/90] Remap save and load had the same word (charger) Thanks to forum user Tromzy for the heads-up! --- intl/msg_hash_fr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 5a96e29b44..8d7a773c80 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1085,9 +1085,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, "Charger un fichier de remap") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - "Charger un fichier remaps de coeur") + ""Sauvegarder un fichier remaps de coeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - "Charger un fichier remap de contenu") + ""Sauvegarder un fichier remap de contenu") MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, "Requis") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, From 6395907887dc283138372a85baa0c9d0152e0dc8 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Mon, 13 Feb 2017 15:25:56 +0000 Subject: [PATCH 67/90] Vulkan: Find supported composite alpha in swapchain. --- gfx/common/vulkan_common.c | 18 +++++++++++++----- gfx/video_shader_driver.h | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index f8db6ed7b4..5774a208ee 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1800,7 +1800,7 @@ static bool vulkan_create_display_surface(gfx_ctx_vulkan_data_t *vk, VkDisplayModePropertiesKHR *modes = NULL; unsigned dpy, i, j; uint32_t best_plane = UINT32_MAX; - VkDisplayPlaneAlphaFlagsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; + VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; VkDisplaySurfaceCreateInfoKHR create_info = { VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR }; VkDisplayModeKHR best_mode = VK_NULL_HANDLE; @@ -1937,9 +1937,7 @@ out: create_info.planeStackIndex = planes[best_plane].currentStackIndex; create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; create_info.globalAlpha = 1.0f; - /* TODO/FIXME - why is this cast needed for CXX_BUILD? Why is - * alpha_mode not just VkDisplayPlaneAlphaFlagBitsKHR to begin with? */ - create_info.alphaMode = (VkDisplayPlaneAlphaFlagBitsKHR)alpha_mode; + create_info.alphaMode = alpha_mode; create_info.imageExtent.width = *width; create_info.imageExtent.height = *height; @@ -2271,6 +2269,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; VkPresentModeKHR swapchain_present_mode = VK_PRESENT_MODE_FIFO_KHR; settings_t *settings = config_get_ptr(); + VkCompositeAlphaFlagBitsKHR composite = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; vkDeviceWaitIdle(vk->context.device); @@ -2371,6 +2370,15 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, else pre_transform = surface_properties.currentTransform; + if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) + composite = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) + composite = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; + else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) + composite = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR; + else if (surface_properties.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) + composite = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR; + old_swapchain = vk->swapchain; info.surface = vk->vk_surface; @@ -2382,7 +2390,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, info.imageArrayLayers = 1; info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; info.preTransform = pre_transform; - info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + info.compositeAlpha = composite; info.presentMode = swapchain_present_mode; info.clipped = true; info.oldSwapchain = old_swapchain; diff --git a/gfx/video_shader_driver.h b/gfx/video_shader_driver.h index ab344056b5..91060b6f06 100644 --- a/gfx/video_shader_driver.h +++ b/gfx/video_shader_driver.h @@ -27,7 +27,7 @@ #include "../config.h" #endif -#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) || defined(HAVE_SLANG) #ifndef HAVE_SHADER_MANAGER #define HAVE_SHADER_MANAGER #endif From 854fd3f1f9e4c8751eee2df0625c31eb0f15bdb2 Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Mon, 13 Feb 2017 11:33:11 -0600 Subject: [PATCH 68/90] More French fixes Courtesy of forum user Tromzy, once again. Much appreciated! --- intl/msg_hash_fr.h | 124 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 8d7a773c80..a4b09fa656 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1,14 +1,14 @@ MSG_HASH( MSG_COMPILER, - "Compiler" + "Compilateur" ) MSG_HASH( MSG_UNKNOWN_COMPILER, - "Unknown compiler" + "Compilateur inconnu" ) MSG_HASH( MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Device disconnected from port" + "Périphérique déconnecté (du port si "port X")" ) MSG_HASH( MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, @@ -40,7 +40,7 @@ MSG_HASH( ) MSG_HASH( MSG_WAITING_FOR_CLIENT, - "Waiting for client ..." + "En attente du client..." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, @@ -48,43 +48,43 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_MENU_SETTINGS, - "Adjusts settings related to the appearance of the menu screen." + "Ajuste les réglages liés à l'apparence de l'écran de menu." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Hard-synchronize the CPU and GPU. Reduces latency at the cost of performance." + "Synchronisation "hard" du CPU et du GPU. Réduit la latence au prix de la performance." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_THREADED, - "Improves performance at the cost of latency and more video stuttering. Use only if you cannot obtain full speed otherwise." + "Améliore les performances au prix d'une certaine latence et d'à-coups visuels accrus. À n'utiliser que si vous ne pouvez pas faire autrement." ) MSG_HASH( MSG_AUDIO_VOLUME, - "Audio volume" + "Volume sonore" ) MSG_HASH( MSG_AUTODETECT, - "Autodetect" + "Détection automatique" ) MSG_HASH( MSG_AUTOLOADING_SAVESTATE_FROM, - "Auto-loading savestate from" + "Chargement auto d'une savestate depuis" ) MSG_HASH( MSG_CAPABILITIES, - "Capabilities" + "Capacités" ) MSG_HASH( MSG_CONNECTING_TO_NETPLAY_HOST, - "Connecting to netplay host" + "Connexion à l'hôte" ) MSG_HASH( MSG_CONNECTING_TO_PORT, - "Connecting to port" + "Connexion au port" ) MSG_HASH( MSG_CONNECTION_SLOT, - "Connection slot" + "Slot de connexion" ) MSG_HASH( MSG_SORRY_UNIMPLEMENTED_CORES_DONT_DEMAND_CONTENT_NETPLAY, @@ -92,7 +92,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_PASSWORD, - "Password" + "Mot de passe" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_SETTINGS, @@ -100,7 +100,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_CHEEVOS_USERNAME, - "Username" + "Nom d'utilisateur" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_LIST, @@ -112,16 +112,16 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements" + "Succès Retro" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, - "Achievement List" + "Liste des Succès" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST_HARDCORE, - "Achievement List (Hardcore)" + "Liste des Succès (hardcore)" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ADD_CONTENT_LIST, @@ -209,11 +209,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUDIO_VOLUME, - "Volume sonnore (dB)" + "Volume sonore (dB)" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTOSAVE_INTERVAL, - "Intervale de sauvegarde SaveRAM" + "Intervalle de sauvegarde SaveRAM" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE, @@ -225,63 +225,63 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_AUTO_SHADERS_ENABLE, - "Load Shader Presets Automatically" + "Charger les pré-réglages de shaders automatiquement" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK, - "Back" + "Retour" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_CONFIRM, - "Confirm" + "Confirmer" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_INFO, - "Info" + "Information" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_QUIT, - "Quit" + "Quitter" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_DOWN, - "Scroll Down" + "Défilement vers le bas" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_SCROLL_UP, - "Scroll Up" + "Défilement vers le haut" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_START, - "Start" + "Démarrer" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_KEYBOARD, - "Toggle Keyboard" + "Basculer sur le Clavier" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_TOGGLE_MENU, - "Toggle Menu" + "Basculer sur le Menu" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS, - "Basic menu controls" + "Contrôles du menu basiques" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_CONFIRM, - "Confirm/OK" + "Confirmer / OK" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_INFO, - "Info" + "Information" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_QUIT, - "Quit" + "Quitter" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_SCROLL_UP, - "Scroll Up" + "Défilement vers le haut" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_START, @@ -289,11 +289,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_KEYBOARD, - "Toggle Keyboard" + "Basculer sur le Klavier" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BASIC_MENU_ENUM_CONTROLS_TOGGLE_MENU, - "Toggle Menu" + "Basculer sur le Menu" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BLOCK_SRAM_OVERWRITE, @@ -301,7 +301,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BLUETOOTH_ENABLE, - "Bluetooth Enable" + "Activer le Bluetooth" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, @@ -333,15 +333,15 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE, - "Cheat File" + "Fichier de Triche" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE_LOAD, - "Load Cheat File" + "Charger un fichier de Triche" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_FILE_SAVE_AS, - "Save Cheat File As" + "Enregistrer le fichier de Triche sous" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEAT_NUM_PASSES, @@ -353,19 +353,19 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, - "Achievements Hardcore Mode" + "Mode Hardcore des Succès" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, - "Locked Achievements:" + "Succès verrouillés:" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY, - "Locked" + "Verrouillé" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "Retro Achievements" + "Succès Retro" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, @@ -373,11 +373,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, - "Unlocked Achievements:" + "Succès déverrouillés:" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, - "Unlocked" + "Déverrouillé" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, @@ -385,11 +385,11 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIG, - "Config" + "Configuration" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIGURATIONS, - "Load Configuration" + "Charger la configuration" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONFIGURATION_SETTINGS, @@ -405,7 +405,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_DATABASE_DIRECTORY, "Dossier des bases de données de contenus") MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_DIR, - "Content" + "Contenu" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CONTENT_HISTORY_SIZE, @@ -413,13 +413,13 @@ MSG_HASH( MSG_HASH(MENU_ENUM_LABEL_VALUE_CONTENT_SETTINGS, "Menu rapide") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIR, - "Core Assets") + "Assets de Coeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ASSETS_DIRECTORY, "Dossier des téléchargements") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_CHEAT_OPTIONS, "Triche") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_COUNTERS, - "Core Counters") + "Compteurs de Cores") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_ENABLE, "Afficher le coeur actuel") MSG_HASH(MENU_ENUM_LABEL_VALUE_CORE_INFORMATION, @@ -477,9 +477,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_CUSTOM_RATIO, MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_MANAGER, "Gestion de la base de données") MSG_HASH(MENU_ENUM_LABEL_VALUE_DATABASE_SELECTION, - "Database Selection") + "Sélection de la base de données") MSG_HASH(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY, - "Remove") + "Supprimer") MSG_HASH(MENU_ENUM_LABEL_VALUE_FAVORITES, "Via les fichiers") /* TODO/FIXME - update */ MSG_HASH(MENU_ENUM_LABEL_VALUE_DIRECTORY_CONTENT, @@ -521,7 +521,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPER, MSG_HASH(MENU_ENUM_LABEL_VALUE_DYNAMIC_WALLPAPERS_DIRECTORY, "Dossier des fonds d'écran dynamiques") MSG_HASH(MENU_ENUM_LABEL_VALUE_CHEEVOS_ENABLE, - "Enable Achievements") + "Activer les Succès") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_HOVER_COLOR, "Couleur de l'entrée active") MSG_HASH(MENU_ENUM_LABEL_VALUE_ENTRY_NORMAL_COLOR, @@ -531,7 +531,7 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_FALSE, MSG_HASH(MENU_ENUM_LABEL_VALUE_FASTFORWARD_RATIO, "Vitesse de l'avance rapide") MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, - "Afficher le FPS") + "Afficher les i/s") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, "Limiter la vitesse d'exécution") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, @@ -539,17 +539,17 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, "Compteurs du Frontend") MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS, - "Options du coeur par-jeu") + "Options du coeur par jeu") MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_CREATE, - "Create game-options file") + "Créer un fichier d'options par jeu") MSG_HASH(MENU_ENUM_LABEL_VALUE_GAME_SPECIFIC_OPTIONS_IN_USE, - "Game-options file") + "Fichier d'option par jeu") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP, "Aide") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING, - "Audio/Video Troubleshooting") + "Dépannage audio / vidéo") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CHANGE_VIRTUAL_GAMEPAD, - "Changing Virtual Gamepad Overlay") + "Modifier l'overlay de la manette virtuelle") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_CONTROLS, "Basic Menu Controls") MSG_HASH(MENU_ENUM_LABEL_VALUE_HELP_LIST, From 04904c5c9effa2485e90b7c87c1bf9cf81d2c5ee Mon Sep 17 00:00:00 2001 From: hizzlekizzle Date: Mon, 13 Feb 2017 11:48:43 -0600 Subject: [PATCH 69/90] whoops, double-quotes typoed in. --- intl/msg_hash_fr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 0b4f7cd785..103dd51d5e 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1083,9 +1083,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_RECORD_USE_OUTPUT_DIRECTORY, MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_LOAD, "Charger un fichier de remap") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_CORE, - ""Sauvegarder un fichier remaps de coeur") + "Sauvegarder un fichier remaps de coeur") MSG_HASH(MENU_ENUM_LABEL_VALUE_REMAP_FILE_SAVE_GAME, - ""Sauvegarder un fichier remap de contenu") + "Sauvegarder un fichier remap de contenu") MSG_HASH(MENU_ENUM_LABEL_VALUE_REQUIRED, "Requis") MSG_HASH(MENU_ENUM_LABEL_VALUE_RESTART_CONTENT, From 07881d9f4f8f33a626230e8c2c069edb11c5e536 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 13 Feb 2017 19:11:32 +0100 Subject: [PATCH 70/90] Buildfix --- intl/msg_hash_fr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 1d7207d894..14d1eb088a 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -8,7 +8,7 @@ MSG_HASH( ) MSG_HASH( MSG_DEVICE_DISCONNECTED_FROM_PORT, - "Périphérique déconnecté (du port si "port X")" + "Périphérique déconnecté (du port si 'port X')" ) MSG_HASH( MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED, @@ -52,7 +52,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC, - "Synchronisation "hard" du CPU et du GPU. Réduit la latence au prix de la performance." + "Synchronisation 'hard' du CPU et du GPU. Réduit la latence au prix de la performance." ) MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_THREADED, From 0143b537a864271068dd43cb058d43c53db743fe Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 13 Feb 2017 20:24:27 +0100 Subject: [PATCH 71/90] Avoid warnings --- cheevos/cheevos.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index b1e64f1f13..979a78a878 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1360,6 +1360,7 @@ static int cheevos_parse_condition(cheevos_condition_t *condition, const char* m return 0; } +#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_free_condition(cheevos_condition_t* condition) { unsigned i; @@ -1374,11 +1375,13 @@ static void cheevos_free_condition(cheevos_condition_t* condition) free((void*)condition->condsets); } } +#endif /***************************************************************************** Parse the Mem field of leaderboards. *****************************************************************************/ +#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem) { const char* aux; @@ -1412,7 +1415,9 @@ static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem) return 0; } +#endif +#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem) { lb->start.condsets = NULL; @@ -1464,6 +1469,7 @@ error: free((void*)lb->value.terms); return -1; } +#endif /***************************************************************************** Load achievements from a JSON string. @@ -1526,6 +1532,7 @@ error: return -1; } +#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_new_lboard(cheevos_readud_t *ud) { cheevos_leaderboard_t *lboard = cheevos_locals.leaderboards + ud->lboard_count++; @@ -1551,6 +1558,7 @@ error: free((void*)lboard->description); return -1; } +#endif static int cheevos_read__json_key( void *userdata, const char *name, size_t length) @@ -2211,6 +2219,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) } } +#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_test_lboard_condition(const cheevos_condition_t* condition) { int dirty_conds = 0; @@ -2290,7 +2299,9 @@ static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, cheevos_log_url("CHEEVOS url to submit the leaderboard: %s\n", url); #endif } +#endif +#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_lboard_submit(void *task_data, void *user_data, const char *error) { cheevos_leaderboard_t *lboard = (cheevos_leaderboard_t *)user_data; @@ -2313,7 +2324,9 @@ static void cheevos_lboard_submit(void *task_data, void *user_data, const char * } #endif } +#endif +#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_test_leaderboards(void) { cheevos_leaderboard_t* lboard = cheevos_locals.leaderboards; @@ -2360,6 +2373,7 @@ static void cheevos_test_leaderboards(void) } } } +#endif /***************************************************************************** Free the loaded achievements. From 6e969d0bc6e86f54368f5a26b80667e3473dea40 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 13 Feb 2017 15:12:04 -0500 Subject: [PATCH 72/90] should be !string_is_equal --- tasks/task_autodetect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index be79f38c95..fd593df1ea 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -124,8 +124,8 @@ static int input_autoconfigure_joypad_try_from_conf(config_file_t *conf, score += 2; else { - if ( !string_is_empty(ident) - && string_is_equal(params->name, ident)) + if ( !string_is_empty(ident) + && !string_is_equal(params->name, ident)) score += 1; } From 91ebcc068079d916ed883dd244b6886c2884477c Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 13 Feb 2017 15:37:34 -0500 Subject: [PATCH 73/90] revert 6e969d0, but need to investigate if the original change to string_is_equal is valid --- tasks/task_autodetect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index fd593df1ea..be79f38c95 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -124,8 +124,8 @@ static int input_autoconfigure_joypad_try_from_conf(config_file_t *conf, score += 2; else { - if ( !string_is_empty(ident) - && !string_is_equal(params->name, ident)) + if ( !string_is_empty(ident) + && string_is_equal(params->name, ident)) score += 1; } From 6659c6af3a30017d33fe9efd8fa18895e7544442 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Mon, 13 Feb 2017 21:52:53 +0000 Subject: [PATCH 74/90] Fix dualshock 3 detection bug --- tasks/task_autodetect.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index be79f38c95..cbbb43d5b8 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -124,8 +124,7 @@ static int input_autoconfigure_joypad_try_from_conf(config_file_t *conf, score += 2; else { - if ( !string_is_empty(ident) - && string_is_equal(params->name, ident)) + if (strstr(params->name, ident)) score += 1; } From 6d821132f5ea75c9655b0676ae97f71337dabff2 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 14 Feb 2017 02:37:25 +0000 Subject: [PATCH 75/90] msvc buildfix --- network/netplay/netplay_frontend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index eddf830df9..f999053822 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -32,7 +32,7 @@ #include "../../tasks/tasks_internal.h" #include #include "../../file_path_special.h" -#include "paths.h" +#include "../../paths.h" /* Only used before init_netplay */ static bool netplay_enabled = false; From 8aa8d6ff6b01c995ef96e7bfd942d40385a9818d Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 14 Feb 2017 02:39:26 +0000 Subject: [PATCH 76/90] MSVC2005: add winmm.lib to linker, needed by rthreads changes in f4c187e --- pkg/msvc/msvc-2005/RetroArch-msvc2005.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/msvc/msvc-2005/RetroArch-msvc2005.vcproj b/pkg/msvc/msvc-2005/RetroArch-msvc2005.vcproj index 159f0092a5..0098e65435 100644 --- a/pkg/msvc/msvc-2005/RetroArch-msvc2005.vcproj +++ b/pkg/msvc/msvc-2005/RetroArch-msvc2005.vcproj @@ -139,7 +139,7 @@ /> Date: Tue, 14 Feb 2017 11:04:21 -0500 Subject: [PATCH 77/90] add 9-slice texture draw function and selectable texture filter type --- menu/drivers/materialui.c | 2 +- menu/drivers/xmb.c | 2 +- menu/menu_display.c | 281 +++++++++++++++++++++++++++++++++++++- menu/menu_display.h | 5 +- 4 files changed, 284 insertions(+), 6 deletions(-) diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 4824c06f4c..d414a3fb8f 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -184,7 +184,7 @@ static void mui_context_reset_textures(mui_handle_t *mui) APPLICATION_SPECIAL_DIRECTORY_ASSETS_MATERIALUI_ICONS); for (i = 0; i < MUI_TEXTURE_LAST; i++) - menu_display_reset_textures_list(mui_texture_path(i), iconpath, &mui->textures.list[i]); + menu_display_reset_textures_list(mui_texture_path(i), iconpath, &mui->textures.list[i], TEXTURE_FILTER_MIPMAP_LINEAR); } static void mui_draw_icon( diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 25bdee0e3f..c4c01c986b 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -3467,7 +3467,7 @@ static void xmb_context_reset_textures( unsigned i; for (i = 0; i < XMB_TEXTURE_LAST; i++) - menu_display_reset_textures_list(xmb_texture_path(i), iconpath, &xmb->textures.list[i]); + menu_display_reset_textures_list(xmb_texture_path(i), iconpath, &xmb->textures.list[i], TEXTURE_FILTER_MIPMAP_LINEAR); menu_display_allocate_white_texture(); diff --git a/menu/menu_display.c b/menu/menu_display.c index 4e6c76e593..dc65ac645a 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -500,7 +500,7 @@ void menu_display_draw_pipeline(menu_display_ctx_draw_t *draw) menu_disp->draw_pipeline(draw); } -void menu_display_draw_bg(menu_display_ctx_draw_t *draw, +void menu_display_draw_bg(menu_display_ctx_draw_t *draw, video_frame_info_t *video_info, bool add_opacity_to_wallpaper) { static struct video_coords coords; @@ -611,6 +611,281 @@ void menu_display_draw_texture( menu_display_draw(&draw); } +/* Draw the texture split into 9 sections, without scaling the corners. + * The middle sections will only scale in the X axis, and the side + * sections will only scale in the Y axis. */ +void menu_display_draw_texture_slice( + int x, int y, unsigned w, unsigned h, + unsigned new_w, unsigned new_h, + unsigned width, unsigned height, + float *color, unsigned offset, float scale_factor, uintptr_t texture) +{ + menu_display_ctx_draw_t draw; + menu_display_ctx_rotate_draw_t rotate_draw; + struct video_coords coords; + math_matrix_4x4 mymat; + unsigned i; + + /* need space for the coordinates of two triangles in a strip, so 8 vertices */ + float *tex_coord = (float*)malloc(8 * sizeof(float)); + float *vert_coord = (float*)malloc(8 * sizeof(float)); + float *colors = (float*)malloc(16 * sizeof(float)); + + /* normalized width/height of the amount to offset from the corners, + * for both the vertex and texture coordinates */ + float vert_woff = (offset * scale_factor) / (float)width; + float vert_hoff = (offset * scale_factor) / (float)height; + float tex_woff = offset / (float)w; + float tex_hoff = offset / (float)h; + + /* the width/height of the middle sections of both the scaled and original image */ + float vert_scaled_mid_width = (new_w - (offset * scale_factor * 2)) / (float)width; + float vert_scaled_mid_height = (new_h - (offset * scale_factor * 2)) / (float)height; + float tex_mid_width = (w - (offset * 2)) / (float)w; + float tex_mid_height = (h - (offset * 2)) / (float)h; + + /* normalized coordinates for the start position of the image */ + float norm_x = x / (float)width; + float norm_y = (height - y) / (float)height; + + /* the four vertices of the top-left corner of the image, + * used as a starting point for all the other sections */ + float V_BL[2] = {norm_x, norm_y}; + float V_BR[2] = {norm_x + vert_woff, norm_y}; + float V_TL[2] = {norm_x, norm_y + vert_hoff}; + float V_TR[2] = {norm_x + vert_woff, norm_y + vert_hoff}; + float T_BL[2] = {0.0f, tex_hoff}; + float T_BR[2] = {tex_woff, tex_hoff}; + float T_TL[2] = {0.0f, 0.0f}; + float T_TR[2] = {tex_woff, 0.0f}; + + for (i = 0; i < (16 * sizeof(float)) / sizeof(colors[0]); i++) + colors[i] = 1.0f; + + rotate_draw.matrix = &mymat; + rotate_draw.rotation = 0.0; + rotate_draw.scale_x = 1.0; + rotate_draw.scale_y = 1.0; + rotate_draw.scale_z = 1; + rotate_draw.scale_enable = true; + coords.vertices = 4; + coords.vertex = vert_coord; + coords.tex_coord = tex_coord; + coords.lut_tex_coord = NULL; + draw.width = width; + draw.height = height; + draw.coords = &coords; + draw.matrix_data = &mymat; + draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; + draw.pipeline.id = 0; + coords.color = (const float*)colors; + + menu_display_rotate_z(&rotate_draw); + + draw.texture = texture; + draw.x = 0; + draw.y = 0; + + /* vertex coords are specfied bottom-up in this order: BL BR TL TR */ + /* texture coords are specfied top-down in this order: BL BR TL TR */ + + /* If someone wants to change this to not draw several times, the + * coordinates will need to be modified because of the triangle strip usage. */ + + /* top-left corner */ + vert_coord[0] = V_BL[0]; + vert_coord[1] = V_BL[1]; + vert_coord[2] = V_BR[0]; + vert_coord[3] = V_BR[1]; + vert_coord[4] = V_TL[0]; + vert_coord[5] = V_TL[1]; + vert_coord[6] = V_TR[0]; + vert_coord[7] = V_TR[1]; + + tex_coord[0] = T_BL[0]; + tex_coord[1] = T_BL[1]; + tex_coord[2] = T_BR[0]; + tex_coord[3] = T_BR[1]; + tex_coord[4] = T_TL[0]; + tex_coord[5] = T_TL[1]; + tex_coord[6] = T_TR[0]; + tex_coord[7] = T_TR[1]; + + menu_display_draw(&draw); + + /* top-middle section */ + vert_coord[0] = V_BL[0] + vert_woff; + vert_coord[1] = V_BL[1]; + vert_coord[2] = V_BR[0] + vert_scaled_mid_width; + vert_coord[3] = V_BR[1]; + vert_coord[4] = V_TL[0] + vert_woff; + vert_coord[5] = V_TL[1]; + vert_coord[6] = V_TR[0] + vert_scaled_mid_width; + vert_coord[7] = V_TR[1]; + + tex_coord[0] = T_BL[0] + tex_woff; + tex_coord[1] = T_BL[1]; + tex_coord[2] = T_BR[0] + tex_mid_width; + tex_coord[3] = T_BR[1]; + tex_coord[4] = T_TL[0] + tex_woff; + tex_coord[5] = T_TL[1]; + tex_coord[6] = T_TR[0] + tex_mid_width; + tex_coord[7] = T_TR[1]; + + menu_display_draw(&draw); + + /* top-right corner */ + vert_coord[0] = V_BL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[1] = V_BL[1]; + vert_coord[2] = V_BR[0] + vert_scaled_mid_width + vert_woff; + vert_coord[3] = V_BR[1]; + vert_coord[4] = V_TL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[5] = V_TL[1]; + vert_coord[6] = V_TR[0] + vert_scaled_mid_width + vert_woff; + vert_coord[7] = V_TR[1]; + + tex_coord[0] = T_BL[0] + tex_woff + tex_mid_width; + tex_coord[1] = T_BL[1]; + tex_coord[2] = T_BR[0] + tex_mid_width + tex_woff; + tex_coord[3] = T_BR[1]; + tex_coord[4] = T_TL[0] + tex_woff + tex_mid_width; + tex_coord[5] = T_TL[1]; + tex_coord[6] = T_TR[0] + tex_mid_width + tex_woff; + tex_coord[7] = T_TR[1]; + + menu_display_draw(&draw); + + /* middle-left section */ + vert_coord[0] = V_BL[0]; + vert_coord[1] = V_BL[1] - vert_scaled_mid_height; + vert_coord[2] = V_BR[0]; + vert_coord[3] = V_BR[1] - vert_scaled_mid_height; + vert_coord[4] = V_TL[0]; + vert_coord[5] = V_TL[1] - vert_hoff; + vert_coord[6] = V_TR[0]; + vert_coord[7] = V_TR[1] - vert_hoff; + + tex_coord[0] = T_BL[0]; + tex_coord[1] = T_BL[1] + tex_mid_height; + tex_coord[2] = T_BR[0]; + tex_coord[3] = T_BR[1] + tex_mid_height; + tex_coord[4] = T_TL[0]; + tex_coord[5] = T_TL[1] + tex_hoff; + tex_coord[6] = T_TR[0]; + tex_coord[7] = T_TR[1] + tex_hoff; + + menu_display_draw(&draw); + + /* center section */ + vert_coord[0] = V_BL[0] + vert_woff; + vert_coord[1] = V_BL[1] - vert_scaled_mid_height; + vert_coord[2] = V_BR[0] + vert_scaled_mid_width; + vert_coord[3] = V_BR[1] - vert_scaled_mid_height; + vert_coord[4] = V_TL[0] + vert_woff; + vert_coord[5] = V_TL[1] - vert_hoff; + vert_coord[6] = V_TR[0] + vert_scaled_mid_width; + vert_coord[7] = V_TR[1] - vert_hoff; + + tex_coord[0] = T_BL[0] + tex_woff; + tex_coord[1] = T_BL[1] + tex_mid_height; + tex_coord[2] = T_BR[0] + tex_mid_width; + tex_coord[3] = T_BR[1] + tex_mid_height; + tex_coord[4] = T_TL[0] + tex_woff; + tex_coord[5] = T_TL[1] + tex_hoff; + tex_coord[6] = T_TR[0] + tex_mid_width; + tex_coord[7] = T_TR[1] + tex_hoff; + + menu_display_draw(&draw); + + /* middle-right section */ + vert_coord[0] = V_BL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[1] = V_BL[1] - vert_scaled_mid_height; + vert_coord[2] = V_BR[0] + vert_woff + vert_scaled_mid_width; + vert_coord[3] = V_BR[1] - vert_scaled_mid_height; + vert_coord[4] = V_TL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[5] = V_TL[1] - vert_hoff; + vert_coord[6] = V_TR[0] + vert_woff + vert_scaled_mid_width; + vert_coord[7] = V_TR[1] - vert_hoff; + + tex_coord[0] = T_BL[0] + tex_woff + tex_mid_width; + tex_coord[1] = T_BL[1] + tex_mid_height; + tex_coord[2] = T_BR[0] + tex_woff + tex_mid_width; + tex_coord[3] = T_BR[1] + tex_mid_height; + tex_coord[4] = T_TL[0] + tex_woff + tex_mid_width; + tex_coord[5] = T_TL[1] + tex_hoff; + tex_coord[6] = T_TR[0] + tex_woff + tex_mid_width; + tex_coord[7] = T_TR[1] + tex_hoff; + + menu_display_draw(&draw); + + /* bottom-left corner */ + vert_coord[0] = V_BL[0]; + vert_coord[1] = V_BL[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[2] = V_BR[0]; + vert_coord[3] = V_BR[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[4] = V_TL[0]; + vert_coord[5] = V_TL[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[6] = V_TR[0]; + vert_coord[7] = V_TR[1] - vert_hoff - vert_scaled_mid_height; + + tex_coord[0] = T_BL[0]; + tex_coord[1] = T_BL[1] + tex_hoff + tex_mid_height; + tex_coord[2] = T_BR[0]; + tex_coord[3] = T_BR[1] + tex_hoff + tex_mid_height; + tex_coord[4] = T_TL[0]; + tex_coord[5] = T_TL[1] + tex_hoff + tex_mid_height; + tex_coord[6] = T_TR[0]; + tex_coord[7] = T_TR[1] + tex_hoff + tex_mid_height; + + menu_display_draw(&draw); + + /* bottom-middle section */ + vert_coord[0] = V_BL[0] + vert_woff; + vert_coord[1] = V_BL[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[2] = V_BR[0] + vert_scaled_mid_width; + vert_coord[3] = V_BR[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[4] = V_TL[0] + vert_woff; + vert_coord[5] = V_TL[1] - vert_scaled_mid_height; + vert_coord[6] = V_TR[0] + vert_scaled_mid_width; + vert_coord[7] = V_TR[1] - vert_scaled_mid_height; + + tex_coord[0] = T_BL[0] + tex_woff; + tex_coord[1] = T_BL[1] + tex_hoff + tex_mid_height; + tex_coord[2] = T_BR[0] + tex_mid_width; + tex_coord[3] = T_BR[1] + tex_hoff + tex_mid_height; + tex_coord[4] = T_TL[0] + tex_woff; + tex_coord[5] = T_TL[1] + tex_mid_height; + tex_coord[6] = T_TR[0] + tex_mid_width; + tex_coord[7] = T_TR[1] + tex_mid_height; + + menu_display_draw(&draw); + + /* bottom-right corner */ + vert_coord[0] = V_BL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[1] = V_BL[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[2] = V_BR[0] + vert_scaled_mid_width + vert_woff; + vert_coord[3] = V_BR[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[4] = V_TL[0] + vert_woff + vert_scaled_mid_width; + vert_coord[5] = V_TL[1] - vert_hoff - vert_scaled_mid_height; + vert_coord[6] = V_TR[0] + vert_scaled_mid_width + vert_woff; + vert_coord[7] = V_TR[1] - vert_hoff - vert_scaled_mid_height; + + tex_coord[0] = T_BL[0] + tex_woff + tex_mid_width; + tex_coord[1] = T_BL[1] + tex_hoff + tex_mid_height; + tex_coord[2] = T_BR[0] + tex_woff + tex_mid_width; + tex_coord[3] = T_BR[1] + tex_hoff + tex_mid_height; + tex_coord[4] = T_TL[0] + tex_woff + tex_mid_width; + tex_coord[5] = T_TL[1] + tex_hoff + tex_mid_height; + tex_coord[6] = T_TR[0] + tex_woff + tex_mid_width; + tex_coord[7] = T_TR[1] + tex_hoff + tex_mid_height; + + menu_display_draw(&draw); + + free(colors); + free(vert_coord); + free(tex_coord); +} + void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw) { #if !defined(VITA) @@ -907,7 +1182,7 @@ void menu_display_set_alpha(float *color, float alpha_value) } void menu_display_reset_textures_list(const char *texture_path, const char *iconpath, - uintptr_t *item) + uintptr_t *item, enum texture_filter_type filter_type) { struct texture_image ti; char path[PATH_MAX_LENGTH]; @@ -929,6 +1204,6 @@ void menu_display_reset_textures_list(const char *texture_path, const char *icon return; video_driver_texture_load(&ti, - TEXTURE_FILTER_MIPMAP_LINEAR, item); + filter_type, item); image_texture_free(&ti); } diff --git a/menu/menu_display.h b/menu/menu_display.h index 99a6834189..c3c8104dec 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -256,6 +256,9 @@ void menu_display_draw_quad(int x, int y, unsigned w, unsigned h, void menu_display_draw_texture(int x, int y, unsigned w, unsigned h, unsigned width, unsigned height, float *color, uintptr_t texture); +void menu_display_draw_texture_slice(int x, int y, unsigned w, unsigned h, + unsigned new_w, unsigned new_h, unsigned width, unsigned height, + float *color, unsigned offset, float scale_factor, uintptr_t texture); void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw); bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw); @@ -294,7 +297,7 @@ void menu_display_set_alpha(float *color, float alpha_value); font_data_t *menu_display_font(enum application_special_type type, float font_size); void menu_display_reset_textures_list(const char *texture_path, const char *iconpath, - uintptr_t *item); + uintptr_t *item, enum texture_filter_type filter_type); extern uintptr_t menu_display_white_texture; From d8e38bedf0f814fdfa4748ea3e5dce7808c4e76a Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 14 Feb 2017 13:50:42 -0500 Subject: [PATCH 78/90] fix heap corruption in core info extension list --- core_info.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core_info.c b/core_info.c index b9cde94b77..1d91ecd444 100644 --- a/core_info.c +++ b/core_info.c @@ -59,6 +59,8 @@ static void core_info_list_resolve_all_extensions( (strlen(core_info_list->list[i].supported_extensions) + 2); } + all_ext_len += strlen("7z|") + strlen("zip|"); + if (all_ext_len) all_ext = (char*)calloc(1, all_ext_len); @@ -77,10 +79,10 @@ static void core_info_list_resolve_all_extensions( strlcat(core_info_list->all_ext, "|", all_ext_len); } #ifdef HAVE_7ZIP - strlcat(core_info_list->all_ext, "7z|", all_ext_len + 3); + strlcat(core_info_list->all_ext, "7z|", all_ext_len); #endif #ifdef HAVE_ZLIB - strlcat(core_info_list->all_ext, "zip|", all_ext_len + 4); + strlcat(core_info_list->all_ext, "zip|", all_ext_len); #endif } From 4f039cac22a1cbb5ed593baea7621f618a665c5c Mon Sep 17 00:00:00 2001 From: Diablodiab Date: Tue, 14 Feb 2017 22:34:46 +0100 Subject: [PATCH 79/90] This adds external mouse support to the Android input driver. It also adds support for using the touch screen as mouse in cores with mouse support (eg. ScummVM). It has been tested with the ScummVM core on: - NVIDIA Shield TV running Android Nougat 7.0 - NVIDIA Shield Tablet running Android Nougat 7.0 - NVIDIA Shield Tablet running Android Lollipop 5.1 - Huawei Honor 7 running Android Marshmallow 6.0 - HTC Desire 500 running Android Jelly Bean 4.1 It's been tested using the touch screen, a USB mouse/keyboard combo, and a bluetooth mouse. The Android version running on the device limits the functionality and user experience of the external mouse support. Android Nougat and/or an NVIDIA SHIELD device with NVIDIA extensions provides the best user experience: Android API < 14: - Only left mouse button supported - The Android mouse cursor will be visible along with the in game mouse cursor - When the Android mouse cursor hits the edge of the screen it will not be possible to move the in-game mouse cursor further in that direction Android API < 24 and no NVIDIA extensions available: - Both left and right mouse buttons supported - The Android mouse cursor will be visible along with the in game mouse cursor - When the Android mouse cursor hits the edge of the screen it will not be possible to move the in-game mouse cursor further in that direction Android API > 23 and/or NVIDIA extensions available (SHIELD devices): - Both left and right mouse buttons supported - The Android mouse cursor will be hidden - The mouse is not limited by the (hidden) Android mouse cursor hitting the edge of the screen Description of how the the touchscreen mouse support works: - You can move the in-game mouse cursor using the touch screen. The in-game mouse cursor will move relative to your movements on the touch screen, it will not be centered on where you press the screen. - One quick tap on the touch screen results in the left mouse button being clicked - Two taps on the screen and keeping the second tap pressed down results in a left mouse being held down until you release - Two fingers on the touch screen results in the right mouse button being clicked The touch screen mouse functionality is active at the same time as overlay support. This might cause some confusion when using cores that are designed for mouse support but where you have also enabled overlay controls. At the top of android_input.c there's a define that can be used to turn off this functionality if it causes more problems than it solves. --- input/drivers/android_input.c | 158 ++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index d93e53daf4..54e763c4bc 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -47,6 +47,26 @@ #define MAX_TOUCH 16 #define MAX_NUM_KEYBOARDS 3 +// If using an SDK lower than 14 then add missing mouse button codes +#if __ANDROID_API__ < 14 +enum { + AMOTION_EVENT_BUTTON_PRIMARY = 1 << 0, + AMOTION_EVENT_BUTTON_SECONDARY = 1 << 1, + AMOTION_EVENT_BUTTON_TERTIARY = 1 << 2, + AMOTION_EVENT_BUTTON_BACK = 1 << 3, + AMOTION_EVENT_BUTTON_FORWARD = 1 << 4, +}; +#endif + +// If using an SDK lower than 24 then add missing relative axis codes +#if __ANDROID_API__ < 24 +#define AMOTION_EVENT_AXIS_RELATIVE_X 27 +#define AMOTION_EVENT_AXIS_RELATIVE_Y 28 +#endif + +// Use this to enable/disable using the touch screen as mouse +#define ENABLE_TOUCH_SCREEN_MOUSE 1 + typedef struct { float x; @@ -96,6 +116,10 @@ typedef struct android_input_data sensor_t accelerometer_state; struct input_pointer pointer[MAX_TOUCH]; unsigned pointer_count; + int mouse_x_delta, mouse_y_delta; + int mouse_x_prev, mouse_y_prev; + int mouse_l, mouse_r; + int64_t quick_tap_time; } android_input_data_t; typedef struct android_input @@ -123,6 +147,12 @@ static typeof(AMotionEvent_getAxisValue) *p_AMotionEvent_getAxisValue; #define AMotionEvent_getAxisValue (*p_AMotionEvent_getAxisValue) +extern int32_t AMotionEvent_getButtonState(const AInputEvent* motion_event); + +static typeof(AMotionEvent_getButtonState) *p_AMotionEvent_getButtonState; + +#define AMotionEvent_getButtonState (*p_AMotionEvent_getButtonState) + static void *libandroid_handle; static bool android_input_lookup_name_prekitkat(char *buf, @@ -452,6 +482,9 @@ static bool android_input_init_handle(void) RARCH_LOG("Set engine_handle_dpad to 'Get Axis Value' (for reading extra analog sticks)"); engine_handle_dpad = engine_handle_dpad_getaxisvalue; } + + p_AMotionEvent_getButtonState = dlsym(RTLD_DEFAULT,"AMotionEvent_getButtonState"); + pad_id1 = -1; pad_id2 = -1; @@ -470,6 +503,8 @@ static void *android_input_init(const char *joypad_driver) android->thread.pads_connected = 0; android->copy.pads_connected = 0; + android->thread.quick_tap_time = 0; + android->copy.quick_tap_time = 0; android->joypad = input_joypad_init_driver(joypad_driver, android); input_keymaps_init_keyboard_lut(rarch_key_map_android); @@ -495,6 +530,59 @@ static void *android_input_init(const char *joypad_driver) return android; } +static int16_t android_mouse_state(android_input_data_t *android_data, unsigned id) +{ + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_LEFT: + return android_data->mouse_l; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return android_data->mouse_r; + case RETRO_DEVICE_ID_MOUSE_X: + return android_data->mouse_x_delta; + case RETRO_DEVICE_ID_MOUSE_Y: + return android_data->mouse_y_delta; + } + + return 0; +} + +static INLINE void android_mouse_calculate_deltas(android_input_data_t *android_data, AInputEvent *event,size_t motion_ptr) +{ + // Adjust mouse speed based on ratio between core resolution and system resolution + float x_scale = 1; + float y_scale = 1; + video_viewport_t *custom_vp = video_viewport_get_custom(); + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); + if(custom_vp && av_info) + { + const struct retro_game_geometry *geom = (const struct retro_game_geometry*)&av_info->geometry; + x_scale = 2 * (float)geom->base_width / (float)custom_vp->width; + y_scale = 2 * (float)geom->base_height / (float)custom_vp->height; + } + + // This axis is only available on Android Nougat and on Android devices with NVIDIA extensions + float x = AMotionEvent_getAxisValue(event,AMOTION_EVENT_AXIS_RELATIVE_X, motion_ptr); + float y = AMotionEvent_getAxisValue(event,AMOTION_EVENT_AXIS_RELATIVE_Y, motion_ptr); + + // Use AXIS_RELATIVE values if they were available + if (x != 0 || y != 0) + { + android_data->mouse_x_delta = ceil(x * x_scale); + android_data->mouse_y_delta = ceil(y * y_scale); + } + // If not then calculate deltas based on AXIS_X and AXIS_Y. This has limitations compared to AXIS_RELATIVE + // because once the Android mouse cursor hits the edge of the screen it is not possible to move the in-game + // mouse any further in that direction. + else + { + android_data->mouse_x_delta = ceil((AMotionEvent_getX(event, motion_ptr) - android_data->mouse_x_prev) * x_scale); + android_data->mouse_y_delta = ceil((AMotionEvent_getY(event, motion_ptr) - android_data->mouse_y_prev) * y_scale); + android_data->mouse_x_prev = AMotionEvent_getX(event, motion_ptr); + android_data->mouse_y_prev = AMotionEvent_getY(event, motion_ptr); + } +} + static INLINE int android_input_poll_event_type_motion( android_input_data_t *android_data, AInputEvent *event, int port, int source) @@ -502,6 +590,7 @@ static INLINE int android_input_poll_event_type_motion( int getaction, action; size_t motion_ptr; bool keyup; + int btn; // Only handle events from a touchscreen or mouse if (!(source & (AINPUT_SOURCE_TOUCHSCREEN | AINPUT_SOURCE_MOUSE))) @@ -517,8 +606,38 @@ static INLINE int android_input_poll_event_type_motion( (source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN); + // If source is mouse then calculate button state and mouse deltas and don't process as touchscreen event + if (source == AINPUT_SOURCE_MOUSE) + { + // getButtonState requires API level 14 + if (p_AMotionEvent_getButtonState) + { + btn = (int)AMotionEvent_getButtonState(event); + android_data->mouse_l = (btn & AMOTION_EVENT_BUTTON_PRIMARY); + android_data->mouse_r = (btn & AMOTION_EVENT_BUTTON_SECONDARY); + } + else + { + // If getButtonState is not available then treat all MotionEvent.ACTION_DOWN as left button presses + if (action == AMOTION_EVENT_ACTION_DOWN) + android_data->mouse_l = 1; + if (action == AMOTION_EVENT_ACTION_UP) + android_data->mouse_l = 0; + } + android_mouse_calculate_deltas(android_data,event,motion_ptr); + return 0; + } + if (keyup && motion_ptr < MAX_TOUCH) { + if(action == AMOTION_EVENT_ACTION_UP && ENABLE_TOUCH_SCREEN_MOUSE) + { + // If touchscreen was pressed for less than 200ms then register time stamp of a quick tap + if((AMotionEvent_getEventTime(event)-AMotionEvent_getDownTime(event))/1000000 < 200) + android_data->quick_tap_time = AMotionEvent_getEventTime(event); + android_data->mouse_l = 0; + } + memmove(android_data->pointer + motion_ptr, android_data->pointer + motion_ptr + 1, (MAX_TOUCH - motion_ptr - 1) * sizeof(struct input_pointer)); @@ -529,6 +648,25 @@ static INLINE int android_input_poll_event_type_motion( { int pointer_max = MIN(AMotionEvent_getPointerCount(event), MAX_TOUCH); + if(action == AMOTION_EVENT_ACTION_DOWN && ENABLE_TOUCH_SCREEN_MOUSE) + { + // When touch screen is pressed, set mouse previous position to current position + // before starting to calculate mouse movement deltas. + android_data->mouse_x_prev = AMotionEvent_getX(event, motion_ptr); + android_data->mouse_y_prev = AMotionEvent_getY(event, motion_ptr); + + // If another touch happened within 200ms after a quick tap then cancel the quick tap + // and register left mouse button as being held down + if((AMotionEvent_getEventTime(event) - android_data->quick_tap_time)/1000000 < 200) + { + android_data->quick_tap_time = 0; + android_data->mouse_l = 1; + } + } + + if(action == AMOTION_EVENT_ACTION_MOVE && ENABLE_TOUCH_SCREEN_MOUSE) + android_mouse_calculate_deltas(android_data,event,motion_ptr); + for (motion_ptr = 0; motion_ptr < pointer_max; motion_ptr++) { struct video_viewport vp = {0}; @@ -549,6 +687,10 @@ static INLINE int android_input_poll_event_type_motion( } } + // If more than one pointer detected then count it as a mouse right click + if (ENABLE_TOUCH_SCREEN_MOUSE) + android_data->mouse_r = (android_data->pointer_count == 2); + return 0; } @@ -1007,6 +1149,20 @@ static void android_input_poll_memcpy(void *data) memcpy(&android->copy, &android->thread, sizeof(android->copy)); + // If a quick tap timer is active then check if more than 200ms have passed without it being + // reset by a new motionevent. If so then queue a single left mouse click. This really should + // by done in one of the polling functions, but since android_input_state() uses a copy of + // the inputstate being created here, it has to be done here. Same goes for the deltas resets. + retro_time_t now = cpu_features_get_time_usec(); + if(android->thread.quick_tap_time && (now/1000 - android->thread.quick_tap_time/1000000) >= 200) + { + android->thread.quick_tap_time = 0; + android->copy.mouse_l = 1; + } + + android->thread.mouse_x_delta = 0; + android->thread.mouse_y_delta = 0; + for (i = 0; i < MAX_PADS; i++) { for (j = 0; j < 2; j++) @@ -1128,6 +1284,8 @@ static int16_t android_input_state(void *data, return input_joypad_analog(android->joypad, joypad_info, port, idx, id, binds[port]); break; + case RETRO_DEVICE_MOUSE: + return android_mouse_state(android_data, id); case RETRO_DEVICE_POINTER: switch (id) { From a67935404d88878c80a5ea2c7f2187c70bfa0693 Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 15 Feb 2017 01:40:04 -0500 Subject: [PATCH 80/90] fix logging to file --- verbosity.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/verbosity.c b/verbosity.c index 418c526d00..e97f38db50 100644 --- a/verbosity.c +++ b/verbosity.c @@ -50,12 +50,14 @@ * will write to this file. */ static FILE *log_file = NULL; static bool main_verbosity = false; +static bool inited = false; void verbosity_enable(void) { main_verbosity = true; #ifdef RARCH_INTERNAL - frontend_driver_attach_console(); + if (!log_file) + frontend_driver_attach_console(); #endif } @@ -63,7 +65,8 @@ void verbosity_disable(void) { main_verbosity = false; #ifdef RARCH_INTERNAL - frontend_driver_detach_console(); + if (!log_file) + frontend_driver_detach_console(); #endif } @@ -84,11 +87,14 @@ void *retro_main_log_file(void) void retro_main_log_file_init(const char *path) { + if (inited) + return; log_file = stderr; if (path == NULL) return; log_file = fopen(path, "wb"); + inited = true; } void retro_main_log_file_deinit(void) From 71b397902a67c363a446e3f4260c5054d1e2d126 Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 15 Feb 2017 01:42:44 -0500 Subject: [PATCH 81/90] better variable name --- verbosity.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/verbosity.c b/verbosity.c index e97f38db50..207070ea75 100644 --- a/verbosity.c +++ b/verbosity.c @@ -50,7 +50,7 @@ * will write to this file. */ static FILE *log_file = NULL; static bool main_verbosity = false; -static bool inited = false; +static bool initialized = false; void verbosity_enable(void) { @@ -87,14 +87,14 @@ void *retro_main_log_file(void) void retro_main_log_file_init(const char *path) { - if (inited) + if (initialized) return; log_file = stderr; if (path == NULL) return; log_file = fopen(path, "wb"); - inited = true; + initialized = true; } void retro_main_log_file_deinit(void) @@ -108,7 +108,7 @@ void retro_main_log_file_deinit(void) void RARCH_LOG_V(const char *tag, const char *fmt, va_list ap) { #if TARGET_OS_IPHONE - static int asl_inited = 0; + static int asl_initialized = 0; #if !TARGET_IPHONE_SIMULATOR static aslclient asl_client; #endif @@ -123,10 +123,10 @@ static aslclient asl_client; #if TARGET_IPHONE_SIMULATOR vprintf(fmt, ap); #else - if (!asl_inited) + if (!asl_initialized) { asl_client = asl_open(file_path_str(FILE_PATH_PROGRAM_NAME), "com.apple.console", ASL_OPT_STDERR | ASL_OPT_NO_DELAY); - asl_inited = 1; + asl_initialized = 1; } aslmsg msg = asl_new(ASL_TYPE_MSG); asl_set(msg, ASL_KEY_READ_UID, "-1"); From 8da9acd1fe1e3fd18efbbe88d9a084dcf38b26ef Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 15 Feb 2017 12:03:25 +0100 Subject: [PATCH 82/90] Rename variable --- verbosity.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/verbosity.c b/verbosity.c index 207070ea75..de42f41202 100644 --- a/verbosity.c +++ b/verbosity.c @@ -48,9 +48,9 @@ /* If this is non-NULL. RARCH_LOG and friends * will write to this file. */ -static FILE *log_file = NULL; -static bool main_verbosity = false; -static bool initialized = false; +static FILE *log_file = NULL; +static bool main_verbosity = false; +static bool log_file_initialized = false; void verbosity_enable(void) { @@ -87,14 +87,15 @@ void *retro_main_log_file(void) void retro_main_log_file_init(const char *path) { - if (initialized) + if (log_file_initialized) return; - log_file = stderr; + + log_file = stderr; if (path == NULL) return; - log_file = fopen(path, "wb"); - initialized = true; + log_file = fopen(path, "wb"); + log_file_initialized = true; } void retro_main_log_file_deinit(void) From 6309b21252f64d17190f47b50fc3f03ea5767668 Mon Sep 17 00:00:00 2001 From: dankcushions Date: Wed, 15 Feb 2017 15:15:09 +0000 Subject: [PATCH 83/90] Change to advanced settings: auto_remaps_enable & auto_overrides_enable There seems to be no reason to show these options as they default to true and there's no reason to disable them unless you were debugging something (and even then...) Maybe even remove the option entirely? --- menu/menu_setting.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 07983f0e81..6cba6258f5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2817,13 +2817,13 @@ static bool setting_append_list( bool_entries[3].name_enum_idx = MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE; bool_entries[3].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_AUTO_OVERRIDES_ENABLE; bool_entries[3].default_value = default_auto_overrides_enable; - bool_entries[3].flags = SD_FLAG_NONE; + bool_entries[3].flags = SD_FLAG_ADVANCED; bool_entries[4].target = &settings->auto_remaps_enable; bool_entries[4].name_enum_idx = MENU_ENUM_LABEL_AUTO_REMAPS_ENABLE; bool_entries[4].SHORT_enum_idx = MENU_ENUM_LABEL_VALUE_AUTO_REMAPS_ENABLE; bool_entries[4].default_value = default_auto_remaps_enable; - bool_entries[4].flags = SD_FLAG_NONE; + bool_entries[4].flags = SD_FLAG_ADVANCED; bool_entries[5].target = &settings->auto_shaders_enable; bool_entries[5].name_enum_idx = MENU_ENUM_LABEL_AUTO_SHADERS_ENABLE; From 4c1abfaa71eed37a16faacfe31d70538d2b37a9e Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Wed, 15 Feb 2017 14:40:37 -0500 Subject: [PATCH 84/90] Support for reset in netplay This patch transfers core_reset across netplay. Resets effectively worked before thanks to check_frames, but this makes resets work even without check_frames, and in particular should allow resets to force sync in savestateless cores, bringing them one step closer to actually being usable by non-experts. --- command.c | 3 + network/netplay/README | 8 +++ network/netplay/netplay.h | 1 + network/netplay/netplay_frontend.c | 109 ++++++++++++++++++++--------- network/netplay/netplay_io.c | 86 ++++++++++++++--------- network/netplay/netplay_private.h | 8 ++- network/netplay/netplay_sync.c | 7 ++ 7 files changed, 155 insertions(+), 67 deletions(-) diff --git a/command.c b/command.c index 86a42a3c06..9dc14b11cd 100644 --- a/command.c +++ b/command.c @@ -1918,6 +1918,9 @@ bool command_event(enum event_command cmd, void *data) core_reset(); #ifdef HAVE_CHEEVOS cheevos_reset_game(); +#endif +#if HAVE_NETWORKING + netplay_driver_ctl(RARCH_NETPLAY_CTL_RESET, NULL); #endif break; case CMD_EVENT_SAVE_STATE: diff --git a/network/netplay/README b/network/netplay/README index 168dd8b4e7..460dbc91cc 100644 --- a/network/netplay/README +++ b/network/netplay/README @@ -316,6 +316,14 @@ Payload: Description: Request that a client stall for the given number of frames. +Command: RESET +Payload: + { + frame: uint32 + } +Description: + Indicate that the core was reset at the beginning of the given frame. + Command: CHEATS Unused diff --git a/network/netplay/netplay.h b/network/netplay/netplay.h index e6fd5f6488..d873e62e99 100644 --- a/network/netplay/netplay.h +++ b/network/netplay/netplay.h @@ -44,6 +44,7 @@ enum rarch_netplay_ctl_state RARCH_NETPLAY_CTL_PAUSE, RARCH_NETPLAY_CTL_UNPAUSE, RARCH_NETPLAY_CTL_LOAD_SAVESTATE, + RARCH_NETPLAY_CTL_RESET, RARCH_NETPLAY_CTL_DISCONNECT }; diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index f999053822..0afbbcb353 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -740,6 +740,48 @@ void netplay_post_frame(netplay_t *netplay) } } +/** + * netplay_force_future + * @netplay : pointer to netplay object + * + * Force netplay to ignore all past input, typically because we've just loaded + * a state or reset. + */ +static void netplay_force_future(netplay_t *netplay) +{ + /* Wherever we're inputting, that's where we consider our state to be loaded */ + netplay->run_ptr = netplay->self_ptr; + netplay->run_frame_count = netplay->self_frame_count; + + /* We need to ignore any intervening data from the other side, + * and never rewind past this */ + netplay_update_unread_ptr(netplay); + if (netplay->unread_frame_count < netplay->run_frame_count) + { + uint32_t player; + for (player = 0; player < MAX_USERS; player++) + { + if (!(netplay->connected_players & (1<read_frame_count[player] < netplay->run_frame_count) + { + netplay->read_ptr[player] = netplay->run_ptr; + netplay->read_frame_count[player] = netplay->run_frame_count; + } + } + if (netplay->server_frame_count < netplay->run_frame_count) + { + netplay->server_ptr = netplay->run_ptr; + netplay->server_frame_count = netplay->run_frame_count; + } + netplay_update_unread_ptr(netplay); + } + if (netplay->other_frame_count < netplay->run_frame_count) + { + netplay->other_ptr = netplay->run_ptr; + netplay->other_frame_count = netplay->run_frame_count; + } +} + /** * netplay_send_savestate * @netplay : pointer to netplay object @@ -808,10 +850,7 @@ void netplay_load_savestate(netplay_t *netplay, { retro_ctx_serialize_info_t tmp_serial_info; - /* Wherever we're inputting, that's where we consider our state to be loaded - * (FIXME: Need to be more careful about saving it?) */ - netplay->run_ptr = netplay->self_ptr; - netplay->run_frame_count = netplay->self_frame_count; + netplay_force_future(netplay); /* Record it in our own buffer */ if (save || !serial_info) @@ -844,34 +883,6 @@ void netplay_load_savestate(netplay_t *netplay, } } - /* We need to ignore any intervening data from the other side, - * and never rewind past this */ - netplay_update_unread_ptr(netplay); - if (netplay->unread_frame_count < netplay->run_frame_count) - { - uint32_t player; - for (player = 0; player < MAX_USERS; player++) - { - if (!(netplay->connected_players & (1<read_frame_count[player] < netplay->run_frame_count) - { - netplay->read_ptr[player] = netplay->run_ptr; - netplay->read_frame_count[player] = netplay->run_frame_count; - } - } - if (netplay->server_frame_count < netplay->run_frame_count) - { - netplay->server_ptr = netplay->run_ptr; - netplay->server_frame_count = netplay->run_frame_count; - } - netplay_update_unread_ptr(netplay); - } - if (netplay->other_frame_count < netplay->run_frame_count) - { - netplay->other_ptr = netplay->run_ptr; - netplay->other_frame_count = netplay->run_frame_count; - } - /* If we can't send it to the peer, loading a state was a bad idea */ if (netplay->quirks & ( NETPLAY_QUIRK_NO_SAVESTATES @@ -886,6 +897,37 @@ void netplay_load_savestate(netplay_t *netplay, &netplay->compress_zlib); } +/** + * netplay_core_reset + * @netplay : pointer to netplay object + * + * Indicate that the core has been reset to netplay peers + **/ +static void netplay_core_reset(netplay_t *netplay) +{ + uint32_t cmd[3]; + size_t i; + + /* Ignore past input */ + netplay_force_future(netplay); + + /* Request that our peers reset */ + cmd[0] = htonl(NETPLAY_CMD_RESET); + cmd[1] = htonl(sizeof(uint32_t)); + cmd[2] = htonl(netplay->self_frame_count); + + for (i = 0; i < netplay->connections_size; i++) + { + struct netplay_connection *connection = &netplay->connections[i]; + if (!connection->active || + connection->mode < NETPLAY_CONNECTION_CONNECTED) continue; + + if (!netplay_send(&connection->send_packet_buffer, connection->fd, cmd, + sizeof(cmd))) + netplay_hangup(netplay, connection); + } +} + /** * netplay_toggle_play_spectate * @@ -1145,6 +1187,9 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data) case RARCH_NETPLAY_CTL_LOAD_SAVESTATE: netplay_load_savestate(netplay_data, (retro_ctx_serialize_info_t*)data, true); break; + case RARCH_NETPLAY_CTL_RESET: + netplay_core_reset(netplay_data); + break; case RARCH_NETPLAY_CTL_DISCONNECT: ret = netplay_disconnect(netplay_data); goto done; diff --git a/network/netplay/netplay_io.c b/network/netplay/netplay_io.c index c8c106a491..4de8e02375 100644 --- a/network/netplay/netplay_io.c +++ b/network/netplay/netplay_io.c @@ -1022,6 +1022,7 @@ static bool netplay_get_cmd(netplay_t *netplay, break; case NETPLAY_CMD_LOAD_SAVESTATE: + case NETPLAY_CMD_RESET: { uint32_t frame; uint32_t isize; @@ -1071,7 +1072,11 @@ static bool netplay_get_cmd(netplay_t *netplay, * (strangely) force a rewind to the frame we're already on, so it * gets loaded. This is just to avoid having reloading implemented in * too many places. */ - if (cmd_size > netplay->zbuffer_size + 2*sizeof(uint32_t)) + + /* Check the payload size */ + if ((cmd == NETPLAY_CMD_LOAD_SAVESTATE && + (cmd_size < 2*sizeof(uint32_t) || cmd_size > netplay->zbuffer_size + 2*sizeof(uint32_t))) || + (cmd == NETPLAY_CMD_RESET && cmd_size != sizeof(uint32_t))) { RARCH_ERR("CMD_LOAD_SAVESTATE received an unexpected payload size.\n"); return netplay_cmd_nak(netplay, connection); @@ -1097,44 +1102,58 @@ static bool netplay_get_cmd(netplay_t *netplay, goto shrt; } - RECV(&isize, sizeof(isize)) + /* Now we switch based on whether we're loading a state or resetting */ + if (cmd == NETPLAY_CMD_LOAD_SAVESTATE) { - RARCH_ERR("CMD_LOAD_SAVESTATE failed to receive inflated size.\n"); - return netplay_cmd_nak(netplay, connection); - } - isize = ntohl(isize); + RECV(&isize, sizeof(isize)) + { + RARCH_ERR("CMD_LOAD_SAVESTATE failed to receive inflated size.\n"); + return netplay_cmd_nak(netplay, connection); + } + isize = ntohl(isize); - if (isize != netplay->state_size) - { - RARCH_ERR("CMD_LOAD_SAVESTATE received an unexpected save state size.\n"); - return netplay_cmd_nak(netplay, connection); - } + if (isize != netplay->state_size) + { + RARCH_ERR("CMD_LOAD_SAVESTATE received an unexpected save state size.\n"); + return netplay_cmd_nak(netplay, connection); + } - RECV(netplay->zbuffer, cmd_size - 2*sizeof(uint32_t)) - { - RARCH_ERR("CMD_LOAD_SAVESTATE failed to receive savestate.\n"); - return netplay_cmd_nak(netplay, connection); - } + RECV(netplay->zbuffer, cmd_size - 2*sizeof(uint32_t)) + { + RARCH_ERR("CMD_LOAD_SAVESTATE failed to receive savestate.\n"); + return netplay_cmd_nak(netplay, connection); + } + + /* And decompress it */ + switch (connection->compression_supported) + { + case NETPLAY_COMPRESSION_ZLIB: + ctrans = &netplay->compress_zlib; + break; + default: + ctrans = &netplay->compress_nil; + } + ctrans->decompression_backend->set_in(ctrans->decompression_stream, + netplay->zbuffer, cmd_size - 2*sizeof(uint32_t)); + ctrans->decompression_backend->set_out(ctrans->decompression_stream, + (uint8_t*)netplay->buffer[netplay->read_ptr[connection->player]].state, + netplay->state_size); + ctrans->decompression_backend->trans(ctrans->decompression_stream, + true, &rd, &wn, NULL); + + /* Force a rewind to the relevant frame */ + netplay->force_rewind = true; + } + else + { + /* Resetting */ + netplay->force_reset = true; - /* And decompress it */ - switch (connection->compression_supported) - { - case NETPLAY_COMPRESSION_ZLIB: - ctrans = &netplay->compress_zlib; - break; - default: - ctrans = &netplay->compress_nil; } - ctrans->decompression_backend->set_in(ctrans->decompression_stream, - netplay->zbuffer, cmd_size - 2*sizeof(uint32_t)); - ctrans->decompression_backend->set_out(ctrans->decompression_stream, - (uint8_t*)netplay->buffer[netplay->read_ptr[connection->player]].state, - netplay->state_size); - ctrans->decompression_backend->trans(ctrans->decompression_stream, - true, &rd, &wn, NULL); /* Skip ahead if it's past where we are */ - if (frame > netplay->run_frame_count) + if (frame > netplay->run_frame_count || + cmd == NETPLAY_CMD_RESET) { /* This is squirrely: We need to assure that when we advance the * frame in post_frame, THEN we're referring to the frame to @@ -1161,8 +1180,7 @@ static bool netplay_get_cmd(netplay_t *netplay, } } - /* And force rewind to it */ - netplay->force_rewind = true; + /* Make sure our states are correct */ netplay->savestate_request_outstanding = false; netplay->other_ptr = netplay->read_ptr[connection->player]; netplay->other_frame_count = frame; diff --git a/network/netplay/netplay_private.h b/network/netplay/netplay_private.h index 9d11e133b1..03b57f34d4 100644 --- a/network/netplay/netplay_private.h +++ b/network/netplay/netplay_private.h @@ -153,8 +153,11 @@ enum netplay_cmd /* Request that a client stall because it's running fast */ NETPLAY_CMD_STALL = 0x0045, + /* Request a core reset */ + NETPLAY_CMD_RESET = 0x0046, + /* Sends over cheats enabled on client (unsupported) */ - NETPLAY_CMD_CHEATS = 0x0046, + NETPLAY_CMD_CHEATS = 0x0047, /* Misc. commands */ @@ -404,6 +407,9 @@ struct netplay * events, such as player flipping or savestate loading. */ bool force_rewind; + /* Force a reset */ + bool force_reset; + /* Quirks in the savestate implementation */ uint64_t quirks; diff --git a/network/netplay/netplay_sync.c b/network/netplay/netplay_sync.c index bfc8caa2a4..02f949aa0c 100644 --- a/network/netplay/netplay_sync.c +++ b/network/netplay/netplay_sync.c @@ -396,6 +396,13 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled) return; } + /* Reset if it was requested */ + if (netplay->force_reset) + { + core_reset(); + netplay->force_reset = false; + } + #ifndef DEBUG_NONDETERMINISTIC_CORES if (!netplay->force_rewind) { From cd1b95220ae462611206a8ee83dc9aaf1a812d3e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 15 Feb 2017 21:03:57 +0100 Subject: [PATCH 85/90] Add miniupnpc dependency which can be optionally compiled in --- Makefile.common | 21 +- deps/miniupnpc/Changelog.txt | 684 ++++++++++++ deps/miniupnpc/LICENSE | 27 + deps/miniupnpc/MANIFEST.in | 5 + deps/miniupnpc/Makefile | 274 +++++ deps/miniupnpc/README | 64 ++ deps/miniupnpc/VERSION | 1 + deps/miniupnpc/apiversions.txt | 172 +++ deps/miniupnpc/codelength.h | 54 + deps/miniupnpc/connecthostport.c | 264 +++++ deps/miniupnpc/connecthostport.h | 18 + deps/miniupnpc/igd_desc_parse.c | 123 +++ deps/miniupnpc/igd_desc_parse.h | 49 + deps/miniupnpc/minisoap.c | 123 +++ deps/miniupnpc/minisoap.h | 15 + deps/miniupnpc/minissdpc.c | 876 +++++++++++++++ deps/miniupnpc/minissdpc.h | 58 + deps/miniupnpc/miniupnpc.c | 722 +++++++++++++ deps/miniupnpc/miniupnpc.def | 45 + deps/miniupnpc/miniupnpc.h | 152 +++ deps/miniupnpc/miniupnpc_declspec.h | 12 + deps/miniupnpc/miniupnpctypes.h | 19 + deps/miniupnpc/miniwget.c | 661 ++++++++++++ deps/miniupnpc/miniwget.h | 30 + deps/miniupnpc/minixml.c | 229 ++++ deps/miniupnpc/minixml.h | 37 + deps/miniupnpc/portlistingparse.c | 172 +++ deps/miniupnpc/portlistingparse.h | 65 ++ deps/miniupnpc/receivedata.c | 105 ++ deps/miniupnpc/receivedata.h | 19 + deps/miniupnpc/updateminiupnpcstrings.sh | 53 + deps/miniupnpc/upnpcommands.c | 1240 ++++++++++++++++++++++ deps/miniupnpc/upnpcommands.h | 348 ++++++ deps/miniupnpc/upnpdev.c | 23 + deps/miniupnpc/upnpdev.h | 36 + deps/miniupnpc/upnperrors.c | 107 ++ deps/miniupnpc/upnperrors.h | 26 + deps/miniupnpc/upnpreplyparse.c | 197 ++++ deps/miniupnpc/upnpreplyparse.h | 63 ++ griffin/griffin.c | 16 + qb/config.libs.sh | 4 + qb/config.params.sh | 1 + 42 files changed, 7209 insertions(+), 1 deletion(-) create mode 100644 deps/miniupnpc/Changelog.txt create mode 100644 deps/miniupnpc/LICENSE create mode 100644 deps/miniupnpc/MANIFEST.in create mode 100644 deps/miniupnpc/Makefile create mode 100644 deps/miniupnpc/README create mode 100644 deps/miniupnpc/VERSION create mode 100644 deps/miniupnpc/apiversions.txt create mode 100644 deps/miniupnpc/codelength.h create mode 100644 deps/miniupnpc/connecthostport.c create mode 100644 deps/miniupnpc/connecthostport.h create mode 100644 deps/miniupnpc/igd_desc_parse.c create mode 100644 deps/miniupnpc/igd_desc_parse.h create mode 100644 deps/miniupnpc/minisoap.c create mode 100644 deps/miniupnpc/minisoap.h create mode 100644 deps/miniupnpc/minissdpc.c create mode 100644 deps/miniupnpc/minissdpc.h create mode 100644 deps/miniupnpc/miniupnpc.c create mode 100644 deps/miniupnpc/miniupnpc.def create mode 100644 deps/miniupnpc/miniupnpc.h create mode 100644 deps/miniupnpc/miniupnpc_declspec.h create mode 100644 deps/miniupnpc/miniupnpctypes.h create mode 100644 deps/miniupnpc/miniwget.c create mode 100644 deps/miniupnpc/miniwget.h create mode 100644 deps/miniupnpc/minixml.c create mode 100644 deps/miniupnpc/minixml.h create mode 100644 deps/miniupnpc/portlistingparse.c create mode 100644 deps/miniupnpc/portlistingparse.h create mode 100644 deps/miniupnpc/receivedata.c create mode 100644 deps/miniupnpc/receivedata.h create mode 100755 deps/miniupnpc/updateminiupnpcstrings.sh create mode 100644 deps/miniupnpc/upnpcommands.c create mode 100644 deps/miniupnpc/upnpcommands.h create mode 100644 deps/miniupnpc/upnpdev.c create mode 100644 deps/miniupnpc/upnpdev.h create mode 100644 deps/miniupnpc/upnperrors.c create mode 100644 deps/miniupnpc/upnperrors.h create mode 100644 deps/miniupnpc/upnpreplyparse.c create mode 100644 deps/miniupnpc/upnpreplyparse.h diff --git a/Makefile.common b/Makefile.common index 8be45a85e3..34c0b4a719 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1208,7 +1208,26 @@ ifeq ($(HAVE_NETWORKING), 1) endif ifeq ($(HAVE_MINIUPNPC), 1) - LIBS += -lminiupnpc + ifeq ($(HAVE_BUILTINMINIUPNPC), 1) + DEFINES += -DHAVE_BUILTINMINIUPNPC -DMINIUPNPC_SET_SOCKET_TIMEOUT -DMINIUPNPC_GET_SRC_ADDR + DEFINES += -I$(DEPS_DIR)/miniupnpc + OBJ += \ + $(DEPS_DIR)/miniupnpc/igd_desc_parse.o \ + $(DEPS_DIR)/miniupnpc/upnpreplyparse.o \ + $(DEPS_DIR)/miniupnpc/upnpcommands.o \ + $(DEPS_DIR)/miniupnpc/upnperrors.o \ + $(DEPS_DIR)/miniupnpc/connecthostport.o \ + $(DEPS_DIR)/miniupnpc/portlistingparse.o \ + $(DEPS_DIR)/miniupnpc/receivedata.o \ + $(DEPS_DIR)/miniupnpc/upnpdev.o \ + $(DEPS_DIR)/miniupnpc/minissdpc.o \ + $(DEPS_DIR)/miniupnpc/miniwget.o \ + $(DEPS_DIR)/miniupnpc/miniupnpc.o \ + $(DEPS_DIR)/miniupnpc/minixml.o \ + $(DEPS_DIR)/miniupnpc/minisoap.o + else + LIBS += -lminiupnpc + endif endif endif diff --git a/deps/miniupnpc/Changelog.txt b/deps/miniupnpc/Changelog.txt new file mode 100644 index 0000000000..76d947b202 --- /dev/null +++ b/deps/miniupnpc/Changelog.txt @@ -0,0 +1,684 @@ +$Id: Changelog.txt,v 1.226 2016/12/16 08:57:19 nanard Exp $ +miniUPnP client Changelog. + +2016/11/11: + check strlen before memcmp in XML parsing portlistingparse.c + fix build under SOLARIS and CYGWIN + +2016/10/11: + Add python 3 compatibility to IGD test + +VERSION 2.0 : released 2016/04/19 + +2016/01/24: + change miniwget to return HTTP status code + increments API_VERSION to 16 + +2016/01/22: + Improve UPNPIGD_IsConnected() to check if WAN address is not private. + parse HTTP response status line in miniwget.c + +2015/10/26: + snprintf() overflow check. check overflow in simpleUPnPcommand2() + +2015/10/25: + fix compilation with old macs + fix compilation with mingw32 (for Appveyor) + fix python module for python <= 2.3 + +2015/10/08: + Change sameport to localport + see https://github.com/miniupnp/miniupnp/pull/120 + increments API_VERSION to 15 + +2015/09/15: + Fix buffer overflow in igd_desc_parse.c/IGDstartelt() + Discovered by Aleksandar Nikolic of Cisco Talos + +2015/08/28: + move ssdpDiscoverDevices() to minissdpc.c + +2015/08/27: + avoid unix socket leak in getDevicesFromMiniSSDPD() + +2015/08/16: + Also accept "Up" as ConnectionStatus value + +2015/07/23: + split getDevicesFromMiniSSDPD + add ttl argument to upnpDiscover() functions + increments API_VERSION to 14 + +2015/07/22: + Read USN from SSDP messages. + +2015/07/15: + Check malloc/calloc + +2015/06/16: + update getDevicesFromMiniSSDPD() to process longer minissdpd + responses + +2015/05/22: + add searchalltypes param to upnpDiscoverDevices() + increments API_VERSION to 13 + +2015/04/30: + upnpc: output version on the terminal + +2015/04/27: + _BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE + fix CMakeLists.txt COMPILE_DEFINITIONS + fix getDevicesFromMiniSSDPD() not setting scope_id + improve -r command of upnpc command line tool + +2014/11/17: + search all : + upnpDiscoverDevices() / upnpDiscoverAll() functions + listdevices executable + increment API_VERSION to 12 + validate igd_desc_parse + +2014/11/13: + increment API_VERSION to 11 + +2014/11/05: + simplified function GetUPNPUrls() + +2014/09/11: + use remoteHost arg of DeletePortMapping + +2014/09/06: + Fix python3 build + +2014/07/01: + Fix parsing of IGD2 root descriptions + +2014/06/10: + rename LIBSPEC to MINIUPNP_LIBSPEC + +2014/05/15: + Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange + +2014/02/05: + handle EINPROGRESS after connect() + +2014/02/03: + minixml now handle XML comments + +VERSION 1.9 : released 2014/01/31 + +2014/01/31: + added argument remoteHost to UPNP_GetSpecificPortMappingEntry() + increment API_VERSION to 10 + +2013/12/09: + --help and -h arguments in upnpc.c + +2013/10/07: + fixed potential buffer overrun in miniwget.c + Modified UPNP_GetValidIGD() to check for ExternalIpAddress + +2013/08/01: + define MAXHOSTNAMELEN if not already done + +2013/06/06: + update upnpreplyparse to allow larger values (128 chars instead of 64) + +2013/05/14: + Update upnpreplyparse to take into account "empty" elements + validate upnpreplyparse.c code with "make check" + +2013/05/03: + Fix Solaris build thanks to Maciej Małecki + +2013/04/27: + Fix testminiwget.sh for BSD + +2013/03/23: + Fixed Makefile for *BSD + +2013/03/11: + Update Makefile to use JNAerator version 0.11 + +2013/02/11: + Fix testminiwget.sh for use with dash + Use $(DESTDIR) in Makefile + +VERSION 1.8 : released 2013/02/06 + +2012/10/16: + fix testminiwget with no IPv6 support + +2012/09/27: + Rename all include guards to not clash with C99 + (7.1.3 Reserved identifiers). + +2012/08/30: + Added -e option to upnpc program (set description for port mappings) + +2012/08/29: + Python 3 support (thanks to Christopher Foo) + +2012/08/11: + Fix a memory link in UPNP_GetValidIGD() + Try to handle scope id in link local IPv6 URL under MS Windows + +2012/07/20: + Disable HAS_IP_MREQN on DragonFly BSD + +2012/06/28: + GetUPNPUrls() now inserts scope into link-local IPv6 addresses + +2012/06/23: + More error return checks in upnpc.c + #define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id + parseURL() now parses IPv6 addresses scope + new parameter for miniwget() : IPv6 address scope + increment API_VERSION to 9 + +2012/06/20: + fixed CMakeLists.txt + +2012/05/29 + Improvements in testminiwget.sh + +VERSION 1.7 : released 2012/05/24 + +2012/05/01: + Cleanup settings of CFLAGS in Makefile + Fix signed/unsigned integer comparaisons + +2012/04/20: + Allow to specify protocol with TCP or UDP for -A option + +2012/04/09: + Only try to fetch XML description once in UPNP_GetValidIGD() + Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments. + +2012/04/05: + minor improvements to minihttptestserver.c + +2012/03/15: + upnperrors.c returns valid error string for unrecognized error codes + +2012/03/08: + make minihttptestserver listen on loopback interface instead of 0.0.0.0 + +2012/01/25: + Maven installation thanks to Alexey Kuznetsov + +2012/01/21: + Replace WIN32 macro by _WIN32 + +2012/01/19: + Fixes in java wrappers thanks to Alexey Kuznetsov : + https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc + Make and install .deb packages (python) thanks to Alexey Kuznetsov : + https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc + +2012/01/07: + The multicast interface can now be specified by name with IPv4. + +2012/01/02: + Install man page + +2011/11/25: + added header to Port Mappings list in upnpc.c + +2011/10/09: + Makefile : make clean now removes jnaerator generated files. + MINIUPNPC_VERSION in miniupnpc.h (updated by make) + +2011/09/12: + added rootdescURL to UPNPUrls structure. + +VERSION 1.6 : released 2011/07/25 + +2011/07/25: + Update doc for version 1.6 release + +2011/06/18: + Fix for windows in miniwget.c + +2011/06/04: + display remote host in port mapping listing + +2011/06/03: + Fix in make install : there were missing headers + +2011/05/26: + Fix the socket leak in miniwget thanks to Richard Marsh. + Permit to add leaseduration in -a command. Display lease duration. + +2011/05/15: + Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6 + +2011/05/09: + add a test in testminiwget.sh. + more error checking in miniwget.c + +2011/05/06: + Adding some tool to test and validate miniwget.c + simplified and debugged miniwget.c + +2011/04/11: + moving ReceiveData() to a receivedata.c file. + parsing presentation url + adding IGD v2 WANIPv6FirewallControl commands + +2011/04/10: + update of miniupnpcmodule.c + comments in miniwget.c, update in testminiwget + Adding errors codes from IGD v2 + new functions in upnpc.c for IGD v2 + +2011/04/09: + Support for litteral ip v6 address in miniwget + +2011/04/08: + Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1 + Updating APIVERSION + Supporting IPV6 in upnpDiscover() + Adding a -6 option to upnpc command line tool + +2011/03/18: + miniwget/parseURL() : return an error when url param is null. + fixing GetListOfPortMappings() + +2011/03/14: + upnpDiscover() now reporting an error code. + improvements in comments. + +2011/03/11: + adding miniupnpcstrings.h.cmake and CMakeLists.txt files. + +2011/02/15: + Implementation of GetListOfPortMappings() + +2011/02/07: + updates to minixml to support character data starting with spaces + minixml now support CDATA + upnpreplyparse treats specificaly + change in simpleUPnPcommand to return the buffer (simplification) + +2011/02/06: + Added leaseDuration argument to AddPortMapping() + Starting to implement GetListOfPortMappings() + +2011/01/11: + updating wingenminiupnpcstrings.c + +2011/01/04: + improving updateminiupnpcstrings.sh + +VERSION 1.5 : released 2011/01/01 + +2010/12/21: + use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo + +2010/12/11: + Improvements on getHTTPResponse() code. + +2010/12/09: + new code for miniwget that handle Chunked transfer encoding + using getHTTPResponse() in SOAP call code + Adding MANIFEST.in for 'python setup.py bdist_rpm' + +2010/11/25: + changes to minissdpc.c to compile under Win32. + see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729 + +2010/09/17: + Various improvement to Makefile from Michał Górny + +2010/08/05: + Adding the script "external-ip.sh" from Reuben Hawkins + +2010/06/09: + update to python module to match modification made on 2010/04/05 + update to Java test code to match modification made on 2010/04/05 + all UPNP_* function now return an error if the SOAP request failed + at HTTP level. + +2010/04/17: + Using GetBestRoute() under win32 in order to find the + right interface to use. + +2010/04/12: + Retrying with HTTP/1.1 if HTTP/1.0 failed. see + http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703 + +2010/04/07: + avoid returning duplicates in upnpDiscover() + +2010/04/05: + Create a connecthostport.h/.c with connecthostport() function + and use it in miniwget and miniupnpc. + Use getnameinfo() instead of inet_ntop or inet_ntoa + Work to make miniupnpc IPV6 compatible... + Add java test code. + Big changes in order to support device having both WANIPConnection + and WANPPPConnection. + +2010/04/04: + Use getaddrinfo() instead of gethostbyname() in miniwget. + +2010/01/06: + #define _DARWIN_C_SOURCE for Mac OS X + +2009/12/19: + Improve MinGW32 build + +2009/12/11: + adding a MSVC9 project to build the static library and executable + +2009/12/10: + Fixing some compilation stuff for Windows/MinGW + +2009/12/07: + adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS + some fixes for Windows when using virtual ethernet adapters (it is the + case with VMWare installed). + +2009/12/04: + some fixes for AmigaOS compilation + Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked + transfer encoding) + +2009/12/03: + updating printIDG and testigddescparse.c for debug. + modifications to compile under AmigaOS + adding a testminiwget program + Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked + transfer encoding + +2009/11/26: + fixing updateminiupnpcstrings.sh to take into account + which command that does not return an error code. + +VERSION 1.4 : released 2009/10/30 + +2009/10/16: + using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module. + +2009/10/10: + Some fixes for compilation under Solaris + compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464 + +2009/09/21: + fixing the code to ignore EINTR during connect() calls. + +2009/08/07: + Set socket timeout for connect() + Some cleanup in miniwget.c + +2009/08/04: + remove multiple redirections with -d in upnpc.c + Print textual error code in upnpc.c + Ignore EINTR during the connect() and poll() calls. + +2009/07/29: + fix in updateminiupnpcstrings.sh if OS name contains "/" + Sending a correct value for MX: field in SSDP request + +2009/07/20: + Change the Makefile to compile under Mac OS X + Fixed a stackoverflow in getDevicesFromMiniSSDPD() + +2009/07/09: + Compile under Haiku + generate miniupnpcstrings.h.in from miniupnpcstrings.h + +2009/06/04: + patching to compile under CygWin and cross compile for minGW + +VERSION 1.3 : + +2009/04/17: + updating python module + Use strtoull() when using C99 + +2009/02/28: + Fixed miniwget.c for compiling under sun + +2008/12/18: + cleanup in Makefile (thanks to Paul de Weerd) + minissdpc.c : win32 compatibility + miniupnpc.c : changed xmlns prefix from 'm' to 'u' + Removed NDEBUG (using DEBUG) + +2008/10/14: + Added the ExternalHost argument to DeletePortMapping() + +2008/10/11: + Added the ExternalHost argument to AddPortMapping() + Put a correct User-Agent: header in HTTP requests. + +VERSION 1.2 : + +2008/10/07: + Update docs + +2008/09/25: + Integrated sameport patch from Dario Meloni : Added a "sameport" + argument to upnpDiscover(). + +2008/07/18: + small modif to make Clang happy :) + +2008/07/17: + #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV... + +2008/07/14: + include declspec.h in installation (to /usr/include/miniupnpc) + +VERSION 1.1 : + +2008/07/04: + standard options for install/ln instead of gnu-specific stuff. + +2008/07/03: + now builds a .dll and .lib with win32. (mingw32) + +2008/04/28: + make install now install the binary of the upnpc tool + +2008/04/27: + added testupnpigd.py + added error strings for miniupnpc "internal" errors + improved python module error/exception reporting. + +2008/04/23: + Completely rewrite igd_desc_parse.c in order to be compatible with + Linksys WAG200G + Added testigddescparse + updated python module + +VERSION 1.0 : + +2008/02/21: + put some #ifdef DEBUG around DisplayNameValueList() + +2008/02/18: + Improved error reporting in upnpcommands.c + UPNP_GetStatusInfo() returns LastConnectionError + +2008/02/16: + better error handling in minisoap.c + improving display of "valid IGD found" in upnpc.c + +2008/02/03: + Fixing UPNP_GetValidIGD() + improved make install :) + +2007/12/22: + Adding upnperrors.c/h to provide a strupnperror() function + used to translate UPnP error codes to string. + +2007/12/19: + Fixing getDevicesFromMiniSSDPD() + improved error reporting of UPnP functions + +2007/12/18: + It is now possible to specify a different location for MiniSSDPd socket. + working with MiniSSDPd is now more efficient. + python module improved. + +2007/12/16: + improving error reporting + +2007/12/13: + Try to improve compatibility by using HTTP/1.0 instead of 1.1 and + XML a bit different for SOAP. + +2007/11/25: + fixed select() call for linux + +2007/11/15: + Added -fPIC to CFLAG for better shared library code. + +2007/11/02: + Fixed a potential socket leak in miniwget2() + +2007/10/16: + added a parameter to upnpDiscover() in order to allow the use of another + interface than the default multicast interface. + +2007/10/12: + Fixed the creation of symbolic link in Makefile + +2007/10/08: + Added man page + +2007/10/02: + fixed memory bug in GetUPNPUrls() + +2007/10/01: + fixes in the Makefile + Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly. + Added SONAME in the shared library to please debian :) + fixed MS Windows compilation (minissdpd is not available under MS Windows). + +2007/09/25: + small change to Makefile to be able to install in a different location + (default is /usr) + +2007/09/24: + now compiling both shared and static library + +2007/09/19: + Cosmetic changes on upnpc.c + +2007/09/02: + adapting to new miniSSDPd (release version ?) + +2007/08/31: + Usage of miniSSDPd to skip discovery process. + +2007/08/27: + fixed python module to allow compilation with Python older than Python 2.4 + +2007/06/12: + Added a python module. + +2007/05/19: + Fixed compilation under MinGW + +2007/05/15: + fixed a memory leak in AddPortMapping() + Added testupnpreplyparse executable to check the parsing of + upnp soap messages + minixml now ignore namespace prefixes. + +2007/04/26: + upnpc now displays external ip address with -s or -l + +2007/04/11: + changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210" + +2007/03/19: + cleanup in miniwget.c + +2007/03/01: + Small typo fix... + +2007/01/30: + Now parsing the HTTP header from SOAP responses in order to + get content-length value. + +2007/01/29: + Fixed the Soap Query to speedup the HTTP request. + added some Win32 DLL stuff... + +2007/01/27: + Fixed some WIN32 compatibility issues + +2006/12/14: + Added UPNPIGD_IsConnected() function in miniupnp.c/.h + Added UPNP_GetValidIGD() in miniupnp.c/.h + cleaned upnpc.c main(). now using UPNP_GetValidIGD() + +2006/12/07: + Version 1.0-RC1 released + +2006/12/03: + Minor changes to compile under SunOS/Solaris + +2006/11/30: + made a minixml parser validator program + updated minixml to handle attributes correctly + +2006/11/22: + Added a -r option to the upnpc sample thanks to Alexander Hubmann. + +2006/11/19: + Cleanup code to make it more ANSI C compliant + +2006/11/10: + detect and display local lan address. + +2006/11/04: + Packets and Bytes Sent/Received are now unsigned int. + +2006/11/01: + Bug fix thanks to Giuseppe D'Angelo + +2006/10/31: + C++ compatibility for .h files. + Added a way to get ip Address on the LAN used to reach the IGD. + +2006/10/25: + Added M-SEARCH to the services in the discovery process. + +2006/10/22: + updated the Makefile to use makedepend, added a "make install" + update Makefile + +2006/10/20: + fixing the description url parsing thanks to patch sent by + Wayne Dawe. + Fixed/translated some comments. + Implemented a better discover process, first looking + for IGD then for root devices (as some devices only reply to + M-SEARCH for root devices). + +2006/09/02: + added freeUPNPDevlist() function. + +2006/08/04: + More command line arguments checking + +2006/08/01: + Added the .bat file to compile under Win32 with minGW32 + +2006/07/31: + Fixed the rootdesc parser (igd_desc_parse.c) + +2006/07/20: + parseMSEARCHReply() is now returning the ST: line as well + starting changes to detect several UPnP devices on the network + +2006/07/19: + using GetCommonLinkProperties to get down/upload bitrate + diff --git a/deps/miniupnpc/LICENSE b/deps/miniupnpc/LICENSE new file mode 100644 index 0000000000..0816733704 --- /dev/null +++ b/deps/miniupnpc/LICENSE @@ -0,0 +1,27 @@ +MiniUPnPc +Copyright (c) 2005-2016, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + diff --git a/deps/miniupnpc/MANIFEST.in b/deps/miniupnpc/MANIFEST.in new file mode 100644 index 0000000000..54b86f95e3 --- /dev/null +++ b/deps/miniupnpc/MANIFEST.in @@ -0,0 +1,5 @@ +include README +include miniupnpcmodule.c +include setup.py +include *.h +include libminiupnpc.a diff --git a/deps/miniupnpc/Makefile b/deps/miniupnpc/Makefile new file mode 100644 index 0000000000..aea07e7d52 --- /dev/null +++ b/deps/miniupnpc/Makefile @@ -0,0 +1,274 @@ +# $Id: Makefile,v 1.134 2016/10/07 09:04:36 nanard Exp $ +# MiniUPnP Project +# http://miniupnp.free.fr/ +# http://miniupnp.tuxfamily.org/ +# https://github.com/miniupnp/miniupnp +# (c) 2005-2016 Thomas Bernard +# to install use : +# $ make DESTDIR=/tmp/dummylocation install +# or +# $ INSTALLPREFIX=/usr/local make install +# or +# $ make install (default INSTALLPREFIX is /usr) +OS = $(shell uname -s) +VERSION = $(shell cat VERSION) + +ifeq ($(OS), Darwin) +JARSUFFIX=mac +LIBTOOL ?= $(shell which libtool) +endif +ifeq ($(OS), Linux) +JARSUFFIX=linux +endif +ifneq (,$(findstring NT-5.1,$(OS))) +JARSUFFIX=win32 +endif + +HAVE_IPV6 ?= yes +export HAVE_IPV6 + +CC ?= gcc +#AR = gar +#CFLAGS = -O -g -DDEBUG +CFLAGS ?= -O +CFLAGS += -Wall +CFLAGS += -W -Wstrict-prototypes +CFLAGS += -fno-common +CFLAGS += -DMINIUPNPC_SET_SOCKET_TIMEOUT +CFLAGS += -DMINIUPNPC_GET_SRC_ADDR +CFLAGS += -D_BSD_SOURCE +CFLAGS += -D_DEFAULT_SOURCE +ifeq ($(OS), NetBSD) +CFLAGS += -D_NETBSD_SOURCE +endif +ifneq ($(OS), FreeBSD) +ifneq ($(OS), Darwin) +#CFLAGS += -D_POSIX_C_SOURCE=200112L +CFLAGS += -D_XOPEN_SOURCE=600 +endif +endif +#CFLAGS += -ansi +# -DNO_GETADDRINFO +INSTALL = install +SH = /bin/sh + +ifeq (SunOS, $(OS)) + LDLIBS=-lsocket -lnsl -lresolv + CFLAGS += -D__EXTENSIONS__ + CFLAGS += -std=c99 +endif + +# APIVERSION is used to build SONAME +APIVERSION = 16 + +SRCS = igd_desc_parse.c miniupnpc.c minixml.c minisoap.c miniwget.c \ + upnpcommands.c upnpreplyparse.c \ + minixmlvalid.c minissdpc.c \ + upnperrors.c \ + connecthostport.c portlistingparse.c receivedata.c \ + upnpdev.c miniupnpcmodule.c + +LIBOBJS = miniwget.o minixml.o igd_desc_parse.o minisoap.o \ + miniupnpc.o upnpreplyparse.o upnpcommands.o upnperrors.o \ + connecthostport.o portlistingparse.o receivedata.o upnpdev.o + +ifneq ($(OS), AmigaOS) +ifeq (,$(findstring CYGWIN,$(OS))) +CFLAGS := -fPIC $(CFLAGS) +endif +LIBOBJS := $(LIBOBJS) minissdpc.o +endif + +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +# HEADERS to install +HEADERS = miniupnpc.h miniwget.h upnpcommands.h igd_desc_parse.h \ + upnpreplyparse.h upnperrors.h miniupnpctypes.h \ + portlistingparse.h \ + upnpdev.h \ + miniupnpc_declspec.h + +# library names +LIBRARY = libminiupnpc.a +ifeq ($(OS), Darwin) + SHAREDLIBRARY = libminiupnpc.dylib + SONAME = $(basename $(SHAREDLIBRARY)).$(APIVERSION).dylib + CFLAGS := -D_DARWIN_C_SOURCE $(CFLAGS) +else +ifeq ($(JARSUFFIX), win32) + SHAREDLIBRARY = miniupnpc.dll +else + # Linux/BSD/etc. + SHAREDLIBRARY = libminiupnpc.so + SONAME = $(SHAREDLIBRARY).$(APIVERSION) +endif +endif + +EXECUTABLES = upnpc-static + +ifneq ($(OS), AmigaOS) +EXECUTABLES := $(EXECUTABLES) upnpc-shared +endif + +LIBDIR ?= lib +# install directories +ifeq ($(strip $(PREFIX)),) +INSTALLPREFIX ?= /usr +else +INSTALLPREFIX ?= $(PREFIX) +endif +INSTALLDIRINC = $(INSTALLPREFIX)/include/miniupnpc +INSTALLDIRLIB = $(INSTALLPREFIX)/$(LIBDIR) +INSTALLDIRBIN = $(INSTALLPREFIX)/bin +INSTALLDIRMAN = $(INSTALLPREFIX)/share/man + +FILESTOINSTALL = $(LIBRARY) $(EXECUTABLES) +ifneq ($(OS), AmigaOS) +FILESTOINSTALL := $(FILESTOINSTALL) $(SHAREDLIBRARY) +endif + + +.PHONY: install clean depend all check test everything \ + updateversion +# validateminixml validateminiwget + +all: $(LIBRARY) $(EXECUTABLES) + +test: check + +check: validateminixml validateminiwget validateupnpreplyparse \ + validateportlistingparse validateigddescparse + +everything: all + +validateminixml: minixmlvalid + @echo "minixml validation test" + ./minixmlvalid + touch $@ + +validateminiwget: testminiwget minihttptestserver testminiwget.sh + @echo "miniwget validation test" + ./testminiwget.sh + touch $@ + +validateupnpreplyparse: testupnpreplyparse testupnpreplyparse.sh + @echo "upnpreplyparse validation test" + ./testupnpreplyparse.sh + touch $@ + +validateportlistingparse: testportlistingparse + @echo "portlistingparse validation test" + ./testportlistingparse + touch $@ + +validateigddescparse: testigddescparse + @echo "igd desc parse validation test" + ./testigddescparse testdesc/new_LiveBox_desc.xml testdesc/new_LiveBox_desc.values + ./testigddescparse testdesc/linksys_WAG200G_desc.xml testdesc/linksys_WAG200G_desc.values + touch $@ + +clean: + $(RM) $(LIBRARY) $(SHAREDLIBRARY) $(EXECUTABLES) $(OBJS) miniupnpcstrings.h + +distclean: clean + +updateversion: miniupnpc.h + cp miniupnpc.h miniupnpc.h.bak + sed 's/\(.*MINIUPNPC_API_VERSION\s\+\)[0-9]\+/\1$(APIVERSION)/' < miniupnpc.h.bak > miniupnpc.h + +install: updateversion $(FILESTOINSTALL) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC) + $(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB) + $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB) +ifneq ($(OS), AmigaOS) + $(INSTALL) -m 644 $(SHAREDLIBRARY) $(DESTDIR)$(INSTALLDIRLIB)/$(SONAME) + ln -fs $(SONAME) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY) +endif + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN) +ifeq ($(OS), AmigaOS) + $(INSTALL) -m 755 upnpc-static $(DESTDIR)$(INSTALLDIRBIN)/upnpc +else + $(INSTALL) -m 755 upnpc-shared $(DESTDIR)$(INSTALLDIRBIN)/upnpc +endif + $(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip +ifneq ($(OS), AmigaOS) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRMAN)/man3 + $(INSTALL) -m 644 man3/miniupnpc.3 $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3 +ifeq ($(OS), Linux) + gzip -f $(DESTDIR)$(INSTALLDIRMAN)/man3/miniupnpc.3 +endif +endif + +install-static: updateversion $(FILESTOINSTALL) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRINC) + $(INSTALL) -m 644 $(HEADERS) $(DESTDIR)$(INSTALLDIRINC) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRLIB) + $(INSTALL) -m 644 $(LIBRARY) $(DESTDIR)$(INSTALLDIRLIB) + $(INSTALL) -d $(DESTDIR)$(INSTALLDIRBIN) + $(INSTALL) -m 755 external-ip.sh $(DESTDIR)$(INSTALLDIRBIN)/external-ip + +cleaninstall: + $(RM) -r $(DESTDIR)$(INSTALLDIRINC) + $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(LIBRARY) + $(RM) $(DESTDIR)$(INSTALLDIRLIB)/$(SHAREDLIBRARY) + +depend: + makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null + +$(LIBRARY): $(LIBOBJS) +ifeq ($(OS), Darwin) + $(LIBTOOL) -static -o $@ $? +else + $(AR) crs $@ $? +endif + +$(SHAREDLIBRARY): $(LIBOBJS) +ifeq ($(OS), Darwin) +# $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(SONAME) -o $@ $^ + $(CC) -dynamiclib $(LDFLAGS) -Wl,-install_name,$(INSTALLDIRLIB)/$(SONAME) -o $@ $^ +else + $(CC) -shared $(LDFLAGS) -Wl,-soname,$(SONAME) -o $@ $^ +endif + +upnpc-static: $(LIBRARY) + $(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS) + +upnpc-shared: $(SHAREDLIBRARY) + $(CC) $(LDFLAGS) -o $@ $^ $(LOADLIBES) $(LDLIBS) + +minixmlvalid: minixml.o minixmlvalid.o + +miniupnpcstrings.h: miniupnpcstrings.h.in updateminiupnpcstrings.sh VERSION + $(SH) updateminiupnpcstrings.sh + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +igd_desc_parse.o: igd_desc_parse.h +miniupnpc.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h upnpdev.h +miniupnpc.o: minissdpc.h miniwget.h minisoap.h minixml.h upnpcommands.h +miniupnpc.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h +miniupnpc.o: connecthostport.h +minixml.o: minixml.h +minisoap.o: minisoap.h miniupnpcstrings.h +miniwget.o: miniupnpcstrings.h miniwget.h miniupnpc_declspec.h +miniwget.o: connecthostport.h receivedata.h +upnpcommands.o: upnpcommands.h upnpreplyparse.h portlistingparse.h +upnpcommands.o: miniupnpc_declspec.h miniupnpctypes.h miniupnpc.h +upnpcommands.o: igd_desc_parse.h upnpdev.h +upnpreplyparse.o: upnpreplyparse.h minixml.h +minixmlvalid.o: minixml.h +minissdpc.o: minissdpc.h miniupnpc_declspec.h upnpdev.h miniupnpc.h +minissdpc.o: igd_desc_parse.h receivedata.h codelength.h +upnperrors.o: upnperrors.h miniupnpc_declspec.h upnpcommands.h +upnperrors.o: upnpreplyparse.h portlistingparse.h miniupnpctypes.h +upnperrors.o: miniupnpc.h igd_desc_parse.h upnpdev.h +connecthostport.o: connecthostport.h +portlistingparse.o: portlistingparse.h miniupnpc_declspec.h miniupnpctypes.h +portlistingparse.o: minixml.h +receivedata.o: receivedata.h +upnpdev.o: upnpdev.h miniupnpc_declspec.h +testportlistingparse.o: miniupnpctypes.h +miniupnpcmodule.o: miniupnpc.h miniupnpc_declspec.h igd_desc_parse.h +miniupnpcmodule.o: upnpdev.h upnpcommands.h upnpreplyparse.h +miniupnpcmodule.o: portlistingparse.h miniupnpctypes.h upnperrors.h diff --git a/deps/miniupnpc/README b/deps/miniupnpc/README new file mode 100644 index 0000000000..91535dbc8b --- /dev/null +++ b/deps/miniupnpc/README @@ -0,0 +1,64 @@ +Project: miniupnp +Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ +github: https://github.com/miniupnp/miniupnp +freecode: http://freecode.com/projects/miniupnp +Author: Thomas Bernard +Copyright (c) 2005-2016 Thomas Bernard +This software is subject to the conditions detailed in the +LICENSE file provided within this distribution. + + +* miniUPnP Client - miniUPnPc * + +To compile, simply run 'gmake' (could be 'make' on your system). +Under win32, to compile with MinGW, type "mingw32make.bat". +MS Visual C solution and project files are supplied in the msvc/ subdirectory. + +The compilation is known to work under linux, FreeBSD, +OpenBSD, MacOS X, AmigaOS and cygwin. +The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3. +upx (http://upx.sourceforge.net) is used to compress the win32 .exe files. + +To install the library and headers on the system use : +> su +> make install +> exit + +alternatively, to install into a specific location, use : +> INSTALLPREFIX=/usr/local make install + +upnpc.c is a sample client using the libminiupnpc. +To use the libminiupnpc in your application, link it with +libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h, +upnpcommands.h and miniwget.h : +- upnpDiscover() +- UPNP_GetValidIGD() +- miniwget() +- parserootdesc() +- GetUPNPUrls() +- UPNP_* (calling UPNP methods) + +Note : use #include etc... for the includes +and -lminiupnpc for the link + +Discovery process is speeded up when MiniSSDPd is running on the machine. + + +* Python module * + +you can build a python module with 'make pythonmodule' +and install it with 'make installpythonmodule'. +setup.py (and setupmingw32.py) are included in the distribution. + + +Feel free to contact me if you have any problem : +e-mail : miniupnp@free.fr + +If you are using libminiupnpc in your application, please +send me an email ! + +For any question, you can use the web forum : +http://miniupnp.tuxfamily.org/forum/ + +Bugs should be reported on github : +https://github.com/miniupnp/miniupnp/issues diff --git a/deps/miniupnpc/VERSION b/deps/miniupnpc/VERSION new file mode 100644 index 0000000000..cd5ac039d6 --- /dev/null +++ b/deps/miniupnpc/VERSION @@ -0,0 +1 @@ +2.0 diff --git a/deps/miniupnpc/apiversions.txt b/deps/miniupnpc/apiversions.txt new file mode 100644 index 0000000000..9464a86759 --- /dev/null +++ b/deps/miniupnpc/apiversions.txt @@ -0,0 +1,172 @@ +$Id: apiversions.txt,v 1.9 2016/01/24 17:24:36 nanard Exp $ + +Differences in API between miniUPnPc versions + +API version 16 + added "status_code" argument to getHTTPResponse(), miniwget() and miniwget_getaddr() + updated macro : + #define MINIUPNPC_API_VERSION 16 + +API version 15 + changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() + to "localport". When 0 or 1, behaviour is not changed, but it can take + any other value between 2 and 65535 + Existing programs should be compatible + updated macro : + #define MINIUPNPC_API_VERSION 15 + +API version 14 +miniupnpc.h + add ttl argument to upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() + upnpDiscoverDevices() + getDevicesFromMiniSSDPD() : + connectToMiniSSDPD() / disconnectFromMiniSSDPD() + requestDevicesFromMiniSSDPD() / receiveDevicesFromMiniSSDPD() + updated macro : + #define MINIUPNPC_API_VERSION 14 + +API version 13 +miniupnpc.h: + add searchalltype param to upnpDiscoverDevices() function + updated macro : + #define MINIUPNPC_API_VERSION 13 + +API version 12 +miniupnpc.h : + add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices() + functions + updated macros : + #define MINIUPNPC_API_VERSION 12 + +API version 11 + +upnpreplyparse.h / portlistingparse.h : + removed usage of sys/queue.h / bsdqueue.h + +miniupnpc.h: + updated macros : + #define MINIUPNPC_API_VERSION 11 + +====================== miniUPnPc version 1.9 ====================== +API version 10 + +upnpcommands.h: + added argument remoteHost to UPNP_GetSpecificPortMappingEntry() + +miniupnpc.h: + updated macros : + #define MINIUPNPC_VERSION "1.9" + #define MINIUPNPC_API_VERSION 10 + +====================== miniUPnPc version 1.8 ====================== +API version 9 + +miniupnpc.h: + updated macros : + #define MINIUPNPC_VERSION "1.8" + #define MINIUPNPC_API_VERSION 9 + added "unsigned int scope_id;" to struct UPNPDev + added scope_id argument to GetUPNPUrls() + + + +====================== miniUPnPc version 1.7 ====================== +API version 8 + +miniupnpc.h : + add new macros : + #define MINIUPNPC_VERSION "1.7" + #define MINIUPNPC_API_VERSION 8 + add rootdescURL to struct UPNPUrls + + + +====================== miniUPnPc version 1.6 ====================== +API version 8 + +Adding support for IPv6. +igd_desc_parse.h : + struct IGDdatas_service : + add char presentationurl[MINIUPNPC_URL_MAXSIZE]; + struct IGDdatas : + add struct IGDdatas_service IPv6FC; +miniupnpc.h : + new macros : + #define UPNPDISCOVER_SUCCESS (0) + #define UPNPDISCOVER_UNKNOWN_ERROR (-1) + #define UPNPDISCOVER_SOCKET_ERROR (-101) + #define UPNPDISCOVER_MEMORY_ERROR (-102) + simpleUPnPcommand() prototype changed (but is normaly not used by API users) + add arguments ipv6 and error to upnpDiscover() : + struct UPNPDev * + upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int sameport, + int ipv6, + int * error); + add controlURL_6FC member to struct UPNPUrls : + struct UPNPUrls { + char * controlURL; + char * ipcondescURL; + char * controlURL_CIF; + char * controlURL_6FC; + }; + +upnpcommands.h : + add leaseDuration argument to UPNP_AddPortMapping() + add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry() + add UPNP_GetListOfPortMappings() function (IGDv2) + add IGDv2 IPv6 related functions : + UPNP_GetFirewallStatus() + UPNP_GetOutboundPinholeTimeout() + UPNP_AddPinhole() + UPNP_UpdatePinhole() + UPNP_DeletePinhole() + UPNP_CheckPinholeWorking() + UPNP_GetPinholePackets() + + + +====================== miniUPnPc version 1.5 ====================== +API version 5 + +new function : +int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); +new macro in upnpcommands.h : +#define UPNPCOMMAND_HTTP_ERROR + +====================== miniUPnPc version 1.4 ====================== +Same API as version 1.3 + +====================== miniUPnPc version 1.3 ====================== +API version 4 + +Use UNSIGNED_INTEGER type for +UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(), +UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived() +Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping() + +====================== miniUPnPc version 1.2 ====================== +API version 3 + +added sameport argument to upnpDiscover() +struct UPNPDev * +upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int sameport); + +====================== miniUPnPc Version 1.1 ====================== +Same API as 1.0 + + +====================== miniUPnPc Version 1.0 ====================== +API version 2 + + +struct UPNPDev { + struct UPNPDev * pNext; + char * descURL; + char * st; + char buffer[2]; +}; +struct UPNPDev * upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock); + diff --git a/deps/miniupnpc/codelength.h b/deps/miniupnpc/codelength.h new file mode 100644 index 0000000000..ea0b005ffe --- /dev/null +++ b/deps/miniupnpc/codelength.h @@ -0,0 +1,54 @@ +/* $Id: codelength.h,v 1.3 2011/07/30 13:10:05 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas BERNARD + * copyright (c) 2005-2015 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#ifndef CODELENGTH_H_INCLUDED +#define CODELENGTH_H_INCLUDED + +/* Encode length by using 7bit per Byte : + * Most significant bit of each byte specifies that the + * following byte is part of the code */ + +/* n : unsigned + * p : unsigned char * + */ +#define DECODELENGTH(n, p) n = 0; \ + do { n = (n << 7) | (*p & 0x7f); } \ + while((*(p++)&0x80) && (n<(1<<25))); + +/* n : unsigned + * READ : function/macro to read one byte (unsigned char) + */ +#define DECODELENGTH_READ(n, READ) \ + n = 0; \ + do { \ + unsigned char c; \ + READ(c); \ + n = (n << 7) | (c & 0x07f); \ + if(!(c&0x80)) break; \ + } while(n<(1<<25)); + +/* n : unsigned + * p : unsigned char * + * p_limit : unsigned char * + */ +#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \ + n = 0; \ + do { \ + if((p) >= (p_limit)) break; \ + n = (n << 7) | (*(p) & 0x7f); \ + } while((*((p)++)&0x80) && (n<(1<<25))); + + +/* n : unsigned + * p : unsigned char * + */ +#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \ + if(n>=2097152) *(p++) = (n >> 21) | 0x80; \ + if(n>=16384) *(p++) = (n >> 14) | 0x80; \ + if(n>=128) *(p++) = (n >> 7) | 0x80; \ + *(p++) = n & 0x7f; + +#endif /* CODELENGTH_H_INCLUDED */ diff --git a/deps/miniupnpc/connecthostport.c b/deps/miniupnpc/connecthostport.c new file mode 100644 index 0000000000..e3c17d36be --- /dev/null +++ b/deps/miniupnpc/connecthostport.c @@ -0,0 +1,264 @@ +/* $Id: connecthostport.c,v 1.15 2015/10/09 16:26:19 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2010-2016 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ + +/* use getaddrinfo() or gethostbyname() + * uncomment the following line in order to use gethostbyname() */ +#ifdef NO_GETADDRINFO +#define USE_GETHOSTBYNAME +#endif + +#include +#include +#ifdef _WIN32 +#include +#include +#include +#define MAXHOSTNAMELEN 64 +#define snprintf _snprintf +#define herror +#define socklen_t int +#else /* #ifdef _WIN32 */ +#include +#include +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT +#include +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ +#include +#include +#include +#define closesocket close +#include +#include +/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions + * during the connect() call */ +#define MINIUPNPC_IGNORE_EINTR +#ifndef USE_GETHOSTBYNAME +#include +#include +#endif /* #ifndef USE_GETHOSTBYNAME */ +#endif /* #else _WIN32 */ + +/* definition of PRINT_SOCKET_ERROR */ +#ifdef _WIN32 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#else +#define PRINT_SOCKET_ERROR(x) perror(x) +#endif + +#if defined(__amigaos__) || defined(__amigaos4__) +#define herror(A) printf("%s\n", A) +#endif + +#include "connecthostport.h" + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +/* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ +int connecthostport(const char * host, unsigned short port, + unsigned int scope_id) +{ + int s, n; +#ifdef USE_GETHOSTBYNAME + struct sockaddr_in dest; + struct hostent *hp; +#else /* #ifdef USE_GETHOSTBYNAME */ + char tmp_host[MAXHOSTNAMELEN+1]; + char port_str[8]; + struct addrinfo *ai, *p; + struct addrinfo hints; +#endif /* #ifdef USE_GETHOSTBYNAME */ +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + struct timeval timeout; +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + +#ifdef USE_GETHOSTBYNAME + hp = gethostbyname(host); + if(hp == NULL) + { + herror(host); + return -1; + } + memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr)); + memset(dest.sin_zero, 0, sizeof(dest.sin_zero)); + s = socket(PF_INET, SOCK_STREAM, 0); + if(s < 0) + { + PRINT_SOCKET_ERROR("socket"); + return -1; + } +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + /* setting a 3 seconds timeout for the connect() call */ + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO"); + } + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO"); + } +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + dest.sin_family = AF_INET; + dest.sin_port = htons(port); + n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in)); +#ifdef MINIUPNPC_IGNORE_EINTR + /* EINTR The system call was interrupted by a signal that was caught + * EINPROGRESS The socket is nonblocking and the connection cannot + * be completed immediately. */ + while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) + { + socklen_t len; + fd_set wset; + int err; + FD_ZERO(&wset); + FD_SET(s, &wset); + if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + continue; + /*len = 0;*/ + /*n = getpeername(s, NULL, &len);*/ + len = sizeof(err); + if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + PRINT_SOCKET_ERROR("getsockopt"); + closesocket(s); + return -1; + } + if(err != 0) { + errno = err; + n = -1; + } + } +#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ + if(n<0) + { + PRINT_SOCKET_ERROR("connect"); + closesocket(s); + return -1; + } +#else /* #ifdef USE_GETHOSTBYNAME */ + /* use getaddrinfo() instead of gethostbyname() */ + memset(&hints, 0, sizeof(hints)); + /* hints.ai_flags = AI_ADDRCONFIG; */ +#ifdef AI_NUMERICSERV + hints.ai_flags = AI_NUMERICSERV; +#endif + hints.ai_socktype = SOCK_STREAM; + hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */ + /* hints.ai_protocol = IPPROTO_TCP; */ + snprintf(port_str, sizeof(port_str), "%hu", port); + if(host[0] == '[') + { + /* literal ip v6 address */ + int i, j; + for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++) + { + tmp_host[i] = host[j]; + if(0 == memcmp(host+j, "%25", 3)) /* %25 is just url encoding for '%' */ + j+=2; /* skip "25" */ + } + tmp_host[i] = '\0'; + } + else + { + strncpy(tmp_host, host, MAXHOSTNAMELEN); + } + tmp_host[MAXHOSTNAMELEN] = '\0'; + n = getaddrinfo(tmp_host, port_str, &hints, &ai); + if(n != 0) + { +#ifdef _WIN32 + fprintf(stderr, "getaddrinfo() error : %d\n", n); +#else + fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n)); +#endif + return -1; + } + s = -1; + for(p = ai; p; p = p->ai_next) + { + s = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if(s < 0) + continue; + if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) { + struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr; + addr6->sin6_scope_id = scope_id; + } +#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT + /* setting a 3 seconds timeout for the connect() call */ + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt"); + } +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + n = connect(s, p->ai_addr, p->ai_addrlen); +#ifdef MINIUPNPC_IGNORE_EINTR + /* EINTR The system call was interrupted by a signal that was caught + * EINPROGRESS The socket is nonblocking and the connection cannot + * be completed immediately. */ + while(n < 0 && (errno == EINTR || errno == EINPROGRESS)) + { + socklen_t len; + fd_set wset; + int err; + FD_ZERO(&wset); + FD_SET(s, &wset); + if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR) + continue; + /*len = 0;*/ + /*n = getpeername(s, NULL, &len);*/ + len = sizeof(err); + if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) { + PRINT_SOCKET_ERROR("getsockopt"); + closesocket(s); + freeaddrinfo(ai); + return -1; + } + if(err != 0) { + errno = err; + n = -1; + } + } +#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */ + if(n < 0) + { + closesocket(s); + continue; + } + else + { + break; + } + } + freeaddrinfo(ai); + if(s < 0) + { + PRINT_SOCKET_ERROR("socket"); + return -1; + } + if(n < 0) + { + PRINT_SOCKET_ERROR("connect"); + return -1; + } +#endif /* #ifdef USE_GETHOSTBYNAME */ + return s; +} + diff --git a/deps/miniupnpc/connecthostport.h b/deps/miniupnpc/connecthostport.h new file mode 100644 index 0000000000..f3b2d2a842 --- /dev/null +++ b/deps/miniupnpc/connecthostport.h @@ -0,0 +1,18 @@ +/* $Id: connecthostport.h,v 1.2 2012/06/23 22:32:33 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ + * Author: Thomas Bernard + * Copyright (c) 2010-2012 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef CONNECTHOSTPORT_H_INCLUDED +#define CONNECTHOSTPORT_H_INCLUDED + +/* connecthostport() + * return a socket connected (TCP) to the host and port + * or -1 in case of error */ +int connecthostport(const char * host, unsigned short port, + unsigned int scope_id); + +#endif + diff --git a/deps/miniupnpc/igd_desc_parse.c b/deps/miniupnpc/igd_desc_parse.c new file mode 100644 index 0000000000..d2999ad011 --- /dev/null +++ b/deps/miniupnpc/igd_desc_parse.c @@ -0,0 +1,123 @@ +/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */ +/* Project : miniupnp + * http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ + +#include "igd_desc_parse.h" +#include +#include + +/* Start element handler : + * update nesting level counter and copy element name */ +void IGDstartelt(void * d, const char * name, int l) +{ + struct IGDdatas * datas = (struct IGDdatas *)d; + if(l >= MINIUPNPC_URL_MAXSIZE) + l = MINIUPNPC_URL_MAXSIZE-1; + memcpy(datas->cureltname, name, l); + datas->cureltname[l] = '\0'; + datas->level++; + if( (l==7) && !memcmp(name, "service", l) ) { + datas->tmp.controlurl[0] = '\0'; + datas->tmp.eventsuburl[0] = '\0'; + datas->tmp.scpdurl[0] = '\0'; + datas->tmp.servicetype[0] = '\0'; + } +} + +#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) + +/* End element handler : + * update nesting level counter and update parser state if + * service element is parsed */ +void IGDendelt(void * d, const char * name, int l) +{ + struct IGDdatas * datas = (struct IGDdatas *)d; + datas->level--; + /*printf("endelt %2d %.*s\n", datas->level, l, name);*/ + if( (l==7) && !memcmp(name, "service", l) ) + { + if(COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) { + memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service)); + } else if(COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) { + memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service)); + } else if(COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANIPConnection:") + || COMPARE(datas->tmp.servicetype, + "urn:schemas-upnp-org:service:WANPPPConnection:") ) { + if(datas->first.servicetype[0] == '\0') { + memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service)); + } else { + memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service)); + } + } + } +} + +/* Data handler : + * copy data depending on the current element name and state */ +void IGDdata(void * d, const char * data, int l) +{ + struct IGDdatas * datas = (struct IGDdatas *)d; + char * dstmember = 0; + /*printf("%2d %s : %.*s\n", + datas->level, datas->cureltname, l, data); */ + if( !strcmp(datas->cureltname, "URLBase") ) + dstmember = datas->urlbase; + else if( !strcmp(datas->cureltname, "presentationURL") ) + dstmember = datas->presentationurl; + else if( !strcmp(datas->cureltname, "serviceType") ) + dstmember = datas->tmp.servicetype; + else if( !strcmp(datas->cureltname, "controlURL") ) + dstmember = datas->tmp.controlurl; + else if( !strcmp(datas->cureltname, "eventSubURL") ) + dstmember = datas->tmp.eventsuburl; + else if( !strcmp(datas->cureltname, "SCPDURL") ) + dstmember = datas->tmp.scpdurl; +/* else if( !strcmp(datas->cureltname, "deviceType") ) + dstmember = datas->devicetype_tmp;*/ + if(dstmember) + { + if(l>=MINIUPNPC_URL_MAXSIZE) + l = MINIUPNPC_URL_MAXSIZE-1; + memcpy(dstmember, data, l); + dstmember[l] = '\0'; + } +} + +#ifdef DEBUG +void printIGD(struct IGDdatas * d) +{ + printf("urlbase = '%s'\n", d->urlbase); + printf("WAN Device (Common interface config) :\n"); + /*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/ + printf(" serviceType = '%s'\n", d->CIF.servicetype); + printf(" controlURL = '%s'\n", d->CIF.controlurl); + printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl); + printf(" SCPDURL = '%s'\n", d->CIF.scpdurl); + printf("primary WAN Connection Device (IP or PPP Connection):\n"); + /*printf(" deviceType = '%s'\n", d->first.devicetype);*/ + printf(" servicetype = '%s'\n", d->first.servicetype); + printf(" controlURL = '%s'\n", d->first.controlurl); + printf(" eventSubURL = '%s'\n", d->first.eventsuburl); + printf(" SCPDURL = '%s'\n", d->first.scpdurl); + printf("secondary WAN Connection Device (IP or PPP Connection):\n"); + /*printf(" deviceType = '%s'\n", d->second.devicetype);*/ + printf(" servicetype = '%s'\n", d->second.servicetype); + printf(" controlURL = '%s'\n", d->second.controlurl); + printf(" eventSubURL = '%s'\n", d->second.eventsuburl); + printf(" SCPDURL = '%s'\n", d->second.scpdurl); + printf("WAN IPv6 Firewall Control :\n"); + /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/ + printf(" servicetype = '%s'\n", d->IPv6FC.servicetype); + printf(" controlURL = '%s'\n", d->IPv6FC.controlurl); + printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl); + printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl); +} +#endif /* DEBUG */ + diff --git a/deps/miniupnpc/igd_desc_parse.h b/deps/miniupnpc/igd_desc_parse.h new file mode 100644 index 0000000000..0de546b697 --- /dev/null +++ b/deps/miniupnpc/igd_desc_parse.h @@ -0,0 +1,49 @@ +/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */ +/* Project : miniupnp + * http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2014 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef IGD_DESC_PARSE_H_INCLUDED +#define IGD_DESC_PARSE_H_INCLUDED + +/* Structure to store the result of the parsing of UPnP + * descriptions of Internet Gateway Devices */ +#define MINIUPNPC_URL_MAXSIZE (128) +struct IGDdatas_service { + char controlurl[MINIUPNPC_URL_MAXSIZE]; + char eventsuburl[MINIUPNPC_URL_MAXSIZE]; + char scpdurl[MINIUPNPC_URL_MAXSIZE]; + char servicetype[MINIUPNPC_URL_MAXSIZE]; + /*char devicetype[MINIUPNPC_URL_MAXSIZE];*/ +}; + +struct IGDdatas { + char cureltname[MINIUPNPC_URL_MAXSIZE]; + char urlbase[MINIUPNPC_URL_MAXSIZE]; + char presentationurl[MINIUPNPC_URL_MAXSIZE]; + int level; + /*int state;*/ + /* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */ + struct IGDdatas_service CIF; + /* "urn:schemas-upnp-org:service:WANIPConnection:1" + * "urn:schemas-upnp-org:service:WANPPPConnection:1" */ + struct IGDdatas_service first; + /* if both WANIPConnection and WANPPPConnection are present */ + struct IGDdatas_service second; + /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */ + struct IGDdatas_service IPv6FC; + /* tmp */ + struct IGDdatas_service tmp; +}; + +void IGDstartelt(void *, const char *, int); +void IGDendelt(void *, const char *, int); +void IGDdata(void *, const char *, int); +#ifdef DEBUG +void printIGD(struct IGDdatas *); +#endif /* DEBUG */ + +#endif /* IGD_DESC_PARSE_H_INCLUDED */ diff --git a/deps/miniupnpc/minisoap.c b/deps/miniupnpc/minisoap.c new file mode 100644 index 0000000000..5c9a11438f --- /dev/null +++ b/deps/miniupnpc/minisoap.c @@ -0,0 +1,123 @@ +/* $Id: minisoap.c,v 1.23 2014/11/04 22:31:55 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * + * Minimal SOAP implementation for UPnP protocol. + */ +#include +#include +#ifdef _WIN32 +#include +#include +#define snprintf _snprintf +#else +#include +#include +#include +#endif +#include "minisoap.h" +#include "miniupnpcstrings.h" + +/* only for malloc */ +#include + +#ifdef _WIN32 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#else +#define PRINT_SOCKET_ERROR(x) perror(x) +#endif + +/* httpWrite sends the headers and the body to the socket + * and returns the number of bytes sent */ +static int +httpWrite(int fd, const char * body, int bodysize, + const char * headers, int headerssize) +{ + int n = 0; + /*n = write(fd, headers, headerssize);*/ + /*if(bodysize>0) + n += write(fd, body, bodysize);*/ + /* Note : my old linksys router only took into account + * soap request that are sent into only one packet */ + char * p; + /* TODO: AVOID MALLOC, we could use writev() for that */ + p = malloc(headerssize+bodysize); + if(!p) + return -1; + memcpy(p, headers, headerssize); + memcpy(p+headerssize, body, bodysize); + /*n = write(fd, p, headerssize+bodysize);*/ + n = send(fd, p, headerssize+bodysize, 0); + if(n<0) { + PRINT_SOCKET_ERROR("send"); + } + /* disable send on the socket */ + /* draytek routers dont seems to like that... */ +#if 0 +#ifdef _WIN32 + if(shutdown(fd, SD_SEND)<0) { +#else + if(shutdown(fd, SHUT_WR)<0) { /*SD_SEND*/ +#endif + PRINT_SOCKET_ERROR("shutdown"); + } +#endif + free(p); + return n; +} + +/* self explanatory */ +int soapPostSubmit(int fd, + const char * url, + const char * host, + unsigned short port, + const char * action, + const char * body, + const char * httpversion) +{ + int bodysize; + char headerbuf[512]; + int headerssize; + char portstr[8]; + bodysize = (int)strlen(body); + /* We are not using keep-alive HTTP connections. + * HTTP/1.1 needs the header Connection: close to do that. + * This is the default with HTTP/1.0 + * Using HTTP/1.1 means we need to support chunked transfer-encoding : + * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked + * transfer encoding. */ + /* Connection: Close is normally there only in HTTP/1.1 but who knows */ + portstr[0] = '\0'; + if(port != 80) + snprintf(portstr, sizeof(portstr), ":%hu", port); + headerssize = snprintf(headerbuf, sizeof(headerbuf), + "POST %s HTTP/%s\r\n" + "Host: %s%s\r\n" + "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" + "Content-Length: %d\r\n" + "Content-Type: text/xml\r\n" + "SOAPAction: \"%s\"\r\n" + "Connection: Close\r\n" + "Cache-Control: no-cache\r\n" /* ??? */ + "Pragma: no-cache\r\n" + "\r\n", + url, httpversion, host, portstr, bodysize, action); + if ((unsigned int)headerssize >= sizeof(headerbuf)) + return -1; +#ifdef DEBUG + /*printf("SOAP request : headersize=%d bodysize=%d\n", + headerssize, bodysize); + */ + printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n", + url, httpversion, host, portstr); + printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize); + printf("Headers :\n%s", headerbuf); + printf("Body :\n%s\n", body); +#endif + return httpWrite(fd, body, bodysize, headerbuf, headerssize); +} + + diff --git a/deps/miniupnpc/minisoap.h b/deps/miniupnpc/minisoap.h new file mode 100644 index 0000000000..60554f5c39 --- /dev/null +++ b/deps/miniupnpc/minisoap.h @@ -0,0 +1,15 @@ +/* $Id: minisoap.h,v 1.4 2010/04/12 20:39:41 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ +#ifndef MINISOAP_H_INCLUDED +#define MINISOAP_H_INCLUDED + +/*int httpWrite(int, const char *, int, const char *);*/ +int soapPostSubmit(int, const char *, const char *, unsigned short, + const char *, const char *, const char *); + +#endif + diff --git a/deps/miniupnpc/minissdpc.c b/deps/miniupnpc/minissdpc.c new file mode 100644 index 0000000000..89b9d249ae --- /dev/null +++ b/deps/miniupnpc/minissdpc.c @@ -0,0 +1,876 @@ +/* $Id: minissdpc.c,v 1.32 2016/10/07 09:04:36 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp + * Web : http://miniupnp.free.fr/ + * Author : Thomas BERNARD + * copyright (c) 2005-2017 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +/*#include */ +#include +#include +#include +#include +#if defined (__NetBSD__) +#include +#endif +#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) +#ifdef _WIN32 +#include +#include +#include +#include +#include +#define snprintf _snprintf +#if !defined(_MSC_VER) +#include +#else /* !defined(_MSC_VER) */ +typedef unsigned short uint16_t; +#endif /* !defined(_MSC_VER) */ +#ifndef strncasecmp +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define strncasecmp _memicmp +#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#define strncasecmp memicmp +#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#endif /* #ifndef strncasecmp */ +#endif /* _WIN32 */ +#if defined(__amigaos__) || defined(__amigaos4__) +#include +#endif /* defined(__amigaos__) || defined(__amigaos4__) */ +#if defined(__amigaos__) +#define uint16_t unsigned short +#endif /* defined(__amigaos__) */ +/* Hack */ +#define UNIX_PATH_LEN 108 +struct sockaddr_un { + uint16_t sun_family; + char sun_path[UNIX_PATH_LEN]; +}; +#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define closesocket close +#endif + +#ifdef _WIN32 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#else +#define PRINT_SOCKET_ERROR(x) perror(x) +#endif + +#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__) +#define HAS_IP_MREQN +#endif + +#if !defined(HAS_IP_MREQN) && !defined(_WIN32) +#include +#if defined(__sun) +#include +#endif +#endif + +#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN) +/* Several versions of glibc don't define this structure, + * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */ +struct ip_mreqn +{ + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_address; /* local IP address of interface */ + int imr_ifindex; /* Interface index */ +}; +#endif + +#if defined(__amigaos__) || defined(__amigaos4__) +/* Amiga OS specific stuff */ +#define TIMEVAL struct timeval +#endif + +#include "minissdpc.h" +#include "miniupnpc.h" +#include "receivedata.h" + +#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) + +#include "codelength.h" + +struct UPNPDev * +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error) +{ + struct UPNPDev * devlist = NULL; + int s; + int res; + + s = connectToMiniSSDPD(socketpath); + if (s < 0) { + if (error) + *error = s; + return NULL; + } + res = requestDevicesFromMiniSSDPD(s, devtype); + if (res < 0) { + if (error) + *error = res; + } else { + devlist = receiveDevicesFromMiniSSDPD(s, error); + } + disconnectFromMiniSSDPD(s); + return devlist; +} + +/* macros used to read from unix socket */ +#define READ_BYTE_BUFFER(c) \ + if((int)bufferindex >= n) { \ + n = read(s, buffer, sizeof(buffer)); \ + if(n<=0) break; \ + bufferindex = 0; \ + } \ + c = buffer[bufferindex++]; + +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif /* MIN */ + +#define READ_COPY_BUFFER(dst, len) \ + for(l = len, p = (unsigned char *)dst; l > 0; ) { \ + unsigned int lcopy; \ + if((int)bufferindex >= n) { \ + n = read(s, buffer, sizeof(buffer)); \ + if(n<=0) break; \ + bufferindex = 0; \ + } \ + lcopy = MIN(l, (n - bufferindex)); \ + memcpy(p, buffer + bufferindex, lcopy); \ + l -= lcopy; \ + p += lcopy; \ + bufferindex += lcopy; \ + } + +#define READ_DISCARD_BUFFER(len) \ + for(l = len; l > 0; ) { \ + unsigned int lcopy; \ + if(bufferindex >= n) { \ + n = read(s, buffer, sizeof(buffer)); \ + if(n<=0) break; \ + bufferindex = 0; \ + } \ + lcopy = MIN(l, (n - bufferindex)); \ + l -= lcopy; \ + bufferindex += lcopy; \ + } + +int +connectToMiniSSDPD(const char * socketpath) +{ + int s; + struct sockaddr_un addr; +#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) + struct timeval timeout; +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if(s < 0) + { + /*syslog(LOG_ERR, "socket(unix): %m");*/ + perror("socket(unix)"); + return MINISSDPC_SOCKET_ERROR; + } +#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun) + /* setting a 3 seconds timeout */ + /* not supported for AF_UNIX sockets under Solaris */ + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + perror("setsockopt SO_RCVTIMEO unix"); + } + timeout.tv_sec = 3; + timeout.tv_usec = 0; + if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0) + { + perror("setsockopt SO_SNDTIMEO unix"); + } +#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */ + if(!socketpath) + socketpath = "/var/run/minissdpd.sock"; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path)); + /* TODO : check if we need to handle the EINTR */ + if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) + { + /*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/ + close(s); + return MINISSDPC_SOCKET_ERROR; + } + return s; +} + +int +disconnectFromMiniSSDPD(int s) +{ + if (close(s) < 0) + return MINISSDPC_SOCKET_ERROR; + return MINISSDPC_SUCCESS; +} + +int +requestDevicesFromMiniSSDPD(int s, const char * devtype) +{ + unsigned char buffer[256]; + unsigned char * p; + unsigned int stsize, l; + + stsize = strlen(devtype); + if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8)) + { + buffer[0] = 3; /* request type 3 : everything */ + } + else + { + buffer[0] = 1; /* request type 1 : request devices/services by type */ + } + p = buffer + 1; + l = stsize; CODELENGTH(l, p); + if(p + stsize > buffer + sizeof(buffer)) + { + /* devtype is too long ! */ +#ifdef DEBUG + fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n", + stsize, (unsigned)sizeof(buffer)); +#endif /* DEBUG */ + return MINISSDPC_INVALID_INPUT; + } + memcpy(p, devtype, stsize); + p += stsize; + if(write(s, buffer, p - buffer) < 0) + { + /*syslog(LOG_ERR, "write(): %m");*/ + perror("minissdpc.c: write()"); + return MINISSDPC_SOCKET_ERROR; + } + return MINISSDPC_SUCCESS; +} + +struct UPNPDev * +receiveDevicesFromMiniSSDPD(int s, int * error) +{ + struct UPNPDev * tmp; + struct UPNPDev * devlist = NULL; + unsigned char buffer[256]; + ssize_t n; + unsigned char * p; + unsigned char * url; + unsigned char * st; + unsigned int bufferindex; + unsigned int i, ndev; + unsigned int urlsize, stsize, usnsize, l; + + n = read(s, buffer, sizeof(buffer)); + if(n<=0) + { + perror("minissdpc.c: read()"); + if (error) + *error = MINISSDPC_SOCKET_ERROR; + return NULL; + } + ndev = buffer[0]; + bufferindex = 1; + for(i = 0; i < ndev; i++) + { + DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + return devlist; + } +#ifdef DEBUG + printf(" urlsize=%u", urlsize); +#endif /* DEBUG */ + url = malloc(urlsize); + if(url == NULL) { + if (error) + *error = MINISSDPC_MEMORY_ERROR; + return devlist; + } + READ_COPY_BUFFER(url, urlsize); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + goto free_url_and_return; + } + DECODELENGTH_READ(stsize, READ_BYTE_BUFFER); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + goto free_url_and_return; + } +#ifdef DEBUG + printf(" stsize=%u", stsize); +#endif /* DEBUG */ + st = malloc(stsize); + if (st == NULL) { + if (error) + *error = MINISSDPC_MEMORY_ERROR; + goto free_url_and_return; + } + READ_COPY_BUFFER(st, stsize); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + goto free_url_and_st_and_return; + } + DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + goto free_url_and_st_and_return; + } +#ifdef DEBUG + printf(" usnsize=%u\n", usnsize); +#endif /* DEBUG */ + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); + if(tmp == NULL) { + if (error) + *error = MINISSDPC_MEMORY_ERROR; + goto free_url_and_st_and_return; + } + tmp->pNext = devlist; + tmp->descURL = tmp->buffer; + tmp->st = tmp->buffer + 1 + urlsize; + memcpy(tmp->buffer, url, urlsize); + tmp->buffer[urlsize] = '\0'; + memcpy(tmp->st, st, stsize); + tmp->buffer[urlsize+1+stsize] = '\0'; + free(url); + free(st); + url = NULL; + st = NULL; + tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize; + READ_COPY_BUFFER(tmp->usn, usnsize); + if(n<=0) { + if (error) + *error = MINISSDPC_INVALID_SERVER_REPLY; + goto free_tmp_and_return; + } + tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->scope_id = 0; /* default value. scope_id is not available with MiniSSDPd */ + devlist = tmp; + } + if (error) + *error = MINISSDPC_SUCCESS; + return devlist; + +free_url_and_st_and_return: + free(st); +free_url_and_return: + free(url); + return devlist; + +free_tmp_and_return: + free(tmp); + return devlist; +} + +#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ + +/* parseMSEARCHReply() + * the last 4 arguments are filled during the parsing : + * - location/locationsize : "location:" field of the SSDP reply packet + * - st/stsize : "st:" field of the SSDP reply packet. + * The strings are NOT null terminated */ +static void +parseMSEARCHReply(const char * reply, int size, + const char * * location, int * locationsize, + const char * * st, int * stsize, + const char * * usn, int * usnsize) +{ + int a, b, i; + i = 0; + a = i; /* start of the line */ + b = 0; /* end of the "header" (position of the colon) */ + while(isin6_family = AF_INET6; + if(localport > 0 && localport < 65536) + p->sin6_port = htons((unsigned short)localport); + p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */ + } else { + struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r; + p->sin_family = AF_INET; + if(localport > 0 && localport < 65536) + p->sin_port = htons((unsigned short)localport); + p->sin_addr.s_addr = INADDR_ANY; + } +#ifdef _WIN32 +/* This code could help us to use the right Network interface for + * SSDP multicast traffic */ +/* Get IP associated with the index given in the ip_forward struct + * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */ + if(!ipv6 + && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) { + DWORD dwRetVal = 0; + PMIB_IPADDRTABLE pIPAddrTable; + DWORD dwSize = 0; +#ifdef DEBUG + IN_ADDR IPAddr; +#endif + int i; +#ifdef DEBUG + printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop); +#endif + pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE)); + if(pIPAddrTable) { + if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { + free(pIPAddrTable); + pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize); + } + } + if(pIPAddrTable) { + dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 ); + if (dwRetVal == NO_ERROR) { +#ifdef DEBUG + printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries); +#endif + for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) { +#ifdef DEBUG + printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr; + printf("\tIP Address[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask; + printf("\tSubnet Mask[%d]: \t%s\n", i, inet_ntoa(IPAddr) ); + IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr; + printf("\tBroadCast[%d]: \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr); + printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize); + printf("\tType and State[%d]:", i); + printf("\n"); +#endif + if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) { + /* Set the address of this interface to be used */ + struct in_addr mc_if; + memset(&mc_if, 0, sizeof(mc_if)); + mc_if.s_addr = pIPAddrTable->table[i].dwAddr; + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) { + PRINT_SOCKET_ERROR("setsockopt"); + } + ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr; +#ifndef DEBUG + break; +#endif + } + } + } + free(pIPAddrTable); + pIPAddrTable = NULL; + } + } +#endif /* _WIN32 */ + +#ifdef _WIN32 + if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0) +#else + if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0) +#endif + { + if(error) + *error = MINISSDPC_SOCKET_ERROR; + PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)"); + return NULL; + } + +#ifdef _WIN32 + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0) +#else /* _WIN32 */ + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) +#endif /* _WIN32 */ + { + /* not a fatal error */ + PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)"); + } + + if(multicastif) + { + if(ipv6) { +#if !defined(_WIN32) + /* according to MSDN, if_nametoindex() is supported since + * MS Windows Vista and MS Windows Server 2008. + * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */ + unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */ + if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF"); + } +#else +#ifdef DEBUG + printf("Setting of multicast interface not supported in IPv6 under Windows.\n"); +#endif +#endif + } else { + struct in_addr mc_if; + mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */ + if(mc_if.s_addr != INADDR_NONE) + { + ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr; + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); + } + } else { +#ifdef HAS_IP_MREQN + /* was not an ip address, try with an interface name */ + struct ip_mreqn reqn; /* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */ + memset(&reqn, 0, sizeof(struct ip_mreqn)); + reqn.imr_ifindex = if_nametoindex(multicastif); + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); + } +#elif !defined(_WIN32) + struct ifreq ifr; + int ifrlen = sizeof(ifr); + strncpy(ifr.ifr_name, multicastif, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; + if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0) + { + PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)"); + } + mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; + if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) + { + PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF"); + } +#else /* _WIN32 */ +#ifdef DEBUG + printf("Setting of multicast interface not supported with interface name.\n"); +#endif +#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */ + } + } + } + + /* Before sending the packed, we first "bind" in order to be able + * to receive the response */ + if (bind(sudp, (const struct sockaddr *)&sockudp_r, + ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0) + { + if(error) + *error = MINISSDPC_SOCKET_ERROR; + PRINT_SOCKET_ERROR("bind"); + closesocket(sudp); + return NULL; + } + + if(error) + *error = MINISSDPC_SUCCESS; + /* Calculating maximum response time in seconds */ + mx = ((unsigned int)delay) / 1000u; + if(mx == 0) { + mx = 1; + delay = 1000; + } + /* receiving SSDP response packet */ + for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { + /* sending the SSDP M-SEARCH packet */ + n = snprintf(bufr, sizeof(bufr), + MSearchMsgFmt, + ipv6 ? + (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") + : UPNP_MCAST_ADDR, + deviceTypes[deviceIndex], mx); + if ((unsigned int)n >= sizeof(bufr)) { + if(error) + *error = MINISSDPC_MEMORY_ERROR; + goto error; + } +#ifdef DEBUG + /*printf("Sending %s", bufr);*/ + printf("Sending M-SEARCH request to %s with ST: %s\n", + ipv6 ? + (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" : "[" UPNP_MCAST_SL_ADDR "]") + : UPNP_MCAST_ADDR, + deviceTypes[deviceIndex]); +#endif +#ifdef NO_GETADDRINFO + /* the following code is not using getaddrinfo */ + /* emission */ + memset(&sockudp_w, 0, sizeof(struct sockaddr_storage)); + if(ipv6) { + struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w; + p->sin6_family = AF_INET6; + p->sin6_port = htons(SSDP_PORT); + inet_pton(AF_INET6, + linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR, + &(p->sin6_addr)); + } else { + struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w; + p->sin_family = AF_INET; + p->sin_port = htons(SSDP_PORT); + p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR); + } + n = sendto(sudp, bufr, n, 0, &sockudp_w, + ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + if (n < 0) { + if(error) + *error = MINISSDPC_SOCKET_ERROR; + PRINT_SOCKET_ERROR("sendto"); + break; + } +#else /* #ifdef NO_GETADDRINFO */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */ + hints.ai_socktype = SOCK_DGRAM; + /*hints.ai_flags = */ + if ((rv = getaddrinfo(ipv6 + ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR) + : UPNP_MCAST_ADDR, + XSTR(SSDP_PORT), &hints, &servinfo)) != 0) { + if(error) + *error = MINISSDPC_SOCKET_ERROR; +#ifdef _WIN32 + fprintf(stderr, "getaddrinfo() failed: %d\n", rv); +#else + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); +#endif + break; + } + for(p = servinfo; p; p = p->ai_next) { + n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen); + if (n < 0) { +#ifdef DEBUG + char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; + if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf, + sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) { + fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf); + } +#endif + PRINT_SOCKET_ERROR("sendto"); + continue; + } + } + freeaddrinfo(servinfo); + if(n < 0) { + if(error) + *error = MINISSDPC_SOCKET_ERROR; + break; + } +#endif /* #ifdef NO_GETADDRINFO */ + /* Waiting for SSDP REPLY packet to M-SEARCH + * if searchalltypes is set, enter the loop only + * when the last deviceType is reached */ + if(!searchalltypes || !deviceTypes[deviceIndex + 1]) do { + n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); + if (n < 0) { + /* error */ + if(error) + *error = MINISSDPC_SOCKET_ERROR; + goto error; + } else if (n == 0) { + /* no data or Time Out */ +#ifdef DEBUG + printf("NODATA or TIMEOUT\n"); +#endif /* DEBUG */ + if (devlist && !searchalltypes) { + /* found some devices, stop now*/ + if(error) + *error = MINISSDPC_SUCCESS; + goto error; + } + } else { + const char * descURL=NULL; + int urlsize=0; + const char * st=NULL; + int stsize=0; + const char * usn=NULL; + int usnsize=0; + parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize); + if(st&&descURL) { +#ifdef DEBUG + printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", + stsize, st, usnsize, (usn?usn:""), urlsize, descURL); +#endif /* DEBUG */ + for(tmp=devlist; tmp; tmp = tmp->pNext) { + if(memcmp(tmp->descURL, descURL, urlsize) == 0 && + tmp->descURL[urlsize] == '\0' && + memcmp(tmp->st, st, stsize) == 0 && + tmp->st[stsize] == '\0' && + (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) && + tmp->usn[usnsize] == '\0') + break; + } + /* at the exit of the loop above, tmp is null if + * no duplicate device was found */ + if(tmp) + continue; + tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize); + if(!tmp) { + /* memory allocation error */ + if(error) + *error = MINISSDPC_MEMORY_ERROR; + goto error; + } + tmp->pNext = devlist; + tmp->descURL = tmp->buffer; + tmp->st = tmp->buffer + 1 + urlsize; + tmp->usn = tmp->st + 1 + stsize; + memcpy(tmp->buffer, descURL, urlsize); + tmp->buffer[urlsize] = '\0'; + memcpy(tmp->st, st, stsize); + tmp->buffer[urlsize+1+stsize] = '\0'; + if(usn != NULL) + memcpy(tmp->usn, usn, usnsize); + tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; + tmp->scope_id = scope_id; + devlist = tmp; + } + } + } while(n > 0); + if(ipv6) { + /* switch linklocal flag */ + if(linklocal) { + linklocal = 0; + --deviceIndex; + } else { + linklocal = 1; + } + } + } +error: + closesocket(sudp); + return devlist; +} + diff --git a/deps/miniupnpc/minissdpc.h b/deps/miniupnpc/minissdpc.h new file mode 100644 index 0000000000..167d897cb6 --- /dev/null +++ b/deps/miniupnpc/minissdpc.h @@ -0,0 +1,58 @@ +/* $Id: minissdpc.h,v 1.6 2015/09/18 12:45:16 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINISSDPC_H_INCLUDED +#define MINISSDPC_H_INCLUDED + +#include "miniupnpc_declspec.h" +#include "upnpdev.h" + +/* error codes : */ +#define MINISSDPC_SUCCESS (0) +#define MINISSDPC_UNKNOWN_ERROR (-1) +#define MINISSDPC_SOCKET_ERROR (-101) +#define MINISSDPC_MEMORY_ERROR (-102) +#define MINISSDPC_INVALID_INPUT (-103) +#define MINISSDPC_INVALID_SERVER_REPLY (-104) + +#ifdef __cplusplus +extern "C" { +#endif + +#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) + +MINIUPNP_LIBSPEC struct UPNPDev * +getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error); + +MINIUPNP_LIBSPEC int +connectToMiniSSDPD(const char * socketpath); + +MINIUPNP_LIBSPEC int +disconnectFromMiniSSDPD(int fd); + +MINIUPNP_LIBSPEC int +requestDevicesFromMiniSSDPD(int fd, const char * devtype); + +MINIUPNP_LIBSPEC struct UPNPDev * +receiveDevicesFromMiniSSDPD(int fd, int * error); + +#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */ + +MINIUPNP_LIBSPEC struct UPNPDev * +ssdpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/deps/miniupnpc/miniupnpc.c b/deps/miniupnpc/miniupnpc.c new file mode 100644 index 0000000000..5eb9500e30 --- /dev/null +++ b/deps/miniupnpc/miniupnpc.c @@ -0,0 +1,722 @@ +/* $Id: miniupnpc.c,v 1.148 2016/01/24 17:24:36 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp + * Web : http://miniupnp.free.fr/ + * Author : Thomas BERNARD + * copyright (c) 2005-2016 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENSE file. */ +#include +#include +#include +#ifdef _WIN32 +/* Win32 Specific includes and defines */ +#include +#include +#include +#include +#define snprintf _snprintf +#define strdup _strdup +#ifndef strncasecmp +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define strncasecmp _memicmp +#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#define strncasecmp memicmp +#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#endif /* #ifndef strncasecmp */ +#define MAXHOSTNAMELEN 64 +#else /* #ifdef _WIN32 */ +/* Standard POSIX includes */ +#include +#if defined(__amigaos__) && !defined(__amigaos4__) +/* Amiga OS 3 specific stuff */ +#define socklen_t int +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#if !defined(__amigaos__) && !defined(__amigaos4__) +#include +#endif +#include +#include +#define closesocket close +#endif /* #else _WIN32 */ +#ifdef __GNU__ +#define MAXHOSTNAMELEN 64 +#endif + + +#include "miniupnpc.h" +#include "minissdpc.h" +#include "miniwget.h" +#include "minisoap.h" +#include "minixml.h" +#include "upnpcommands.h" +#include "connecthostport.h" + +/* compare the begining of a string with a constant string */ +#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1)) + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#define SOAPPREFIX "s" +#define SERVICEPREFIX "u" +#define SERVICEPREFIX2 'u' + +/* check if an ip address is a private (LAN) address + * see https://tools.ietf.org/html/rfc1918 */ +static int is_rfc1918addr(const char * addr) +{ + /* 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) */ + if(COMPARE(addr, "192.168.")) + return 1; + /* 10.0.0.0 - 10.255.255.255 (10/8 prefix) */ + if(COMPARE(addr, "10.")) + return 1; + /* 172.16.0.0 - 172.31.255.255 (172.16/12 prefix) */ + if(COMPARE(addr, "172.")) { + int i = atoi(addr + 4); + if((16 <= i) && (i <= 31)) + return 1; + } + return 0; +} + +/* root description parsing */ +MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data) +{ + struct xmlparser parser; + /* xmlparser object */ + parser.xmlstart = buffer; + parser.xmlsize = bufsize; + parser.data = data; + parser.starteltfunc = IGDstartelt; + parser.endeltfunc = IGDendelt; + parser.datafunc = IGDdata; + parser.attfunc = 0; + parsexml(&parser); +#ifdef DEBUG + printIGD(data); +#endif +} + +/* simpleUPnPcommand2 : + * not so simple ! + * return values : + * pointer - OK + * NULL - error */ +char * simpleUPnPcommand2(int s, const char * url, const char * service, + const char * action, struct UPNParg * args, + int * bufsize, const char * httpversion) +{ + char hostname[MAXHOSTNAMELEN+1]; + unsigned short port = 0; + char * path; + char soapact[128]; + char soapbody[2048]; + int soapbodylen; + char * buf; + int n; + int status_code; + + *bufsize = 0; + snprintf(soapact, sizeof(soapact), "%s#%s", service, action); + if(args==NULL) + { + soapbodylen = snprintf(soapbody, sizeof(soapbody), + "\r\n" + "<" SOAPPREFIX ":Envelope " + "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " + SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<" SOAPPREFIX ":Body>" + "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">" + "" + "" + "\r\n", action, service, action); + if ((unsigned int)soapbodylen >= sizeof(soapbody)) + return NULL; + } + else + { + char * p; + const char * pe, * pv; + const char * const pend = soapbody + sizeof(soapbody); + soapbodylen = snprintf(soapbody, sizeof(soapbody), + "\r\n" + "<" SOAPPREFIX ":Envelope " + "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" " + SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" + "<" SOAPPREFIX ":Body>" + "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">", + action, service); + if ((unsigned int)soapbodylen >= sizeof(soapbody)) + return NULL; + p = soapbody + soapbodylen; + while(args->elt) + { + if(p >= pend) /* check for space to write next byte */ + return NULL; + *(p++) = '<'; + + pe = args->elt; + while(p < pend && *pe) + *(p++) = *(pe++); + + if(p >= pend) /* check for space to write next byte */ + return NULL; + *(p++) = '>'; + + if((pv = args->val)) + { + while(p < pend && *pv) + *(p++) = *(pv++); + } + + if((p+2) > pend) /* check for space to write next 2 bytes */ + return NULL; + *(p++) = '<'; + *(p++) = '/'; + + pe = args->elt; + while(p < pend && *pe) + *(p++) = *(pe++); + + if(p >= pend) /* check for space to write next byte */ + return NULL; + *(p++) = '>'; + + args++; + } + if((p+4) > pend) /* check for space to write next 4 bytes */ + return NULL; + *(p++) = '<'; + *(p++) = '/'; + *(p++) = SERVICEPREFIX2; + *(p++) = ':'; + + pe = action; + while(p < pend && *pe) + *(p++) = *(pe++); + + strncpy(p, ">\r\n", + pend - p); + if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */ + return NULL; + } + if(!parseURL(url, hostname, &port, &path, NULL)) return NULL; + if(s < 0) { + s = connecthostport(hostname, port, 0); + if(s < 0) { + /* failed to connect */ + return NULL; + } + } + + n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion); + if(n<=0) { +#ifdef DEBUG + printf("Error sending SOAP request\n"); +#endif + closesocket(s); + return NULL; + } + + buf = getHTTPResponse(s, bufsize, &status_code); +#ifdef DEBUG + if(*bufsize > 0 && buf) + { + printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf); + } + else + { + printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize); + } +#endif + closesocket(s); + return buf; +} + +/* simpleUPnPcommand : + * not so simple ! + * return values : + * pointer - OK + * NULL - error */ +char * simpleUPnPcommand(int s, const char * url, const char * service, + const char * action, struct UPNParg * args, + int * bufsize) +{ + char * buf; + +#if 1 + buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); +#else + buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0"); + if (!buf || *bufsize == 0) + { +#if DEBUG + printf("Error or no result from SOAP request; retrying with HTTP/1.1\n"); +#endif + buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1"); + } +#endif + return buf; +} + +/* upnpDiscoverDevices() : + * return a chained list of all devices found or NULL if + * no devices was found. + * It is up to the caller to free the chained list + * delay is in millisecond (poll). + * UDA v1.1 says : + * The TTL for the IP packet SHOULD default to 2 and + * SHOULD be configurable. */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes) +{ + struct UPNPDev * tmp; + struct UPNPDev * devlist = 0; +#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) + int deviceIndex; +#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + + if(error) + *error = UPNPDISCOVER_UNKNOWN_ERROR; +#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) + /* first try to get infos from minissdpd ! */ + if(!minissdpdsock) + minissdpdsock = "/var/run/minissdpd.sock"; + for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) { + struct UPNPDev * minissdpd_devlist; + int only_rootdevice = 1; + minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex], + minissdpdsock, 0); + if(minissdpd_devlist) { +#ifdef DEBUG + printf("returned by MiniSSDPD: %s\t%s\n", + minissdpd_devlist->st, minissdpd_devlist->descURL); +#endif /* DEBUG */ + if(!strstr(minissdpd_devlist->st, "rootdevice")) + only_rootdevice = 0; + for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) { +#ifdef DEBUG + printf("returned by MiniSSDPD: %s\t%s\n", + tmp->pNext->st, tmp->pNext->descURL); +#endif /* DEBUG */ + if(!strstr(tmp->st, "rootdevice")) + only_rootdevice = 0; + } + tmp->pNext = devlist; + devlist = minissdpd_devlist; + if(!searchalltypes && !only_rootdevice) + break; + } + } + for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) { + /* We return what we have found if it was not only a rootdevice */ + if(!strstr(tmp->st, "rootdevice")) { + if(error) + *error = UPNPDISCOVER_SUCCESS; + return devlist; + } + } +#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + + /* direct discovery if minissdpd responses are not sufficient */ + { + struct UPNPDev * discovered_devlist; + discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport, + ipv6, ttl, error, searchalltypes); + if(devlist == NULL) + devlist = discovered_devlist; + else { + for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext); + tmp->pNext = discovered_devlist; + } + } + return devlist; +} + +/* upnpDiscover() Discover IGD device */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) +{ + static const char * const deviceList[] = { +#if 0 + "urn:schemas-upnp-org:device:InternetGatewayDevice:2", + "urn:schemas-upnp-org:service:WANIPConnection:2", +#endif + "urn:schemas-upnp-org:device:InternetGatewayDevice:1", + "urn:schemas-upnp-org:service:WANIPConnection:1", + "urn:schemas-upnp-org:service:WANPPPConnection:1", + "upnp:rootdevice", + /*"ssdp:all",*/ + 0 + }; + return upnpDiscoverDevices(deviceList, + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); +} + +/* upnpDiscoverAll() Discover all UPnP devices */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverAll(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) +{ + static const char * const deviceList[] = { + /*"upnp:rootdevice",*/ + "ssdp:all", + 0 + }; + return upnpDiscoverDevices(deviceList, + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); +} + +/* upnpDiscoverDevice() Discover a specific device */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevice(const char * device, int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error) +{ + const char * const deviceList[] = { + device, + 0 + }; + return upnpDiscoverDevices(deviceList, + delay, multicastif, minissdpdsock, localport, + ipv6, ttl, error, 0); +} + +static char * +build_absolute_url(const char * baseurl, const char * descURL, + const char * url, unsigned int scope_id) +{ + int l, n; + char * s; + const char * base; + char * p; +#if defined(IF_NAMESIZE) && !defined(_WIN32) + char ifname[IF_NAMESIZE]; +#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + char scope_str[8]; +#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + + if( (url[0] == 'h') + &&(url[1] == 't') + &&(url[2] == 't') + &&(url[3] == 'p') + &&(url[4] == ':') + &&(url[5] == '/') + &&(url[6] == '/')) + return strdup(url); + base = (baseurl[0] == '\0') ? descURL : baseurl; + n = strlen(base); + if(n > 7) { + p = strchr(base + 7, '/'); + if(p) + n = p - base; + } + l = n + strlen(url) + 1; + if(url[0] != '/') + l++; + if(scope_id != 0) { +#if defined(IF_NAMESIZE) && !defined(_WIN32) + if(if_indextoname(scope_id, ifname)) { + l += 3 + strlen(ifname); /* 3 == strlen(%25) */ + } +#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + /* under windows, scope is numerical */ + l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id); +#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + } + s = malloc(l); + if(s == NULL) return NULL; + memcpy(s, base, n); + if(scope_id != 0) { + s[n] = '\0'; + if(0 == memcmp(s, "http://[fe80:", 13)) { + /* this is a linklocal IPv6 address */ + p = strchr(s, ']'); + if(p) { + /* insert %25 into URL */ +#if defined(IF_NAMESIZE) && !defined(_WIN32) + memmove(p + 3 + strlen(ifname), p, strlen(p) + 1); + memcpy(p, "%25", 3); + memcpy(p + 3, ifname, strlen(ifname)); + n += 3 + strlen(ifname); +#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1); + memcpy(p, "%25", 3); + memcpy(p + 3, scope_str, strlen(scope_str)); + n += 3 + strlen(scope_str); +#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */ + } + } + } + if(url[0] != '/') + s[n++] = '/'; + memcpy(s + n, url, l - n); + return s; +} + +/* Prepare the Urls for usage... + */ +MINIUPNP_LIBSPEC void +GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data, + const char * descURL, unsigned int scope_id) +{ + /* strdup descURL */ + urls->rootdescURL = strdup(descURL); + + /* get description of WANIPConnection */ + urls->ipcondescURL = build_absolute_url(data->urlbase, descURL, + data->first.scpdurl, scope_id); + urls->controlURL = build_absolute_url(data->urlbase, descURL, + data->first.controlurl, scope_id); + urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL, + data->CIF.controlurl, scope_id); + urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL, + data->IPv6FC.controlurl, scope_id); + +#ifdef DEBUG + printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL); + printf("urls->controlURL='%s'\n", urls->controlURL); + printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF); + printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC); +#endif +} + +MINIUPNP_LIBSPEC void +FreeUPNPUrls(struct UPNPUrls * urls) +{ + if(!urls) + return; + free(urls->controlURL); + urls->controlURL = 0; + free(urls->ipcondescURL); + urls->ipcondescURL = 0; + free(urls->controlURL_CIF); + urls->controlURL_CIF = 0; + free(urls->controlURL_6FC); + urls->controlURL_6FC = 0; + free(urls->rootdescURL); + urls->rootdescURL = 0; +} + +int +UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data) +{ + char status[64]; + unsigned int uptime; + status[0] = '\0'; + UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype, + status, &uptime, NULL); + if(0 == strcmp("Connected", status)) + return 1; + else if(0 == strcmp("Up", status)) /* Also accept "Up" */ + return 1; + else + return 0; +} + + +/* UPNP_GetValidIGD() : + * return values : + * -1 = Internal error + * 0 = NO IGD found + * 1 = A valid connected IGD has been found + * 2 = A valid IGD has been found but it reported as + * not connected + * 3 = an UPnP device has been found but was not recognized as an IGD + * + * In any positive non zero return case, the urls and data structures + * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to + * free allocated memory. + */ +MINIUPNP_LIBSPEC int +UPNP_GetValidIGD(struct UPNPDev * devlist, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen) +{ + struct xml_desc { + char * xml; + int size; + int is_igd; + } * desc = NULL; + struct UPNPDev * dev; + int ndev = 0; + int i; + int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */ + int n_igd = 0; + char extIpAddr[16]; + char myLanAddr[40]; + int status_code = -1; + + if(!devlist) + { +#ifdef DEBUG + printf("Empty devlist\n"); +#endif + return 0; + } + /* counting total number of devices in the list */ + for(dev = devlist; dev; dev = dev->pNext) + ndev++; + if(ndev > 0) + { + desc = calloc(ndev, sizeof(struct xml_desc)); + if(!desc) + return -1; /* memory allocation error */ + } + /* Step 1 : downloading descriptions and testing type */ + for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) + { + /* we should choose an internet gateway device. + * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */ + desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size), + myLanAddr, sizeof(myLanAddr), + dev->scope_id, &status_code); +#ifdef DEBUG + if(!desc[i].xml) + { + printf("error getting XML description %s\n", dev->descURL); + } +#endif + if(desc[i].xml) + { + memset(data, 0, sizeof(struct IGDdatas)); + memset(urls, 0, sizeof(struct UPNPUrls)); + parserootdesc(desc[i].xml, desc[i].size, data); + if(COMPARE(data->CIF.servicetype, + "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) + { + desc[i].is_igd = 1; + n_igd++; + if(lanaddr) + strncpy(lanaddr, myLanAddr, lanaddrlen); + } + } + } + /* iterate the list to find a device depending on state */ + for(state = 1; state <= 3; state++) + { + for(dev = devlist, i = 0; dev; dev = dev->pNext, i++) + { + if(desc[i].xml) + { + memset(data, 0, sizeof(struct IGDdatas)); + memset(urls, 0, sizeof(struct UPNPUrls)); + parserootdesc(desc[i].xml, desc[i].size, data); + if(desc[i].is_igd || state >= 3 ) + { + int is_connected; + + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + + /* in state 2 and 3 we dont test if device is connected ! */ + if(state >= 2) + goto free_and_return; + is_connected = UPNPIGD_IsConnected(urls, data); +#ifdef DEBUG + printf("UPNPIGD_IsConnected(%s) = %d\n", + urls->controlURL, is_connected); +#endif + /* checks that status is connected AND there is a external IP address assigned */ + if(is_connected && + (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { + if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') + && (0 != strcmp(extIpAddr, "0.0.0.0"))) + goto free_and_return; + } + FreeUPNPUrls(urls); + if(data->second.servicetype[0] != '\0') { +#ifdef DEBUG + printf("We tried %s, now we try %s !\n", + data->first.servicetype, data->second.servicetype); +#endif + /* swaping WANPPPConnection and WANIPConnection ! */ + memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service)); + memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service)); + memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service)); + GetUPNPUrls(urls, data, dev->descURL, dev->scope_id); + is_connected = UPNPIGD_IsConnected(urls, data); +#ifdef DEBUG + printf("UPNPIGD_IsConnected(%s) = %d\n", + urls->controlURL, is_connected); +#endif + if(is_connected && + (UPNP_GetExternalIPAddress(urls->controlURL, data->first.servicetype, extIpAddr) == 0)) { + if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0') + && (0 != strcmp(extIpAddr, "0.0.0.0"))) + goto free_and_return; + } + FreeUPNPUrls(urls); + } + } + memset(data, 0, sizeof(struct IGDdatas)); + } + } + } + state = 0; +free_and_return: + if(desc) { + for(i = 0; i < ndev; i++) { + if(desc[i].xml) { + free(desc[i].xml); + } + } + free(desc); + } + return state; +} + +/* UPNP_GetIGDFromUrl() + * Used when skipping the discovery process. + * return value : + * 0 - Not ok + * 1 - OK */ +int +UPNP_GetIGDFromUrl(const char * rootdescurl, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen) +{ + char * descXML; + int descXMLsize = 0; + + descXML = miniwget_getaddr(rootdescurl, &descXMLsize, + lanaddr, lanaddrlen, 0, NULL); + if(descXML) { + memset(data, 0, sizeof(struct IGDdatas)); + memset(urls, 0, sizeof(struct UPNPUrls)); + parserootdesc(descXML, descXMLsize, data); + free(descXML); + descXML = NULL; + GetUPNPUrls(urls, data, rootdescurl, 0); + return 1; + } else { + return 0; + } +} + diff --git a/deps/miniupnpc/miniupnpc.def b/deps/miniupnpc/miniupnpc.def new file mode 100644 index 0000000000..60e0bbe423 --- /dev/null +++ b/deps/miniupnpc/miniupnpc.def @@ -0,0 +1,45 @@ +LIBRARY +; miniupnpc library + miniupnpc + +EXPORTS +; miniupnpc + upnpDiscover + freeUPNPDevlist + parserootdesc + UPNP_GetValidIGD + UPNP_GetIGDFromUrl + GetUPNPUrls + FreeUPNPUrls +; miniwget + miniwget + miniwget_getaddr +; upnpcommands + UPNP_GetTotalBytesSent + UPNP_GetTotalBytesReceived + UPNP_GetTotalPacketsSent + UPNP_GetTotalPacketsReceived + UPNP_GetStatusInfo + UPNP_GetConnectionTypeInfo + UPNP_GetExternalIPAddress + UPNP_GetLinkLayerMaxBitRates + UPNP_AddPortMapping + UPNP_AddAnyPortMapping + UPNP_DeletePortMapping + UPNP_DeletePortMappingRange + UPNP_GetPortMappingNumberOfEntries + UPNP_GetSpecificPortMappingEntry + UPNP_GetGenericPortMappingEntry + UPNP_GetListOfPortMappings + UPNP_AddPinhole + UPNP_CheckPinholeWorking + UPNP_UpdatePinhole + UPNP_GetPinholePackets + UPNP_DeletePinhole + UPNP_GetFirewallStatus + UPNP_GetOutboundPinholeTimeout +; upnperrors + strupnperror +; portlistingparse + ParsePortListing + FreePortListing diff --git a/deps/miniupnpc/miniupnpc.h b/deps/miniupnpc/miniupnpc.h new file mode 100644 index 0000000000..0b5b473295 --- /dev/null +++ b/deps/miniupnpc/miniupnpc.h @@ -0,0 +1,152 @@ +/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ + * Author: Thomas Bernard + * Copyright (c) 2005-2016 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINIUPNPC_H_INCLUDED +#define MINIUPNPC_H_INCLUDED + +#include "miniupnpc_declspec.h" +#include "igd_desc_parse.h" +#include "upnpdev.h" + +/* error codes : */ +#define UPNPDISCOVER_SUCCESS (0) +#define UPNPDISCOVER_UNKNOWN_ERROR (-1) +#define UPNPDISCOVER_SOCKET_ERROR (-101) +#define UPNPDISCOVER_MEMORY_ERROR (-102) + +/* versions : */ +#define MINIUPNPC_VERSION "2.0" +#define MINIUPNPC_API_VERSION 16 + +/* Source port: + Using "1" as an alias for 1900 for backwards compatability + (presuming one would have used that for the "sameport" parameter) */ +#define UPNP_LOCAL_PORT_ANY 0 +#define UPNP_LOCAL_PORT_SAME 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structures definitions : */ +struct UPNParg { const char * elt; const char * val; }; + +char * +simpleUPnPcommand(int, const char *, const char *, + const char *, struct UPNParg *, + int *); + +/* upnpDiscover() + * discover UPnP devices on the network. + * The discovered devices are returned as a chained list. + * It is up to the caller to free the list with freeUPNPDevlist(). + * delay (in millisecond) is the maximum time for waiting any device + * response. + * If available, device list will be obtained from MiniSSDPd. + * Default path for minissdpd socket will be used if minissdpdsock argument + * is NULL. + * If multicastif is not NULL, it will be used instead of the default + * multicast interface for sending SSDP discover packets. + * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent + * from the source port 1900 (same as destination port), if set to + * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will + * be attempted as the source port. + * "searchalltypes" parameter is useful when searching several types, + * if 0, the discovery will stop with the first type returning results. + * TTL should default to 2. */ +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscover(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverAll(int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevice(const char * device, int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error); + +MINIUPNP_LIBSPEC struct UPNPDev * +upnpDiscoverDevices(const char * const deviceTypes[], + int delay, const char * multicastif, + const char * minissdpdsock, int localport, + int ipv6, unsigned char ttl, + int * error, + int searchalltypes); + +/* parserootdesc() : + * parse root XML description of a UPnP device and fill the IGDdatas + * structure. */ +MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *); + +/* structure used to get fast access to urls + * controlURL: controlURL of the WANIPConnection + * ipcondescURL: url of the description of the WANIPConnection + * controlURL_CIF: controlURL of the WANCommonInterfaceConfig + * controlURL_6FC: controlURL of the WANIPv6FirewallControl + */ +struct UPNPUrls { + char * controlURL; + char * ipcondescURL; + char * controlURL_CIF; + char * controlURL_6FC; + char * rootdescURL; +}; + +/* UPNP_GetValidIGD() : + * return values : + * 0 = NO IGD found + * 1 = A valid connected IGD has been found + * 2 = A valid IGD has been found but it reported as + * not connected + * 3 = an UPnP device has been found but was not recognized as an IGD + * + * In any non zero return case, the urls and data structures + * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to + * free allocated memory. + */ +MINIUPNP_LIBSPEC int +UPNP_GetValidIGD(struct UPNPDev * devlist, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); + +/* UPNP_GetIGDFromUrl() + * Used when skipping the discovery process. + * When succeding, urls, data, and lanaddr arguments are set. + * return value : + * 0 - Not ok + * 1 - OK */ +MINIUPNP_LIBSPEC int +UPNP_GetIGDFromUrl(const char * rootdescurl, + struct UPNPUrls * urls, + struct IGDdatas * data, + char * lanaddr, int lanaddrlen); + +MINIUPNP_LIBSPEC void +GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, + const char *, unsigned int); + +MINIUPNP_LIBSPEC void +FreeUPNPUrls(struct UPNPUrls *); + +/* return 0 or 1 */ +MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/deps/miniupnpc/miniupnpc_declspec.h b/deps/miniupnpc/miniupnpc_declspec.h new file mode 100644 index 0000000000..e0a624d275 --- /dev/null +++ b/deps/miniupnpc/miniupnpc_declspec.h @@ -0,0 +1,12 @@ +#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED +#define MINIUPNPC_DECLSPEC_H_INCLUDED + +#if defined(__GNUC__) && __GNUC__ >= 4 +/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */ +#define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default"))) +#else +#define MINIUPNP_LIBSPEC +#endif + +#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */ + diff --git a/deps/miniupnpc/miniupnpctypes.h b/deps/miniupnpc/miniupnpctypes.h new file mode 100644 index 0000000000..307ce39699 --- /dev/null +++ b/deps/miniupnpc/miniupnpctypes.h @@ -0,0 +1,19 @@ +/* $Id: miniupnpctypes.h,v 1.1 2011/02/15 11:10:40 nanard Exp $ */ +/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org + * Author : Thomas Bernard + * Copyright (c) 2011 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided within this distribution */ +#ifndef MINIUPNPCTYPES_H_INCLUDED +#define MINIUPNPCTYPES_H_INCLUDED + +#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) +#define UNSIGNED_INTEGER unsigned long long +#define STRTOUI strtoull +#else +#define UNSIGNED_INTEGER unsigned int +#define STRTOUI strtoul +#endif + +#endif + diff --git a/deps/miniupnpc/miniwget.c b/deps/miniupnpc/miniwget.c new file mode 100644 index 0000000000..84b392b372 --- /dev/null +++ b/deps/miniupnpc/miniwget.c @@ -0,0 +1,661 @@ +/* $Id: miniwget.c,v 1.75 2016/01/24 17:24:36 nanard Exp $ */ +/* Project : miniupnp + * Website : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2016 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ + +#include +#include +#include +#include +#ifdef _WIN32 +#include +#include +#include +#define MAXHOSTNAMELEN 64 +#define snprintf _snprintf +#define socklen_t int +#ifndef strncasecmp +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#define strncasecmp _memicmp +#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#define strncasecmp memicmp +#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */ +#endif /* #ifndef strncasecmp */ +#else /* #ifdef _WIN32 */ +#include +#include +#if defined(__amigaos__) && !defined(__amigaos4__) +#define socklen_t int +#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#include +#include +#include +#include +#define closesocket close +#include +#endif /* #else _WIN32 */ +#ifdef __GNU__ +#define MAXHOSTNAMELEN 64 +#endif /* __GNU__ */ + +#ifndef MIN +#define MIN(x,y) (((x)<(y))?(x):(y)) +#endif /* MIN */ + + +#include "miniupnpcstrings.h" +#include "miniwget.h" +#include "connecthostport.h" +#include "receivedata.h" + +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +/* + * Read a HTTP response from a socket. + * Process Content-Length and Transfer-encoding headers. + * return a pointer to the content buffer, which length is saved + * to the length parameter. + */ +void * +getHTTPResponse(int s, int * size, int * status_code) +{ + char buf[2048]; + int n; + int endofheaders = 0; + int chunked = 0; + int content_length = -1; + unsigned int chunksize = 0; + unsigned int bytestocopy = 0; + /* buffers : */ + char * header_buf; + unsigned int header_buf_len = 2048; + unsigned int header_buf_used = 0; + char * content_buf; + unsigned int content_buf_len = 2048; + unsigned int content_buf_used = 0; + char chunksize_buf[32]; + unsigned int chunksize_buf_index; +#ifdef DEBUG + char * reason_phrase = NULL; + int reason_phrase_len = 0; +#endif + + if(status_code) *status_code = -1; + header_buf = malloc(header_buf_len); + if(header_buf == NULL) + { +#ifdef DEBUG + fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); +#endif /* DEBUG */ + *size = -1; + return NULL; + } + content_buf = malloc(content_buf_len); + if(content_buf == NULL) + { + free(header_buf); +#ifdef DEBUG + fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse"); +#endif /* DEBUG */ + *size = -1; + return NULL; + } + chunksize_buf[0] = '\0'; + chunksize_buf_index = 0; + + while((n = receivedata(s, buf, 2048, 5000, NULL)) > 0) + { + if(endofheaders == 0) + { + int i; + int linestart=0; + int colon=0; + int valuestart=0; + if(header_buf_used + n > header_buf_len) { + char * tmp = realloc(header_buf, header_buf_used + n); + if(tmp == NULL) { + /* memory allocation error */ + free(header_buf); + free(content_buf); + *size = -1; + return NULL; + } + header_buf = tmp; + header_buf_len = header_buf_used + n; + } + memcpy(header_buf + header_buf_used, buf, n); + header_buf_used += n; + /* search for CR LF CR LF (end of headers) + * recognize also LF LF */ + i = 0; + while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { + if(header_buf[i] == '\r') { + i++; + if(header_buf[i] == '\n') { + i++; + if(i < (int)header_buf_used && header_buf[i] == '\r') { + i++; + if(i < (int)header_buf_used && header_buf[i] == '\n') { + endofheaders = i+1; + } + } + } + } else if(header_buf[i] == '\n') { + i++; + if(header_buf[i] == '\n') { + endofheaders = i+1; + } + } + i++; + } + if(endofheaders == 0) + continue; + /* parse header lines */ + for(i = 0; i < endofheaders - 1; i++) { + if(linestart > 0 && colon <= linestart && header_buf[i]==':') + { + colon = i; + while(i < (endofheaders-1) + && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t')) + i++; + valuestart = i + 1; + } + /* detecting end of line */ + else if(header_buf[i]=='\r' || header_buf[i]=='\n') + { + if(linestart == 0 && status_code) + { + /* Status line + * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */ + int sp; + for(sp = 0; sp < i; sp++) + if(header_buf[sp] == ' ') + { + if(*status_code < 0) + *status_code = atoi(header_buf + sp + 1); + else + { +#ifdef DEBUG + reason_phrase = header_buf + sp + 1; + reason_phrase_len = i - sp - 1; +#endif + break; + } + } +#ifdef DEBUG + printf("HTTP status code = %d, Reason phrase = %.*s\n", + *status_code, reason_phrase_len, reason_phrase); +#endif + } + else if(colon > linestart && valuestart > colon) + { +#ifdef DEBUG + printf("header='%.*s', value='%.*s'\n", + colon-linestart, header_buf+linestart, + i-valuestart, header_buf+valuestart); +#endif + if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart)) + { + content_length = atoi(header_buf+valuestart); +#ifdef DEBUG + printf("Content-Length: %d\n", content_length); +#endif + } + else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart) + && 0==strncasecmp(header_buf+valuestart, "chunked", 7)) + { +#ifdef DEBUG + printf("chunked transfer-encoding!\n"); +#endif + chunked = 1; + } + } + while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n')) + i++; + linestart = i; + colon = linestart; + valuestart = 0; + } + } + /* copy the remaining of the received data back to buf */ + n = header_buf_used - endofheaders; + memcpy(buf, header_buf + endofheaders, n); + /* if(headers) */ + } + if(endofheaders) + { + /* content */ + if(chunked) + { + int i = 0; + while(i < n) + { + if(chunksize == 0) + { + /* reading chunk size */ + if(chunksize_buf_index == 0) { + /* skipping any leading CR LF */ + if(i= '0' + && chunksize_buf[j] <= '9') + chunksize = (chunksize << 4) + (chunksize_buf[j] - '0'); + else + chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10); + } + chunksize_buf[0] = '\0'; + chunksize_buf_index = 0; + i++; + } else { + /* not finished to get chunksize */ + continue; + } +#ifdef DEBUG + printf("chunksize = %u (%x)\n", chunksize, chunksize); +#endif + if(chunksize == 0) + { +#ifdef DEBUG + printf("end of HTTP content - %d %d\n", i, n); + /*printf("'%.*s'\n", n-i, buf+i);*/ +#endif + goto end_of_stream; + } + } + bytestocopy = ((int)chunksize < (n - i))?chunksize:(unsigned int)(n - i); + if((content_buf_used + bytestocopy) > content_buf_len) + { + char * tmp; + if(content_length >= (int)(content_buf_used + bytestocopy)) { + content_buf_len = content_length; + } else { + content_buf_len = content_buf_used + bytestocopy; + } + tmp = realloc(content_buf, content_buf_len); + if(tmp == NULL) { + /* memory allocation error */ + free(content_buf); + free(header_buf); + *size = -1; + return NULL; + } + content_buf = tmp; + } + memcpy(content_buf + content_buf_used, buf + i, bytestocopy); + content_buf_used += bytestocopy; + i += bytestocopy; + chunksize -= bytestocopy; + } + } + else + { + /* not chunked */ + if(content_length > 0 + && (int)(content_buf_used + n) > content_length) { + /* skipping additional bytes */ + n = content_length - content_buf_used; + } + if(content_buf_used + n > content_buf_len) + { + char * tmp; + if(content_length >= (int)(content_buf_used + n)) { + content_buf_len = content_length; + } else { + content_buf_len = content_buf_used + n; + } + tmp = realloc(content_buf, content_buf_len); + if(tmp == NULL) { + /* memory allocation error */ + free(content_buf); + free(header_buf); + *size = -1; + return NULL; + } + content_buf = tmp; + } + memcpy(content_buf + content_buf_used, buf, n); + content_buf_used += n; + } + } + /* use the Content-Length header value if available */ + if(content_length > 0 && (int)content_buf_used >= content_length) + { +#ifdef DEBUG + printf("End of HTTP content\n"); +#endif + break; + } + } +end_of_stream: + free(header_buf); header_buf = NULL; + *size = content_buf_used; + if(content_buf_used == 0) + { + free(content_buf); + content_buf = NULL; + } + return content_buf; +} + +/* miniwget3() : + * do all the work. + * Return NULL if something failed. */ +static void * +miniwget3(const char * host, + unsigned short port, const char * path, + int * size, char * addr_str, int addr_str_len, + const char * httpversion, unsigned int scope_id, + int * status_code) +{ + char buf[2048]; + int s; + int n; + int len; + int sent; + void * content; + + *size = 0; + s = connecthostport(host, port, scope_id); + if(s < 0) + return NULL; + + /* get address for caller ! */ + if(addr_str) + { + struct sockaddr_storage saddr; + socklen_t saddrlen; + + saddrlen = sizeof(saddr); + if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0) + { + perror("getsockname"); + } + else + { +#if defined(__amigaos__) && !defined(__amigaos4__) + /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD); + * But his function make a string with the port : nn.nn.nn.nn:port */ +/* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr), + NULL, addr_str, (DWORD *)&addr_str_len)) + { + printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError()); + }*/ + /* the following code is only compatible with ip v4 addresses */ + strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len); +#else +#if 0 + if(saddr.sa_family == AF_INET6) { + inet_ntop(AF_INET6, + &(((struct sockaddr_in6 *)&saddr)->sin6_addr), + addr_str, addr_str_len); + } else { + inet_ntop(AF_INET, + &(((struct sockaddr_in *)&saddr)->sin_addr), + addr_str, addr_str_len); + } +#endif + /* getnameinfo return ip v6 address with the scope identifier + * such as : 2a01:e35:8b2b:7330::%4281128194 */ + n = getnameinfo((const struct sockaddr *)&saddr, saddrlen, + addr_str, addr_str_len, + NULL, 0, + NI_NUMERICHOST | NI_NUMERICSERV); + if(n != 0) { +#ifdef _WIN32 + fprintf(stderr, "getnameinfo() failed : %d\n", n); +#else + fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n)); +#endif + } +#endif + } +#ifdef DEBUG + printf("address miniwget : %s\n", addr_str); +#endif + } + + len = snprintf(buf, sizeof(buf), + "GET %s HTTP/%s\r\n" + "Host: %s:%d\r\n" + "Connection: Close\r\n" + "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n" + + "\r\n", + path, httpversion, host, port); + if ((unsigned int)len >= sizeof(buf)) + { + closesocket(s); + return NULL; + } + sent = 0; + /* sending the HTTP request */ + while(sent < len) + { + n = send(s, buf+sent, len-sent, 0); + if(n < 0) + { + perror("send"); + closesocket(s); + return NULL; + } + else + { + sent += n; + } + } + content = getHTTPResponse(s, size, status_code); + closesocket(s); + return content; +} + +/* miniwget2() : + * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */ +static void * +miniwget2(const char * host, + unsigned short port, const char * path, + int * size, char * addr_str, int addr_str_len, + unsigned int scope_id, int * status_code) +{ + char * respbuffer; + +#if 1 + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", + scope_id, status_code); +#else + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.0", + scope_id, status_code); + if (*size == 0) + { +#ifdef DEBUG + printf("Retrying with HTTP/1.1\n"); +#endif + free(respbuffer); + respbuffer = miniwget3(host, port, path, size, + addr_str, addr_str_len, "1.1", + scope_id, status_code); + } +#endif + return respbuffer; +} + + + + +/* parseURL() + * arguments : + * url : source string not modified + * hostname : hostname destination string (size of MAXHOSTNAMELEN+1) + * port : port (destination) + * path : pointer to the path part of the URL + * + * Return values : + * 0 - Failure + * 1 - Success */ +int +parseURL(const char * url, + char * hostname, unsigned short * port, + char * * path, unsigned int * scope_id) +{ + char * p1, *p2, *p3; + if(!url) + return 0; + p1 = strstr(url, "://"); + if(!p1) + return 0; + p1 += 3; + if( (url[0]!='h') || (url[1]!='t') + ||(url[2]!='t') || (url[3]!='p')) + return 0; + memset(hostname, 0, MAXHOSTNAMELEN + 1); + if(*p1 == '[') + { + /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */ + char * scope; + scope = strchr(p1, '%'); + p2 = strchr(p1, ']'); + if(p2 && scope && scope < p2 && scope_id) { + /* parse scope */ +#ifdef IF_NAMESIZE + char tmp[IF_NAMESIZE]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= IF_NAMESIZE) + l = IF_NAMESIZE - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = if_nametoindex(tmp); + if(*scope_id == 0) { + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); + } +#else + /* under windows, scope is numerical */ + char tmp[8]; + int l; + scope++; + /* "%25" is just '%' in URL encoding */ + if(scope[0] == '2' && scope[1] == '5') + scope += 2; /* skip "25" */ + l = p2 - scope; + if(l >= sizeof(tmp)) + l = sizeof(tmp) - 1; + memcpy(tmp, scope, l); + tmp[l] = '\0'; + *scope_id = (unsigned int)strtoul(tmp, NULL, 10); +#endif + } + p3 = strchr(p1, '/'); + if(p2 && p3) + { + p2++; + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); + if(*p2 == ':') + { + *port = 0; + p2++; + while( (*p2 >= '0') && (*p2 <= '9')) + { + *port *= 10; + *port += (unsigned short)(*p2 - '0'); + p2++; + } + } + else + { + *port = 80; + } + *path = p3; + return 1; + } + } + p2 = strchr(p1, ':'); + p3 = strchr(p1, '/'); + if(!p3) + return 0; + if(!p2 || (p2>p3)) + { + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1))); + *port = 80; + } + else + { + strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1))); + *port = 0; + p2++; + while( (*p2 >= '0') && (*p2 <= '9')) + { + *port *= 10; + *port += (unsigned short)(*p2 - '0'); + p2++; + } + } + *path = p3; + return 1; +} + +void * +miniwget(const char * url, int * size, + unsigned int scope_id, int * status_code) +{ + unsigned short port; + char * path; + /* protocol://host:port/chemin */ + char hostname[MAXHOSTNAMELEN+1]; + *size = 0; + if(!parseURL(url, hostname, &port, &path, &scope_id)) + return NULL; +#ifdef DEBUG + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); +#endif + return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code); +} + +void * +miniwget_getaddr(const char * url, int * size, + char * addr, int addrlen, unsigned int scope_id, + int * status_code) +{ + unsigned short port; + char * path; + /* protocol://host:port/path */ + char hostname[MAXHOSTNAMELEN+1]; + *size = 0; + if(addr) + addr[0] = '\0'; + if(!parseURL(url, hostname, &port, &path, &scope_id)) + return NULL; +#ifdef DEBUG + printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n", + hostname, port, path, scope_id); +#endif + return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code); +} + diff --git a/deps/miniupnpc/miniwget.h b/deps/miniupnpc/miniwget.h new file mode 100644 index 0000000000..0701494d0c --- /dev/null +++ b/deps/miniupnpc/miniwget.h @@ -0,0 +1,30 @@ +/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005-2016 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef MINIWGET_H_INCLUDED +#define MINIWGET_H_INCLUDED + +#include "miniupnpc_declspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code); + +MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *); + +MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *); + +int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/deps/miniupnpc/minixml.c b/deps/miniupnpc/minixml.c new file mode 100644 index 0000000000..1f2227343c --- /dev/null +++ b/deps/miniupnpc/minixml.c @@ -0,0 +1,229 @@ +/* $Id: minixml.c,v 1.10 2012/03/05 19:42:47 nanard Exp $ */ +/* minixml.c : the minimum size a xml parser can be ! */ +/* Project : miniupnp + * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author : Thomas Bernard + +Copyright (c) 2005-2014, Thomas BERNARD +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include "minixml.h" + +/* parseatt : used to parse the argument list + * return 0 (false) in case of success and -1 (true) if the end + * of the xmlbuffer is reached. */ +static int parseatt(struct xmlparser * p) +{ + const char * attname; + int attnamelen; + const char * attvalue; + int attvaluelen; + while(p->xml < p->xmlend) + { + if(*p->xml=='/' || *p->xml=='>') + return 0; + if( !IS_WHITE_SPACE(*p->xml) ) + { + char sep; + attname = p->xml; + attnamelen = 0; + while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) ) + { + attnamelen++; p->xml++; + if(p->xml >= p->xmlend) + return -1; + } + while(*(p->xml++) != '=') + { + if(p->xml >= p->xmlend) + return -1; + } + while(IS_WHITE_SPACE(*p->xml)) + { + p->xml++; + if(p->xml >= p->xmlend) + return -1; + } + sep = *p->xml; + if(sep=='\'' || sep=='\"') + { + p->xml++; + if(p->xml >= p->xmlend) + return -1; + attvalue = p->xml; + attvaluelen = 0; + while(*p->xml != sep) + { + attvaluelen++; p->xml++; + if(p->xml >= p->xmlend) + return -1; + } + } + else + { + attvalue = p->xml; + attvaluelen = 0; + while( !IS_WHITE_SPACE(*p->xml) + && *p->xml != '>' && *p->xml != '/') + { + attvaluelen++; p->xml++; + if(p->xml >= p->xmlend) + return -1; + } + } + /*printf("%.*s='%.*s'\n", + attnamelen, attname, attvaluelen, attvalue);*/ + if(p->attfunc) + p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen); + } + p->xml++; + } + return -1; +} + +/* parseelt parse the xml stream and + * call the callback functions when needed... */ +static void parseelt(struct xmlparser * p) +{ + int i; + const char * elementname; + while(p->xml < (p->xmlend - 1)) + { + if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "", 3) != 0); + p->xml += 3; + } + else if((p->xml)[0]=='<' && (p->xml)[1]!='?') + { + i = 0; elementname = ++p->xml; + while( !IS_WHITE_SPACE(*p->xml) + && (*p->xml!='>') && (*p->xml!='/') + ) + { + i++; p->xml++; + if (p->xml >= p->xmlend) + return; + /* to ignore namespace : */ + if(*p->xml==':') + { + i = 0; + elementname = ++p->xml; + } + } + if(i>0) + { + if(p->starteltfunc) + p->starteltfunc(p->data, elementname, i); + if(parseatt(p)) + return; + if(*p->xml!='/') + { + const char * data; + i = 0; data = ++p->xml; + if (p->xml >= p->xmlend) + return; + while( IS_WHITE_SPACE(*p->xml) ) + { + i++; p->xml++; + if (p->xml >= p->xmlend) + return; + } + if(memcmp(p->xml, "xml += 9; + data = p->xml; + i = 0; + while(memcmp(p->xml, "]]>", 3) != 0) + { + i++; p->xml++; + if ((p->xml + 3) >= p->xmlend) + return; + } + if(i>0 && p->datafunc) + p->datafunc(p->data, data, i); + while(*p->xml!='<') + { + p->xml++; + if (p->xml >= p->xmlend) + return; + } + } + else + { + while(*p->xml!='<') + { + i++; p->xml++; + if ((p->xml + 1) >= p->xmlend) + return; + } + if(i>0 && p->datafunc && *(p->xml + 1) == '/') + p->datafunc(p->data, data, i); + } + } + } + else if(*p->xml == '/') + { + i = 0; elementname = ++p->xml; + if (p->xml >= p->xmlend) + return; + while((*p->xml != '>')) + { + i++; p->xml++; + if (p->xml >= p->xmlend) + return; + } + if(p->endeltfunc) + p->endeltfunc(p->data, elementname, i); + p->xml++; + } + } + else + { + p->xml++; + } + } +} + +/* the parser must be initialized before calling this function */ +void parsexml(struct xmlparser * parser) +{ + parser->xml = parser->xmlstart; + parser->xmlend = parser->xmlstart + parser->xmlsize; + parseelt(parser); +} + + diff --git a/deps/miniupnpc/minixml.h b/deps/miniupnpc/minixml.h new file mode 100644 index 0000000000..19e6f513bf --- /dev/null +++ b/deps/miniupnpc/minixml.h @@ -0,0 +1,37 @@ +/* $Id: minixml.h,v 1.6 2006/11/30 11:47:21 nanard Exp $ */ +/* minimal xml parser + * + * Project : miniupnp + * Website : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#ifndef MINIXML_H_INCLUDED +#define MINIXML_H_INCLUDED +#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n')) + +/* if a callback function pointer is set to NULL, + * the function is not called */ +struct xmlparser { + const char *xmlstart; + const char *xmlend; + const char *xml; /* pointer to current character */ + int xmlsize; + void * data; + void (*starteltfunc) (void *, const char *, int); + void (*endeltfunc) (void *, const char *, int); + void (*datafunc) (void *, const char *, int); + void (*attfunc) (void *, const char *, int, const char *, int); +}; + +/* parsexml() + * the xmlparser structure must be initialized before the call + * the following structure members have to be initialized : + * xmlstart, xmlsize, data, *func + * xml is for internal usage, xmlend is computed automatically */ +void parsexml(struct xmlparser *); + +#endif + diff --git a/deps/miniupnpc/portlistingparse.c b/deps/miniupnpc/portlistingparse.c new file mode 100644 index 0000000000..55859f2714 --- /dev/null +++ b/deps/miniupnpc/portlistingparse.c @@ -0,0 +1,172 @@ +/* $Id: portlistingparse.c,v 1.9 2015/07/15 12:41:13 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2011-2016 Thomas Bernard + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ +#include +#include +#ifdef DEBUG +#include +#endif /* DEBUG */ +#include "portlistingparse.h" +#include "minixml.h" + +/* list of the elements */ +static const struct { + const portMappingElt code; + const char * const str; +} elements[] = { + { PortMappingEntry, "PortMappingEntry"}, + { NewRemoteHost, "NewRemoteHost"}, + { NewExternalPort, "NewExternalPort"}, + { NewProtocol, "NewProtocol"}, + { NewInternalPort, "NewInternalPort"}, + { NewInternalClient, "NewInternalClient"}, + { NewEnabled, "NewEnabled"}, + { NewDescription, "NewDescription"}, + { NewLeaseTime, "NewLeaseTime"}, + { PortMappingEltNone, NULL} +}; + +/* Helper function */ +static UNSIGNED_INTEGER +atoui(const char * p, int l) +{ + UNSIGNED_INTEGER r = 0; + while(l > 0 && *p) + { + if(*p >= '0' && *p <= '9') + r = r*10 + (*p - '0'); + else + break; + p++; + l--; + } + return r; +} + +/* Start element handler */ +static void +startelt(void * d, const char * name, int l) +{ + int i; + struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; + pdata->curelt = PortMappingEltNone; + for(i = 0; elements[i].str; i++) + { + if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0) + { + pdata->curelt = elements[i].code; + break; + } + } + if(pdata->curelt == PortMappingEntry) + { + struct PortMapping * pm; + pm = calloc(1, sizeof(struct PortMapping)); + if(pm == NULL) + { + /* malloc error */ +#ifdef DEBUG + fprintf(stderr, "%s: error allocating memory", + "startelt"); +#endif /* DEBUG */ + return; + } + pm->l_next = pdata->l_head; /* insert in list */ + pdata->l_head = pm; + } +} + +/* End element handler */ +static void +endelt(void * d, const char * name, int l) +{ + struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; + (void)name; + (void)l; + pdata->curelt = PortMappingEltNone; +} + +/* Data handler */ +static void +data(void * d, const char * data, int l) +{ + struct PortMapping * pm; + struct PortMappingParserData * pdata = (struct PortMappingParserData *)d; + pm = pdata->l_head; + if(!pm) + return; + if(l > 63) + l = 63; + switch(pdata->curelt) + { + case NewRemoteHost: + memcpy(pm->remoteHost, data, l); + pm->remoteHost[l] = '\0'; + break; + case NewExternalPort: + pm->externalPort = (unsigned short)atoui(data, l); + break; + case NewProtocol: + if(l > 3) + l = 3; + memcpy(pm->protocol, data, l); + pm->protocol[l] = '\0'; + break; + case NewInternalPort: + pm->internalPort = (unsigned short)atoui(data, l); + break; + case NewInternalClient: + memcpy(pm->internalClient, data, l); + pm->internalClient[l] = '\0'; + break; + case NewEnabled: + pm->enabled = (unsigned char)atoui(data, l); + break; + case NewDescription: + memcpy(pm->description, data, l); + pm->description[l] = '\0'; + break; + case NewLeaseTime: + pm->leaseTime = atoui(data, l); + break; + default: + break; + } +} + + +/* Parse the PortMappingList XML document for IGD version 2 + */ +void +ParsePortListing(const char * buffer, int bufsize, + struct PortMappingParserData * pdata) +{ + struct xmlparser parser; + + memset(pdata, 0, sizeof(struct PortMappingParserData)); + /* init xmlparser */ + parser.xmlstart = buffer; + parser.xmlsize = bufsize; + parser.data = pdata; + parser.starteltfunc = startelt; + parser.endeltfunc = endelt; + parser.datafunc = data; + parser.attfunc = 0; + parsexml(&parser); +} + +void +FreePortListing(struct PortMappingParserData * pdata) +{ + struct PortMapping * pm; + while((pm = pdata->l_head) != NULL) + { + /* remove from list */ + pdata->l_head = pm->l_next; + free(pm); + } +} + diff --git a/deps/miniupnpc/portlistingparse.h b/deps/miniupnpc/portlistingparse.h new file mode 100644 index 0000000000..e3957a3f4c --- /dev/null +++ b/deps/miniupnpc/portlistingparse.h @@ -0,0 +1,65 @@ +/* $Id: portlistingparse.h,v 1.10 2014/11/01 10:37:32 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2011-2015 Thomas Bernard + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ +#ifndef PORTLISTINGPARSE_H_INCLUDED +#define PORTLISTINGPARSE_H_INCLUDED + +#include "miniupnpc_declspec.h" +/* for the definition of UNSIGNED_INTEGER */ +#include "miniupnpctypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* sample of PortMappingEntry : + + 202.233.2.1 + 2345 + TCP + 2345 + 192.168.1.137 + 1 + dooom + 345 + + */ +typedef enum { PortMappingEltNone, + PortMappingEntry, NewRemoteHost, + NewExternalPort, NewProtocol, + NewInternalPort, NewInternalClient, + NewEnabled, NewDescription, + NewLeaseTime } portMappingElt; + +struct PortMapping { + struct PortMapping * l_next; /* list next element */ + UNSIGNED_INTEGER leaseTime; + unsigned short externalPort; + unsigned short internalPort; + char remoteHost[64]; + char internalClient[64]; + char description[64]; + char protocol[4]; + unsigned char enabled; +}; + +struct PortMappingParserData { + struct PortMapping * l_head; /* list head */ + portMappingElt curelt; +}; + +MINIUPNP_LIBSPEC void +ParsePortListing(const char * buffer, int bufsize, + struct PortMappingParserData * pdata); + +MINIUPNP_LIBSPEC void +FreePortListing(struct PortMappingParserData * pdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/miniupnpc/receivedata.c b/deps/miniupnpc/receivedata.c new file mode 100644 index 0000000000..ef85a3db41 --- /dev/null +++ b/deps/miniupnpc/receivedata.c @@ -0,0 +1,105 @@ +/* $Id: receivedata.c,v 1.7 2015/11/09 21:51:41 nanard Exp $ */ +/* Project : miniupnp + * Website : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2011-2014 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. */ + +#include +#include +#ifdef _WIN32 +#include +#include +#else /* _WIN32 */ +#include +#if defined(__amigaos__) && !defined(__amigaos4__) +#define socklen_t int +#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#include +#if !defined(__amigaos__) && !defined(__amigaos4__) +#include +#endif /* !defined(__amigaos__) && !defined(__amigaos4__) */ +#include +#define MINIUPNPC_IGNORE_EINTR +#endif /* _WIN32 */ + +#ifdef _WIN32 +#define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError()); +#else +#define PRINT_SOCKET_ERROR(x) perror(x) +#endif + +#include "receivedata.h" + +int +receivedata(int socket, + char * data, int length, + int timeout, unsigned int * scope_id) +{ +#ifdef MINIUPNPC_GET_SRC_ADDR + struct sockaddr_storage src_addr; + socklen_t src_addr_len = sizeof(src_addr); +#endif /* MINIUPNPC_GET_SRC_ADDR */ + int n; +#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) + /* using poll */ + struct pollfd fds[1]; /* for the poll */ +#ifdef MINIUPNPC_IGNORE_EINTR + do { +#endif /* MINIUPNPC_IGNORE_EINTR */ + fds[0].fd = socket; + fds[0].events = POLLIN; + n = poll(fds, 1, timeout); +#ifdef MINIUPNPC_IGNORE_EINTR + } while(n < 0 && errno == EINTR); +#endif /* MINIUPNPC_IGNORE_EINTR */ + if(n < 0) { + PRINT_SOCKET_ERROR("poll"); + return -1; + } else if(n == 0) { + /* timeout */ + return 0; + } +#else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ + /* using select under _WIN32 and amigaos */ + fd_set socketSet; + TIMEVAL timeval; + FD_ZERO(&socketSet); + FD_SET(socket, &socketSet); + timeval.tv_sec = timeout / 1000; + timeval.tv_usec = (timeout % 1000) * 1000; + n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval); + if(n < 0) { + PRINT_SOCKET_ERROR("select"); + return -1; + } else if(n == 0) { + return 0; + } +#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */ +#ifdef MINIUPNPC_GET_SRC_ADDR + memset(&src_addr, 0, sizeof(src_addr)); + n = recvfrom(socket, data, length, 0, + (struct sockaddr *)&src_addr, &src_addr_len); +#else /* MINIUPNPC_GET_SRC_ADDR */ + n = recv(socket, data, length, 0); +#endif /* MINIUPNPC_GET_SRC_ADDR */ + if(n<0) { + PRINT_SOCKET_ERROR("recv"); + } +#ifdef MINIUPNPC_GET_SRC_ADDR + if (src_addr.ss_family == AF_INET6) { + const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr; +#ifdef DEBUG + printf("scope_id=%u\n", src_addr6->sin6_scope_id); +#endif /* DEBUG */ + if(scope_id) + *scope_id = src_addr6->sin6_scope_id; + } +#endif /* MINIUPNPC_GET_SRC_ADDR */ + return n; +} + diff --git a/deps/miniupnpc/receivedata.h b/deps/miniupnpc/receivedata.h new file mode 100644 index 0000000000..cb85c33177 --- /dev/null +++ b/deps/miniupnpc/receivedata.h @@ -0,0 +1,19 @@ +/* $Id: receivedata.h,v 1.3 2012/06/23 22:34:47 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2011-2012 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef RECEIVEDATA_H_INCLUDED +#define RECEIVEDATA_H_INCLUDED + +/* Reads data from the specified socket. + * Returns the number of bytes read if successful, zero if no bytes were + * read or if we timed out. Returns negative if there was an error. */ +int receivedata(int socket, + char * data, int length, + int timeout, unsigned int * scope_id); + +#endif + diff --git a/deps/miniupnpc/updateminiupnpcstrings.sh b/deps/miniupnpc/updateminiupnpcstrings.sh new file mode 100755 index 0000000000..dde4354a8a --- /dev/null +++ b/deps/miniupnpc/updateminiupnpcstrings.sh @@ -0,0 +1,53 @@ +#! /bin/sh +# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $ +# project miniupnp : http://miniupnp.free.fr/ +# (c) 2009 Thomas Bernard + +FILE=miniupnpcstrings.h +TMPFILE=miniupnpcstrings.h.tmp +TEMPLATE_FILE=${FILE}.in + +# detecting the OS name and version +OS_NAME=`uname -s` +OS_VERSION=`uname -r` +if [ -f /etc/debian_version ]; then + OS_NAME=Debian + OS_VERSION=`cat /etc/debian_version` +fi +# use lsb_release (Linux Standard Base) when available +LSB_RELEASE=`which lsb_release` +if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then + OS_NAME=`${LSB_RELEASE} -i -s` + OS_VERSION=`${LSB_RELEASE} -r -s` + case $OS_NAME in + Debian) + #OS_VERSION=`${LSB_RELEASE} -c -s` + ;; + Ubuntu) + #OS_VERSION=`${LSB_RELEASE} -c -s` + ;; + esac +fi + +# on AmigaOS 3, uname -r returns "unknown", so we use uname -v +if [ "$OS_NAME" = "AmigaOS" ]; then + if [ "$OS_VERSION" = "unknown" ]; then + OS_VERSION=`uname -v` + fi +fi + +echo "Detected OS [$OS_NAME] version [$OS_VERSION]" +MINIUPNPC_VERSION=`cat VERSION` +echo "MiniUPnPc version [${MINIUPNPC_VERSION}]" + +EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|" +#echo $EXPR +test -f ${FILE}.in +echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE." +sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE + +EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|" +echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE." +sed -e "$EXPR" < $TMPFILE > $FILE +rm $TMPFILE + diff --git a/deps/miniupnpc/upnpcommands.c b/deps/miniupnpc/upnpcommands.c new file mode 100644 index 0000000000..9f704496fb --- /dev/null +++ b/deps/miniupnpc/upnpcommands.c @@ -0,0 +1,1240 @@ +/* $Id: upnpcommands.c,v 1.46 2015/07/15 12:19:00 nanard Exp $ */ +/* vim: tabstop=4 shiftwidth=4 noexpandtab + * Project : miniupnp + * Author : Thomas Bernard + * Copyright (c) 2005-2017 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided in this distribution. + * */ +#include +#include +#include +#include "upnpcommands.h" +#include "miniupnpc.h" +#include "portlistingparse.h" + +static UNSIGNED_INTEGER +my_atoui(const char * s) +{ + return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; +} + +/* + * */ +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesSent(const char * controlURL, + const char * servicetype) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + unsigned int r = 0; + char * p; + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetTotalBytesSent", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + /*DisplayNameValueList(buffer, bufsize);*/ + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent"); + r = my_atoui(p); + ClearNameValueList(&pdata); + return r; +} + +/* + * */ +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesReceived(const char * controlURL, + const char * servicetype) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + unsigned int r = 0; + char * p; + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetTotalBytesReceived", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + /*DisplayNameValueList(buffer, bufsize);*/ + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived"); + r = my_atoui(p); + ClearNameValueList(&pdata); + return r; +} + +/* + * */ +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsSent(const char * controlURL, + const char * servicetype) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + unsigned int r = 0; + char * p; + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetTotalPacketsSent", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + /*DisplayNameValueList(buffer, bufsize);*/ + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent"); + r = my_atoui(p); + ClearNameValueList(&pdata); + return r; +} + +/* + * */ +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsReceived(const char * controlURL, + const char * servicetype) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + unsigned int r = 0; + char * p; + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetTotalPacketsReceived", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + /*DisplayNameValueList(buffer, bufsize);*/ + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived"); + r = my_atoui(p); + ClearNameValueList(&pdata); + return r; +} + +/* UPNP_GetStatusInfo() call the corresponding UPNP method + * returns the current status and uptime */ +MINIUPNP_LIBSPEC int +UPNP_GetStatusInfo(const char * controlURL, + const char * servicetype, + char * status, + unsigned int * uptime, + char * lastconnerror) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + char * p; + char * up; + char * err; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!status && !uptime) + return UPNPCOMMAND_INVALID_ARGS; + + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetStatusInfo", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + /*DisplayNameValueList(buffer, bufsize);*/ + free(buffer); buffer = NULL; + up = GetValueFromNameValueList(&pdata, "NewUptime"); + p = GetValueFromNameValueList(&pdata, "NewConnectionStatus"); + err = GetValueFromNameValueList(&pdata, "NewLastConnectionError"); + if(p && up) + ret = UPNPCOMMAND_SUCCESS; + + if(status) { + if(p){ + strncpy(status, p, 64 ); + status[63] = '\0'; + }else + status[0]= '\0'; + } + + if(uptime) { + if(up) + sscanf(up,"%u",uptime); + else + *uptime = 0; + } + + if(lastconnerror) { + if(err) { + strncpy(lastconnerror, err, 64 ); + lastconnerror[63] = '\0'; + } else + lastconnerror[0] = '\0'; + } + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + ClearNameValueList(&pdata); + return ret; +} + +/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method + * returns the connection type */ +MINIUPNP_LIBSPEC int +UPNP_GetConnectionTypeInfo(const char * controlURL, + const char * servicetype, + char * connectionType) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + char * p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!connectionType) + return UPNPCOMMAND_INVALID_ARGS; + + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetConnectionTypeInfo", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "NewConnectionType"); + /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/ + /* PossibleConnectionTypes will have several values.... */ + if(p) { + strncpy(connectionType, p, 64 ); + connectionType[63] = '\0'; + ret = UPNPCOMMAND_SUCCESS; + } else + connectionType[0] = '\0'; + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + ClearNameValueList(&pdata); + return ret; +} + +/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. + * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. + * One of the values can be null + * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only + * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ +MINIUPNP_LIBSPEC int +UPNP_GetLinkLayerMaxBitRates(const char * controlURL, + const char * servicetype, + unsigned int * bitrateDown, + unsigned int * bitrateUp) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + char * down; + char * up; + char * p; + + if(!bitrateDown && !bitrateUp) + return UPNPCOMMAND_INVALID_ARGS; + + /* shouldn't we use GetCommonLinkProperties ? */ + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetCommonLinkProperties", 0, &bufsize))) { + /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/ + return UPNPCOMMAND_HTTP_ERROR; + } + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/ + /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/ + down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate"); + up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate"); + /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/ + /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/ + if(down && up) + ret = UPNPCOMMAND_SUCCESS; + + if(bitrateDown) { + if(down) + sscanf(down,"%u",bitrateDown); + else + *bitrateDown = 0; + } + + if(bitrateUp) { + if(up) + sscanf(up,"%u",bitrateUp); + else + *bitrateUp = 0; + } + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + ClearNameValueList(&pdata); + return ret; +} + + +/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. + * if the third arg is not null the value is copied to it. + * at least 16 bytes must be available + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR Either an UPnP error code or an unknown error. + * + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + */ +MINIUPNP_LIBSPEC int +UPNP_GetExternalIPAddress(const char * controlURL, + const char * servicetype, + char * extIpAdd) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + char * p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!extIpAdd || !controlURL || !servicetype) + return UPNPCOMMAND_INVALID_ARGS; + + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetExternalIPAddress", 0, &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/ + p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress"); + if(p) { + strncpy(extIpAdd, p, 16 ); + extIpAdd[15] = '\0'; + ret = UPNPCOMMAND_SUCCESS; + } else + extIpAdd[0] = '\0'; + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration) +{ + struct UPNParg * AddPortMappingArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!inPort || !inClient || !proto || !extPort) + return UPNPCOMMAND_INVALID_ARGS; + + AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); + if(AddPortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + AddPortMappingArgs[0].elt = "NewRemoteHost"; + AddPortMappingArgs[0].val = remoteHost; + AddPortMappingArgs[1].elt = "NewExternalPort"; + AddPortMappingArgs[1].val = extPort; + AddPortMappingArgs[2].elt = "NewProtocol"; + AddPortMappingArgs[2].val = proto; + AddPortMappingArgs[3].elt = "NewInternalPort"; + AddPortMappingArgs[3].val = inPort; + AddPortMappingArgs[4].elt = "NewInternalClient"; + AddPortMappingArgs[4].val = inClient; + AddPortMappingArgs[5].elt = "NewEnabled"; + AddPortMappingArgs[5].val = "1"; + AddPortMappingArgs[6].elt = "NewPortMappingDescription"; + AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; + AddPortMappingArgs[7].elt = "NewLeaseDuration"; + AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "AddPortMapping", AddPortMappingArgs, + &bufsize); + free(AddPortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + /*DisplayNameValueList(buffer, bufsize);*/ + /*buffer[bufsize] = '\0';*/ + /*puts(buffer);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) { + /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } else { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration, + char * reservedPort) +{ + struct UPNParg * AddPortMappingArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!inPort || !inClient || !proto || !extPort) + return UPNPCOMMAND_INVALID_ARGS; + + AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); + if(AddPortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + AddPortMappingArgs[0].elt = "NewRemoteHost"; + AddPortMappingArgs[0].val = remoteHost; + AddPortMappingArgs[1].elt = "NewExternalPort"; + AddPortMappingArgs[1].val = extPort; + AddPortMappingArgs[2].elt = "NewProtocol"; + AddPortMappingArgs[2].val = proto; + AddPortMappingArgs[3].elt = "NewInternalPort"; + AddPortMappingArgs[3].val = inPort; + AddPortMappingArgs[4].elt = "NewInternalClient"; + AddPortMappingArgs[4].val = inClient; + AddPortMappingArgs[5].elt = "NewEnabled"; + AddPortMappingArgs[5].val = "1"; + AddPortMappingArgs[6].elt = "NewPortMappingDescription"; + AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; + AddPortMappingArgs[7].elt = "NewLeaseDuration"; + AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0"; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "AddAnyPortMapping", AddPortMappingArgs, + &bufsize); + free(AddPortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } else { + char *p; + + p = GetValueFromNameValueList(&pdata, "NewReservedPort"); + if(p) { + strncpy(reservedPort, p, 6); + reservedPort[5] = '\0'; + ret = UPNPCOMMAND_SUCCESS; + } else { + ret = UPNPCOMMAND_INVALID_RESPONSE; + } + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, + const char * extPort, const char * proto, + const char * remoteHost) +{ + /*struct NameValueParserData pdata;*/ + struct UPNParg * DeletePortMappingArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!extPort || !proto) + return UPNPCOMMAND_INVALID_ARGS; + + DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); + if(DeletePortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + DeletePortMappingArgs[0].elt = "NewRemoteHost"; + DeletePortMappingArgs[0].val = remoteHost; + DeletePortMappingArgs[1].elt = "NewExternalPort"; + DeletePortMappingArgs[1].val = extPort; + DeletePortMappingArgs[2].elt = "NewProtocol"; + DeletePortMappingArgs[2].val = proto; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "DeletePortMapping", + DeletePortMappingArgs, &bufsize); + free(DeletePortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } else { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, + const char * extPortStart, const char * extPortEnd, + const char * proto, + const char * manage) +{ + struct UPNParg * DeletePortMappingArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!extPortStart || !extPortEnd || !proto || !manage) + return UPNPCOMMAND_INVALID_ARGS; + + DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg)); + if(DeletePortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + DeletePortMappingArgs[0].elt = "NewStartPort"; + DeletePortMappingArgs[0].val = extPortStart; + DeletePortMappingArgs[1].elt = "NewEndPort"; + DeletePortMappingArgs[1].val = extPortEnd; + DeletePortMappingArgs[2].elt = "NewProtocol"; + DeletePortMappingArgs[2].val = proto; + DeletePortMappingArgs[3].elt = "NewManage"; + DeletePortMappingArgs[3].val = manage; + + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "DeletePortMappingRange", + DeletePortMappingArgs, &bufsize); + free(DeletePortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } else { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_GetGenericPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * index, + char * extPort, + char * intClient, + char * intPort, + char * protocol, + char * desc, + char * enabled, + char * rHost, + char * duration) +{ + struct NameValueParserData pdata; + struct UPNParg * GetPortMappingArgs; + char * buffer; + int bufsize; + char * p; + int r = UPNPCOMMAND_UNKNOWN_ERROR; + if(!index) + return UPNPCOMMAND_INVALID_ARGS; + intClient[0] = '\0'; + intPort[0] = '\0'; + GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); + if(GetPortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + GetPortMappingArgs[0].elt = "NewPortMappingIndex"; + GetPortMappingArgs[0].val = index; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetGenericPortMappingEntry", + GetPortMappingArgs, &bufsize); + free(GetPortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); + if(p && rHost) + { + strncpy(rHost, p, 64); + rHost[63] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "NewExternalPort"); + if(p && extPort) + { + strncpy(extPort, p, 6); + extPort[5] = '\0'; + r = UPNPCOMMAND_SUCCESS; + } + p = GetValueFromNameValueList(&pdata, "NewProtocol"); + if(p && protocol) + { + strncpy(protocol, p, 4); + protocol[3] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "NewInternalClient"); + if(p) + { + strncpy(intClient, p, 16); + intClient[15] = '\0'; + r = 0; + } + p = GetValueFromNameValueList(&pdata, "NewInternalPort"); + if(p) + { + strncpy(intPort, p, 6); + intPort[5] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "NewEnabled"); + if(p && enabled) + { + strncpy(enabled, p, 4); + enabled[3] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); + if(p && desc) + { + strncpy(desc, p, 80); + desc[79] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); + if(p && duration) + { + strncpy(duration, p, 16); + duration[15] = '\0'; + } + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + r = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &r); + } + ClearNameValueList(&pdata); + return r; +} + +MINIUPNP_LIBSPEC int +UPNP_GetPortMappingNumberOfEntries(const char * controlURL, + const char * servicetype, + unsigned int * numEntries) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + char* p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetPortMappingNumberOfEntries", 0, + &bufsize))) { + return UPNPCOMMAND_HTTP_ERROR; + } +#ifdef DEBUG + DisplayNameValueList(buffer, bufsize); +#endif + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); + if(numEntries && p) { + *numEntries = 0; + sscanf(p, "%u", numEntries); + ret = UPNPCOMMAND_SUCCESS; + } + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + + ClearNameValueList(&pdata); + return ret; +} + +/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping + * the result is returned in the intClient and intPort strings + * please provide 16 and 6 bytes of data */ +MINIUPNP_LIBSPEC int +UPNP_GetSpecificPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * extPort, + const char * proto, + const char * remoteHost, + char * intClient, + char * intPort, + char * desc, + char * enabled, + char * leaseDuration) +{ + struct NameValueParserData pdata; + struct UPNParg * GetPortMappingArgs; + char * buffer; + int bufsize; + char * p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!intPort || !intClient || !extPort || !proto) + return UPNPCOMMAND_INVALID_ARGS; + + GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); + if(GetPortMappingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + GetPortMappingArgs[0].elt = "NewRemoteHost"; + GetPortMappingArgs[0].val = remoteHost; + GetPortMappingArgs[1].elt = "NewExternalPort"; + GetPortMappingArgs[1].val = extPort; + GetPortMappingArgs[2].elt = "NewProtocol"; + GetPortMappingArgs[2].val = proto; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetSpecificPortMappingEntry", + GetPortMappingArgs, &bufsize); + free(GetPortMappingArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + p = GetValueFromNameValueList(&pdata, "NewInternalClient"); + if(p) { + strncpy(intClient, p, 16); + intClient[15] = '\0'; + ret = UPNPCOMMAND_SUCCESS; + } else + intClient[0] = '\0'; + + p = GetValueFromNameValueList(&pdata, "NewInternalPort"); + if(p) { + strncpy(intPort, p, 6); + intPort[5] = '\0'; + } else + intPort[0] = '\0'; + + p = GetValueFromNameValueList(&pdata, "NewEnabled"); + if(p && enabled) { + strncpy(enabled, p, 4); + enabled[3] = '\0'; + } + + p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); + if(p && desc) { + strncpy(desc, p, 80); + desc[79] = '\0'; + } + + p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); + if(p && leaseDuration) + { + strncpy(leaseDuration, p, 16); + leaseDuration[15] = '\0'; + } + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + + ClearNameValueList(&pdata); + return ret; +} + +/* UPNP_GetListOfPortMappings() + * + * Possible UPNP Error codes : + * 606 Action not Authorized + * 730 PortMappingNotFound - no port mapping is found in the specified range. + * 733 InconsistantParameters - NewStartPort and NewEndPort values are not + * consistent. + */ +MINIUPNP_LIBSPEC int +UPNP_GetListOfPortMappings(const char * controlURL, + const char * servicetype, + const char * startPort, + const char * endPort, + const char * protocol, + const char * numberOfPorts, + struct PortMappingParserData * data) +{ + struct NameValueParserData pdata; + struct UPNParg * GetListOfPortMappingsArgs; + const char * p; + char * buffer; + int bufsize; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!startPort || !endPort || !protocol) + return UPNPCOMMAND_INVALID_ARGS; + + GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg)); + if(GetListOfPortMappingsArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + GetListOfPortMappingsArgs[0].elt = "NewStartPort"; + GetListOfPortMappingsArgs[0].val = startPort; + GetListOfPortMappingsArgs[1].elt = "NewEndPort"; + GetListOfPortMappingsArgs[1].val = endPort; + GetListOfPortMappingsArgs[2].elt = "NewProtocol"; + GetListOfPortMappingsArgs[2].val = protocol; + GetListOfPortMappingsArgs[3].elt = "NewManage"; + GetListOfPortMappingsArgs[3].val = "1"; + GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts"; + GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000"; + + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetListOfPortMappings", + GetListOfPortMappingsArgs, &bufsize); + free(GetListOfPortMappingsArgs); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/ + /*if(p) { + printf("NewPortListing : %s\n", p); + }*/ + /*printf("NewPortListing(%d chars) : %s\n", + pdata.portListingLength, pdata.portListing);*/ + if(pdata.portListing) + { + /*struct PortMapping * pm; + int i = 0;*/ + ParsePortListing(pdata.portListing, pdata.portListingLength, + data); + ret = UPNPCOMMAND_SUCCESS; + /* + for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next) + { + printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n", + i, pm->protocol, pm->externalPort, pm->internalClient, + pm->internalPort, + pm->description, pm->remoteHost); + i++; + } + */ + /*FreePortListing(&data);*/ + } + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + ClearNameValueList(&pdata); + + /*printf("%.*s", bufsize, buffer);*/ + + return ret; +} + +/* IGD:2, functions for service WANIPv6FirewallControl:1 */ +MINIUPNP_LIBSPEC int +UPNP_GetFirewallStatus(const char * controlURL, + const char * servicetype, + int * firewallEnabled, + int * inboundPinholeAllowed) +{ + struct NameValueParserData pdata; + char * buffer; + int bufsize; + char * fe, *ipa, *p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!firewallEnabled || !inboundPinholeAllowed) + return UPNPCOMMAND_INVALID_ARGS; + + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetFirewallStatus", 0, &bufsize); + if(!buffer) { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + fe = GetValueFromNameValueList(&pdata, "FirewallEnabled"); + ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed"); + if(ipa && fe) + ret = UPNPCOMMAND_SUCCESS; + if(fe) + *firewallEnabled = my_atoui(fe); + /*else + *firewallEnabled = 0;*/ + if(ipa) + *inboundPinholeAllowed = my_atoui(ipa); + /*else + *inboundPinholeAllowed = 0;*/ + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) + { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + int * opTimeout) +{ + struct UPNParg * GetOutboundPinholeTimeoutArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + char * p; + int ret; + + if(!intPort || !intClient || !proto || !remotePort || !remoteHost) + return UPNPCOMMAND_INVALID_ARGS; + + GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg)); + if(GetOutboundPinholeTimeoutArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost"; + GetOutboundPinholeTimeoutArgs[0].val = remoteHost; + GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort"; + GetOutboundPinholeTimeoutArgs[1].val = remotePort; + GetOutboundPinholeTimeoutArgs[2].elt = "Protocol"; + GetOutboundPinholeTimeoutArgs[2].val = proto; + GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort"; + GetOutboundPinholeTimeoutArgs[3].val = intPort; + GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient"; + GetOutboundPinholeTimeoutArgs[4].val = intClient; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize); + free(GetOutboundPinholeTimeoutArgs); + if(!buffer) + return UPNPCOMMAND_HTTP_ERROR; + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) + { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } + else + { + ret = UPNPCOMMAND_SUCCESS; + p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout"); + if(p) + *opTimeout = my_atoui(p); + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_AddPinhole(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + const char * leaseTime, + char * uniqueID) +{ + struct UPNParg * AddPinholeArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + char * p; + int ret; + + if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime) + return UPNPCOMMAND_INVALID_ARGS; + + AddPinholeArgs = calloc(7, sizeof(struct UPNParg)); + if(AddPinholeArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + /* RemoteHost can be wilcarded */ + if(strncmp(remoteHost, "empty", 5)==0) + { + AddPinholeArgs[0].elt = "RemoteHost"; + AddPinholeArgs[0].val = ""; + } + else + { + AddPinholeArgs[0].elt = "RemoteHost"; + AddPinholeArgs[0].val = remoteHost; + } + AddPinholeArgs[1].elt = "RemotePort"; + AddPinholeArgs[1].val = remotePort; + AddPinholeArgs[2].elt = "Protocol"; + AddPinholeArgs[2].val = proto; + AddPinholeArgs[3].elt = "InternalPort"; + AddPinholeArgs[3].val = intPort; + if(strncmp(intClient, "empty", 5)==0) + { + AddPinholeArgs[4].elt = "InternalClient"; + AddPinholeArgs[4].val = ""; + } + else + { + AddPinholeArgs[4].elt = "InternalClient"; + AddPinholeArgs[4].val = intClient; + } + AddPinholeArgs[5].elt = "LeaseTime"; + AddPinholeArgs[5].val = leaseTime; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "AddPinhole", AddPinholeArgs, &bufsize); + free(AddPinholeArgs); + if(!buffer) + return UPNPCOMMAND_HTTP_ERROR; + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + p = GetValueFromNameValueList(&pdata, "UniqueID"); + if(p) + { + strncpy(uniqueID, p, 8); + uniqueID[7] = '\0'; + } + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) + { + /*printf("AddPortMapping errorCode = '%s'\n", resVal);*/ + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } + else + { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, + const char * uniqueID, + const char * leaseTime) +{ + struct UPNParg * UpdatePinholeArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!uniqueID || !leaseTime) + return UPNPCOMMAND_INVALID_ARGS; + + UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg)); + if(UpdatePinholeArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + UpdatePinholeArgs[0].elt = "UniqueID"; + UpdatePinholeArgs[0].val = uniqueID; + UpdatePinholeArgs[1].elt = "NewLeaseTime"; + UpdatePinholeArgs[1].val = leaseTime; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "UpdatePinhole", UpdatePinholeArgs, &bufsize); + free(UpdatePinholeArgs); + if(!buffer) + return UPNPCOMMAND_HTTP_ERROR; + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) + { + /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } + else + { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID) +{ + /*struct NameValueParserData pdata;*/ + struct UPNParg * DeletePinholeArgs; + char * buffer; + int bufsize; + struct NameValueParserData pdata; + const char * resVal; + int ret; + + if(!uniqueID) + return UPNPCOMMAND_INVALID_ARGS; + + DeletePinholeArgs = calloc(2, sizeof(struct UPNParg)); + if(DeletePinholeArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + DeletePinholeArgs[0].elt = "UniqueID"; + DeletePinholeArgs[0].val = uniqueID; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "DeletePinhole", DeletePinholeArgs, &bufsize); + free(DeletePinholeArgs); + if(!buffer) + return UPNPCOMMAND_HTTP_ERROR; + /*DisplayNameValueList(buffer, bufsize);*/ + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + resVal = GetValueFromNameValueList(&pdata, "errorCode"); + if(resVal) + { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(resVal, "%d", &ret); + } + else + { + ret = UPNPCOMMAND_SUCCESS; + } + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, + const char * uniqueID, int * isWorking) +{ + struct NameValueParserData pdata; + struct UPNParg * CheckPinholeWorkingArgs; + char * buffer; + int bufsize; + char * p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!uniqueID) + return UPNPCOMMAND_INVALID_ARGS; + + CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg)); + if(CheckPinholeWorkingArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + CheckPinholeWorkingArgs[0].elt = "UniqueID"; + CheckPinholeWorkingArgs[0].val = uniqueID; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize); + free(CheckPinholeWorkingArgs); + if(!buffer) + { + return UPNPCOMMAND_HTTP_ERROR; + } + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + p = GetValueFromNameValueList(&pdata, "IsWorking"); + if(p) + { + *isWorking=my_atoui(p); + ret = UPNPCOMMAND_SUCCESS; + } + else + *isWorking = 0; + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) + { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + + ClearNameValueList(&pdata); + return ret; +} + +MINIUPNP_LIBSPEC int +UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, + const char * uniqueID, int * packets) +{ + struct NameValueParserData pdata; + struct UPNParg * GetPinholePacketsArgs; + char * buffer; + int bufsize; + char * p; + int ret = UPNPCOMMAND_UNKNOWN_ERROR; + + if(!uniqueID) + return UPNPCOMMAND_INVALID_ARGS; + + GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg)); + if(GetPinholePacketsArgs == NULL) + return UPNPCOMMAND_MEM_ALLOC_ERROR; + GetPinholePacketsArgs[0].elt = "UniqueID"; + GetPinholePacketsArgs[0].val = uniqueID; + buffer = simpleUPnPcommand(-1, controlURL, servicetype, + "GetPinholePackets", GetPinholePacketsArgs, &bufsize); + free(GetPinholePacketsArgs); + if(!buffer) + return UPNPCOMMAND_HTTP_ERROR; + ParseNameValue(buffer, bufsize, &pdata); + free(buffer); buffer = NULL; + + p = GetValueFromNameValueList(&pdata, "PinholePackets"); + if(p) + { + *packets=my_atoui(p); + ret = UPNPCOMMAND_SUCCESS; + } + + p = GetValueFromNameValueList(&pdata, "errorCode"); + if(p) + { + ret = UPNPCOMMAND_UNKNOWN_ERROR; + sscanf(p, "%d", &ret); + } + + ClearNameValueList(&pdata); + return ret; +} + + diff --git a/deps/miniupnpc/upnpcommands.h b/deps/miniupnpc/upnpcommands.h new file mode 100644 index 0000000000..55b7b060dc --- /dev/null +++ b/deps/miniupnpc/upnpcommands.h @@ -0,0 +1,348 @@ +/* $Id: upnpcommands.h,v 1.30 2015/07/15 12:21:28 nanard Exp $ */ +/* Miniupnp project : http://miniupnp.free.fr/ + * Author : Thomas Bernard + * Copyright (c) 2005-2015 Thomas Bernard + * This software is subject to the conditions detailed in the + * LICENCE file provided within this distribution */ +#ifndef UPNPCOMMANDS_H_INCLUDED +#define UPNPCOMMANDS_H_INCLUDED + +#include "upnpreplyparse.h" +#include "portlistingparse.h" +#include "miniupnpc_declspec.h" +#include "miniupnpctypes.h" + +/* MiniUPnPc return codes : */ +#define UPNPCOMMAND_SUCCESS (0) +#define UPNPCOMMAND_UNKNOWN_ERROR (-1) +#define UPNPCOMMAND_INVALID_ARGS (-2) +#define UPNPCOMMAND_HTTP_ERROR (-3) +#define UPNPCOMMAND_INVALID_RESPONSE (-4) +#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5) + +#ifdef __cplusplus +extern "C" { +#endif + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesSent(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalBytesReceived(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsSent(const char * controlURL, + const char * servicetype); + +MINIUPNP_LIBSPEC UNSIGNED_INTEGER +UPNP_GetTotalPacketsReceived(const char * controlURL, + const char * servicetype); + +/* UPNP_GetStatusInfo() + * status and lastconnerror are 64 byte buffers + * Return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ +MINIUPNP_LIBSPEC int +UPNP_GetStatusInfo(const char * controlURL, + const char * servicetype, + char * status, + unsigned int * uptime, + char * lastconnerror); + +/* UPNP_GetConnectionTypeInfo() + * argument connectionType is a 64 character buffer + * Return Values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error code */ +MINIUPNP_LIBSPEC int +UPNP_GetConnectionTypeInfo(const char * controlURL, + const char * servicetype, + char * connectionType); + +/* UPNP_GetExternalIPAddress() call the corresponding UPNP method. + * if the third arg is not null the value is copied to it. + * at least 16 bytes must be available + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR Either an UPnP error code or an unknown error. + * + * possible UPnP Errors : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. */ +MINIUPNP_LIBSPEC int +UPNP_GetExternalIPAddress(const char * controlURL, + const char * servicetype, + char * extIpAdd); + +/* UPNP_GetLinkLayerMaxBitRates() + * call WANCommonInterfaceConfig:1#GetCommonLinkProperties + * + * return values : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. */ +MINIUPNP_LIBSPEC int +UPNP_GetLinkLayerMaxBitRates(const char* controlURL, + const char* servicetype, + unsigned int * bitrateDown, + unsigned int * bitrateUp); + +/* UPNP_AddPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 718 ConflictInMappingEntry - The port mapping entry specified conflicts + * with a mapping assigned previously to another client + * 724 SamePortValuesRequired - Internal and External port values + * must be the same + * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports + * permanent lease times on port mappings + * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard + * and cannot be a specific IP address or DNS name + * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and + * cannot be a specific port value + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ +MINIUPNP_LIBSPEC int +UPNP_AddPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration); + +/* UPNP_AddAnyPortMapping() + * if desc is NULL, it will be defaulted to "libminiupnpc" + * remoteHost is usually NULL because IGD don't support it. + * + * Return values : + * 0 : SUCCESS + * NON ZERO : ERROR. Either an UPnP error code or an unknown error. + * + * List of possible UPnP errors for AddPortMapping : + * errorCode errorDescription (short) - Description (long) + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization and + * the sender was not authorized. + * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be + * wild-carded + * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded + * 728 NoPortMapsAvailable - There are not enough free ports available to + * complete port mapping. + * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed + * due to conflict with other mechanisms. + * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded + */ +MINIUPNP_LIBSPEC int +UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype, + const char * extPort, + const char * inPort, + const char * inClient, + const char * desc, + const char * proto, + const char * remoteHost, + const char * leaseDuration, + char * reservedPort); + +/* UPNP_DeletePortMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array */ +MINIUPNP_LIBSPEC int +UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, + const char * extPort, const char * proto, + const char * remoteHost); + +/* UPNP_DeletePortRangeMapping() + * Use same argument values as what was used for AddPortMapping(). + * remoteHost is usually NULL because IGD don't support it. + * Return Values : + * 0 : SUCCESS + * NON ZERO : error. Either an UPnP error code or an undefined error. + * + * List of possible UPnP errors for DeletePortMapping : + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 730 PortMappingNotFound - This error message is returned if no port + * mapping is found in the specified range. + * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */ +MINIUPNP_LIBSPEC int +UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype, + const char * extPortStart, const char * extPortEnd, + const char * proto, + const char * manage); + +/* UPNP_GetPortMappingNumberOfEntries() + * not supported by all routers */ +MINIUPNP_LIBSPEC int +UPNP_GetPortMappingNumberOfEntries(const char* controlURL, + const char* servicetype, + unsigned int * num); + +/* UPNP_GetSpecificPortMappingEntry() + * retrieves an existing port mapping + * params : + * in extPort + * in proto + * in remoteHost + * out intClient (16 bytes) + * out intPort (6 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out leaseDuration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * List of possible UPnP errors for _GetSpecificPortMappingEntry : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 501 Action Failed - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 714 NoSuchEntryInArray - The specified value does not exist in the array. + */ +MINIUPNP_LIBSPEC int +UPNP_GetSpecificPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * extPort, + const char * proto, + const char * remoteHost, + char * intClient, + char * intPort, + char * desc, + char * enabled, + char * leaseDuration); + +/* UPNP_GetGenericPortMappingEntry() + * params : + * in index + * out extPort (6 bytes) + * out intClient (16 bytes) + * out intPort (6 bytes) + * out protocol (4 bytes) + * out desc (80 bytes) + * out enabled (4 bytes) + * out rHost (64 bytes) + * out duration (16 bytes) + * + * return value : + * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR + * or a UPnP Error Code. + * + * Possible UPNP Error codes : + * 402 Invalid Args - See UPnP Device Architecture section on Control. + * 606 Action not authorized - The action requested REQUIRES authorization + * and the sender was not authorized. + * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds + */ +MINIUPNP_LIBSPEC int +UPNP_GetGenericPortMappingEntry(const char * controlURL, + const char * servicetype, + const char * index, + char * extPort, + char * intClient, + char * intPort, + char * protocol, + char * desc, + char * enabled, + char * rHost, + char * duration); + +/* UPNP_GetListOfPortMappings() Available in IGD v2 + * + * + * Possible UPNP Error codes : + * 606 Action not Authorized + * 730 PortMappingNotFound - no port mapping is found in the specified range. + * 733 InconsistantParameters - NewStartPort and NewEndPort values are not + * consistent. + */ +MINIUPNP_LIBSPEC int +UPNP_GetListOfPortMappings(const char * controlURL, + const char * servicetype, + const char * startPort, + const char * endPort, + const char * protocol, + const char * numberOfPorts, + struct PortMappingParserData * data); + +/* IGD:2, functions for service WANIPv6FirewallControl:1 */ +MINIUPNP_LIBSPEC int +UPNP_GetFirewallStatus(const char * controlURL, + const char * servicetype, + int * firewallEnabled, + int * inboundPinholeAllowed); + +MINIUPNP_LIBSPEC int +UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + int * opTimeout); + +MINIUPNP_LIBSPEC int +UPNP_AddPinhole(const char * controlURL, const char * servicetype, + const char * remoteHost, + const char * remotePort, + const char * intClient, + const char * intPort, + const char * proto, + const char * leaseTime, + char * uniqueID); + +MINIUPNP_LIBSPEC int +UPNP_UpdatePinhole(const char * controlURL, const char * servicetype, + const char * uniqueID, + const char * leaseTime); + +MINIUPNP_LIBSPEC int +UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID); + +MINIUPNP_LIBSPEC int +UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype, + const char * uniqueID, int * isWorking); + +MINIUPNP_LIBSPEC int +UPNP_GetPinholePackets(const char * controlURL, const char * servicetype, + const char * uniqueID, int * packets); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/deps/miniupnpc/upnpdev.c b/deps/miniupnpc/upnpdev.c new file mode 100644 index 0000000000..d89a9934c3 --- /dev/null +++ b/deps/miniupnpc/upnpdev.c @@ -0,0 +1,23 @@ +/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ +/* Project : miniupnp + * Web : http://miniupnp.free.fr/ + * Author : Thomas BERNARD + * copyright (c) 2005-2015 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENSE file. */ +#include +#include "upnpdev.h" + +/* freeUPNPDevlist() should be used to + * free the chained list returned by upnpDiscover() */ +void freeUPNPDevlist(struct UPNPDev * devlist) +{ + struct UPNPDev * next; + while(devlist) + { + next = devlist->pNext; + free(devlist); + devlist = next; + } +} + diff --git a/deps/miniupnpc/upnpdev.h b/deps/miniupnpc/upnpdev.h new file mode 100644 index 0000000000..f49fbe17ca --- /dev/null +++ b/deps/miniupnpc/upnpdev.h @@ -0,0 +1,36 @@ +/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */ +/* Project : miniupnp + * Web : http://miniupnp.free.fr/ + * Author : Thomas BERNARD + * copyright (c) 2005-2015 Thomas Bernard + * This software is subjet to the conditions detailed in the + * provided LICENSE file. */ +#ifndef UPNPDEV_H_INCLUDED +#define UPNPDEV_H_INCLUDED + +#include "miniupnpc_declspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct UPNPDev { + struct UPNPDev * pNext; + char * descURL; + char * st; + unsigned int scope_id; + char * usn; + char buffer[3]; +}; + +/* freeUPNPDevlist() + * free list returned by upnpDiscover() */ +MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist); + + +#ifdef __cplusplus +} +#endif + + +#endif /* UPNPDEV_H_INCLUDED */ diff --git a/deps/miniupnpc/upnperrors.c b/deps/miniupnpc/upnperrors.c new file mode 100644 index 0000000000..40a2e7857f --- /dev/null +++ b/deps/miniupnpc/upnperrors.c @@ -0,0 +1,107 @@ +/* $Id: upnperrors.c,v 1.5 2011/04/10 11:19:36 nanard Exp $ */ +/* Project : miniupnp + * Author : Thomas BERNARD + * copyright (c) 2007 Thomas Bernard + * All Right reserved. + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#include +#include "upnperrors.h" +#include "upnpcommands.h" +#include "miniupnpc.h" + +const char * strupnperror(int err) +{ + const char * s = NULL; + switch(err) { + case UPNPCOMMAND_SUCCESS: + s = "Success"; + break; + case UPNPCOMMAND_UNKNOWN_ERROR: + s = "Miniupnpc Unknown Error"; + break; + case UPNPCOMMAND_INVALID_ARGS: + s = "Miniupnpc Invalid Arguments"; + break; + case UPNPCOMMAND_INVALID_RESPONSE: + s = "Miniupnpc Invalid response"; + break; + case UPNPDISCOVER_SOCKET_ERROR: + s = "Miniupnpc Socket error"; + break; + case UPNPDISCOVER_MEMORY_ERROR: + s = "Miniupnpc Memory allocation error"; + break; + case 401: + s = "Invalid Action"; + break; + case 402: + s = "Invalid Args"; + break; + case 501: + s = "Action Failed"; + break; + case 606: + s = "Action not authorized"; + break; + case 701: + s = "PinholeSpaceExhausted"; + break; + case 702: + s = "FirewallDisabled"; + break; + case 703: + s = "InboundPinholeNotAllowed"; + break; + case 704: + s = "NoSuchEntry"; + break; + case 705: + s = "ProtocolNotSupported"; + break; + case 706: + s = "InternalPortWildcardingNotAllowed"; + break; + case 707: + s = "ProtocolWildcardingNotAllowed"; + break; + case 708: + s = "WildcardNotPermittedInSrcIP"; + break; + case 709: + s = "NoPacketSent"; + break; + case 713: + s = "SpecifiedArrayIndexInvalid"; + break; + case 714: + s = "NoSuchEntryInArray"; + break; + case 715: + s = "WildCardNotPermittedInSrcIP"; + break; + case 716: + s = "WildCardNotPermittedInExtPort"; + break; + case 718: + s = "ConflictInMappingEntry"; + break; + case 724: + s = "SamePortValuesRequired"; + break; + case 725: + s = "OnlyPermanentLeasesSupported"; + break; + case 726: + s = "RemoteHostOnlySupportsWildcard"; + break; + case 727: + s = "ExternalPortOnlySupportsWildcard"; + break; + default: + s = "UnknownError"; + break; + } + return s; +} diff --git a/deps/miniupnpc/upnperrors.h b/deps/miniupnpc/upnperrors.h new file mode 100644 index 0000000000..8499d9a1c9 --- /dev/null +++ b/deps/miniupnpc/upnperrors.h @@ -0,0 +1,26 @@ +/* $Id: upnperrors.h,v 1.2 2008/07/02 23:31:15 nanard Exp $ */ +/* (c) 2007-2015 Thomas Bernard + * All rights reserved. + * MiniUPnP Project. + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * This software is subjet to the conditions detailed in the + * provided LICENCE file. */ +#ifndef UPNPERRORS_H_INCLUDED +#define UPNPERRORS_H_INCLUDED + +#include "miniupnpc_declspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* strupnperror() + * Return a string description of the UPnP error code + * or NULL for undefinded errors */ +MINIUPNP_LIBSPEC const char * strupnperror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/miniupnpc/upnpreplyparse.c b/deps/miniupnpc/upnpreplyparse.c new file mode 100644 index 0000000000..5de5796a39 --- /dev/null +++ b/deps/miniupnpc/upnpreplyparse.c @@ -0,0 +1,197 @@ +/* $Id: upnpreplyparse.c,v 1.19 2015/07/15 10:29:11 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2006-2015 Thomas Bernard + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ + +#include +#include +#include + +#include "upnpreplyparse.h" +#include "minixml.h" + +static void +NameValueParserStartElt(void * d, const char * name, int l) +{ + struct NameValueParserData * data = (struct NameValueParserData *)d; + data->topelt = 1; + if(l>63) + l = 63; + memcpy(data->curelt, name, l); + data->curelt[l] = '\0'; + data->cdata = NULL; + data->cdatalen = 0; +} + +static void +NameValueParserEndElt(void * d, const char * name, int l) +{ + struct NameValueParserData * data = (struct NameValueParserData *)d; + struct NameValue * nv; + (void)name; + (void)l; + if(!data->topelt) + return; + if(strcmp(data->curelt, "NewPortListing") != 0) + { + int l; + /* standard case. Limited to n chars strings */ + l = data->cdatalen; + nv = malloc(sizeof(struct NameValue)); + if(nv == NULL) + { + /* malloc error */ +#ifdef DEBUG + fprintf(stderr, "%s: error allocating memory", + "NameValueParserEndElt"); +#endif /* DEBUG */ + return; + } + if(l>=(int)sizeof(nv->value)) + l = sizeof(nv->value) - 1; + strncpy(nv->name, data->curelt, 64); + nv->name[63] = '\0'; + if(data->cdata != NULL) + { + memcpy(nv->value, data->cdata, l); + nv->value[l] = '\0'; + } + else + { + nv->value[0] = '\0'; + } + nv->l_next = data->l_head; /* insert in list */ + data->l_head = nv; + } + data->cdata = NULL; + data->cdatalen = 0; + data->topelt = 0; +} + +static void +NameValueParserGetData(void * d, const char * datas, int l) +{ + struct NameValueParserData * data = (struct NameValueParserData *)d; + if(strcmp(data->curelt, "NewPortListing") == 0) + { + /* specific case for NewPortListing which is a XML Document */ + data->portListing = malloc(l + 1); + if(!data->portListing) + { + /* malloc error */ +#ifdef DEBUG + fprintf(stderr, "%s: error allocating memory", + "NameValueParserGetData"); +#endif /* DEBUG */ + return; + } + memcpy(data->portListing, datas, l); + data->portListing[l] = '\0'; + data->portListingLength = l; + } + else + { + /* standard case. */ + data->cdata = datas; + data->cdatalen = l; + } +} + +void +ParseNameValue(const char * buffer, int bufsize, + struct NameValueParserData * data) +{ + struct xmlparser parser; + data->l_head = NULL; + data->portListing = NULL; + data->portListingLength = 0; + /* init xmlparser object */ + parser.xmlstart = buffer; + parser.xmlsize = bufsize; + parser.data = data; + parser.starteltfunc = NameValueParserStartElt; + parser.endeltfunc = NameValueParserEndElt; + parser.datafunc = NameValueParserGetData; + parser.attfunc = 0; + parsexml(&parser); +} + +void +ClearNameValueList(struct NameValueParserData * pdata) +{ + struct NameValue * nv; + if(pdata->portListing) + { + free(pdata->portListing); + pdata->portListing = NULL; + pdata->portListingLength = 0; + } + while((nv = pdata->l_head) != NULL) + { + pdata->l_head = nv->l_next; + free(nv); + } +} + +char * +GetValueFromNameValueList(struct NameValueParserData * pdata, + const char * Name) +{ + struct NameValue * nv; + char * p = NULL; + for(nv = pdata->l_head; + (nv != NULL) && (p == NULL); + nv = nv->l_next) + { + if(strcmp(nv->name, Name) == 0) + p = nv->value; + } + return p; +} + +#if 0 +/* useless now that minixml ignores namespaces by itself */ +char * +GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, + const char * Name) +{ + struct NameValue * nv; + char * p = NULL; + char * pname; + for(nv = pdata->head.lh_first; + (nv != NULL) && (p == NULL); + nv = nv->entries.le_next) + { + pname = strrchr(nv->name, ':'); + if(pname) + pname++; + else + pname = nv->name; + if(strcmp(pname, Name)==0) + p = nv->value; + } + return p; +} +#endif + +/* debug all-in-one function + * do parsing then display to stdout */ +#ifdef DEBUG +void +DisplayNameValueList(char * buffer, int bufsize) +{ + struct NameValueParserData pdata; + struct NameValue * nv; + ParseNameValue(buffer, bufsize, &pdata); + for(nv = pdata.l_head; + nv != NULL; + nv = nv->l_next) + { + printf("%s = %s\n", nv->name, nv->value); + } + ClearNameValueList(&pdata); +} +#endif /* DEBUG */ + diff --git a/deps/miniupnpc/upnpreplyparse.h b/deps/miniupnpc/upnpreplyparse.h new file mode 100644 index 0000000000..6badd15b26 --- /dev/null +++ b/deps/miniupnpc/upnpreplyparse.h @@ -0,0 +1,63 @@ +/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */ +/* MiniUPnP project + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * (c) 2006-2013 Thomas Bernard + * This software is subject to the conditions detailed + * in the LICENCE file provided within the distribution */ + +#ifndef UPNPREPLYPARSE_H_INCLUDED +#define UPNPREPLYPARSE_H_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +struct NameValue { + struct NameValue * l_next; + char name[64]; + char value[128]; +}; + +struct NameValueParserData { + struct NameValue * l_head; + char curelt[64]; + char * portListing; + int portListingLength; + int topelt; + const char * cdata; + int cdatalen; +}; + +/* ParseNameValue() */ +void +ParseNameValue(const char * buffer, int bufsize, + struct NameValueParserData * data); + +/* ClearNameValueList() */ +void +ClearNameValueList(struct NameValueParserData * pdata); + +/* GetValueFromNameValueList() */ +char * +GetValueFromNameValueList(struct NameValueParserData * pdata, + const char * Name); + +#if 0 +/* GetValueFromNameValueListIgnoreNS() */ +char * +GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata, + const char * Name); +#endif + +/* DisplayNameValueList() */ +#ifdef DEBUG +void +DisplayNameValueList(char * buffer, int bufsize); +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/griffin/griffin.c b/griffin/griffin.c index cf1efc8d58..7c8dc2e1e2 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1128,6 +1128,22 @@ XML #include "../database_info.c" #endif +#if defined(HAVE_BUILTINMINIUPNPC) +#include "../deps/miniupnpc/igd_desc_parse.c" +#include "../deps/miniupnpc/upnpreplyparse.c" +#include "../deps/miniupnpc/upnpcommands.c" +#include "../deps/miniupnpc/upnperrors.c" +#include "../deps/miniupnpc/connecthostport.c" +#include "../deps/miniupnpc/portlistingparse.c" +#include "../deps/miniupnpc/receivedata.c" +#include "../deps/miniupnpc/upnpdev.c" +#include "../deps/miniupnpc/minissdpc.c" +#include "../deps/miniupnpc/miniwget.c" +#include "../deps/miniupnpc/miniupnpc.c" +#include "../deps/miniupnpc/minixml.c" +#include "../deps/miniupnpc/minisoap.c" +#endif + /*============================================================ HTTP SERVER ============================================================ */ diff --git a/qb/config.libs.sh b/qb/config.libs.sh index 6ef3ac614d..94959cad98 100644 --- a/qb/config.libs.sh +++ b/qb/config.libs.sh @@ -195,6 +195,10 @@ if [ "$HAVE_NETWORKING" = 'yes' ]; then if [ "$HAVE_MINIUPNPC" != "no" ]; then check_lib MINIUPNPC "-lminiupnpc" fi + + if [ "$HAVE_BUILTINMINIUPNPC" = "yes" ]; then + HAVE_MINIUPNPC='yes' + fi else echo "Warning: All networking features have been disabled." HAVE_NETWORK_CMD='no' diff --git a/qb/config.params.sh b/qb/config.params.sh index 36e7eda08f..9a75385df0 100644 --- a/qb/config.params.sh +++ b/qb/config.params.sh @@ -30,6 +30,7 @@ HAVE_NETWORKING=auto # Networking features (recommended) HAVE_NETWORKGAMEPAD=auto # Networked game pad (plus baked-in core) C89_NETWORKGAMEPAD=no HAVE_MINIUPNPC=auto # Mini UPnP client library (for NAT traversal) +HAVE_BUILTINMINIUPNPC=no # Bake in Mini UPnP client library (for NAT traversal) HAVE_D3D9=yes # Direct3D 9 support HAVE_OPENGL=auto # OpenGL support HAVE_MALI_FBDEV=no # Mali fbdev context support From db4b7578433013ae5b9150c28285ff113a19978c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 15 Feb 2017 21:06:16 +0100 Subject: [PATCH 86/90] Add missing file --- deps/miniupnpc/miniupnpcstrings.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 deps/miniupnpc/miniupnpcstrings.h diff --git a/deps/miniupnpc/miniupnpcstrings.h b/deps/miniupnpc/miniupnpcstrings.h new file mode 100644 index 0000000000..68bf4293df --- /dev/null +++ b/deps/miniupnpc/miniupnpcstrings.h @@ -0,0 +1,23 @@ +/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */ +/* Project: miniupnp + * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ + * Author: Thomas Bernard + * Copyright (c) 2005-2014 Thomas Bernard + * This software is subjects to the conditions detailed + * in the LICENCE file provided within this distribution */ +#ifndef MINIUPNPCSTRINGS_H_INCLUDED +#define MINIUPNPCSTRINGS_H_INCLUDED + +#define OS_STRING "OS/version" +#define MINIUPNPC_VERSION_STRING "version" + +#if 0 +/* according to "UPnP Device Architecture 1.0" */ +#define UPNP_VERSION_STRING "UPnP/1.0" +#else +/* according to "UPnP Device Architecture 1.1" */ +#define UPNP_VERSION_STRING "UPnP/1.1" +#endif + +#endif + From 1b2685949a481d2dc477ce2adb3873883f1b88fe Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Wed, 15 Feb 2017 21:30:47 +0000 Subject: [PATCH 87/90] Fix for when net_http_get returns NET_HTTP_GET_OK but a NULL body --- cheevos/cheevos.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 979a78a878..6ada9611b8 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -724,11 +724,19 @@ static int cheevos_http_get(const char **result, size_t *size, int ret = net_http_get(result, size, url, timeout); #endif + if (ret == NET_HTTP_GET_OK) + { + if (*result != NULL) + { + return ret; + } + + RARCH_ERR("CHEEVOS error during HTTP GET: ok.\n"); + return NET_HTTP_GET_CONNECT_ERROR; + } + switch (ret) { - case NET_HTTP_GET_OK: - return ret; - case NET_HTTP_GET_MALFORMED_URL: msg = "malformed url"; break; @@ -742,7 +750,7 @@ static int cheevos_http_get(const char **result, size_t *size, break; default: - msg = "?"; + msg = "unknown error"; break; } From 3a6c7b96fd95530a6517963bff3ca2dc2ce43a74 Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 15 Feb 2017 18:15:42 -0500 Subject: [PATCH 88/90] prevent null check --- tasks/task_netplay_find_content.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 5a154095d9..585384a96b 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -272,7 +272,8 @@ bool task_push_netplay_crc_scan(uint32_t crc, char* name, { strlcpy(state->core_path, info->list[i].path, sizeof(state->core_path)); - if (!string_is_equal(state->content_path, "N/A")) + if (!string_is_equal(state->content_path, "N/A") && + !string_is_empty(info->list[i].supported_extensions)) { strlcpy(state->core_extensions, info->list[i].supported_extensions, sizeof(state->core_extensions)); From f00dd6f7c407ed0d41ee572ca2ae742297d0b14a Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 15 Feb 2017 18:25:21 -0500 Subject: [PATCH 89/90] update changelog & copyright --- CHANGES.md | 9 +++++++-- tasks/task_netplay_find_content.c | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 82e3282484..629c13ba29 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,16 +1,21 @@ # 1.4.2 (future) - ANDROID: Autoconf fallback +- AUTOCONF: Fix partial matches for pad name - CHEEVOS: Fix crashes in the cheevos description menu - CHEEVOS: WIP leaderboards support - COMMON: Threading fixes - DOS: Add keyboard driver - DOS: Improve color accuracy and scalines +- GUI: Various settings are now only visible when advanced settings is enabled - LOCALIZATION: Rewrite german translation - LOCALIZATION: Update several english sublabels - NET: Allow manual netplay content loading - NET: Announcing network games to the public lobby is optional now -- NET: fix netplay join for contentless cores -- SCANNER: always add 7z & zip to supported extensions +- NET: Bake in miniupnpc +- NET: Fix netplay join for contentless cores +- SCANNER: Always add 7z & zip to supported extensions +- VULKAN: Find supported composite alpha in swapchain - WIIU: Keyboard support +- WINDOWS: Logging to file no longer spawns an empty window # 1.4.1 diff --git a/tasks/task_netplay_find_content.c b/tasks/task_netplay_find_content.c index 585384a96b..2a255695e0 100644 --- a/tasks/task_netplay_find_content.c +++ b/tasks/task_netplay_find_content.c @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. - * Copyright (C) 2016 - Jean-André Santoni + * Copyright (C) 2017 - Jean-André Santoni + * Copyright (C) 2017 - Andrés Suárez * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- From 14c1d48c66ed1404db75e34692a4a1b444391895 Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 15 Feb 2017 18:26:18 -0500 Subject: [PATCH 90/90] update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 629c13ba29..3c5065c92f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ # 1.4.2 (future) - ANDROID: Autoconf fallback +- ANDROID: Mouse support / Emulated mouse support - AUTOCONF: Fix partial matches for pad name - CHEEVOS: Fix crashes in the cheevos description menu - CHEEVOS: WIP leaderboards support