diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/android/id_cache.cpp | 163 | ||||
| -rw-r--r-- | src/common/android/id_cache.h | 24 | ||||
| -rw-r--r-- | src/common/demangle.cpp | 4 | ||||
| -rw-r--r-- | src/common/host_memory.cpp | 4 | ||||
| -rw-r--r-- | src/common/page_table.cpp | 4 | ||||
| -rw-r--r-- | src/common/scope_exit.h | 66 | ||||
| -rw-r--r-- | src/common/settings_input.h | 4 |
7 files changed, 244 insertions, 25 deletions
diff --git a/src/common/android/id_cache.cpp b/src/common/android/id_cache.cpp index f39262db9..1145cbdf2 100644 --- a/src/common/android/id_cache.cpp +++ b/src/common/android/id_cache.cpp | |||
| @@ -65,6 +65,30 @@ static jclass s_boolean_class; | |||
| 65 | static jmethodID s_boolean_constructor; | 65 | static jmethodID s_boolean_constructor; |
| 66 | static jfieldID s_boolean_value_field; | 66 | static jfieldID s_boolean_value_field; |
| 67 | 67 | ||
| 68 | static jclass s_player_input_class; | ||
| 69 | static jmethodID s_player_input_constructor; | ||
| 70 | static jfieldID s_player_input_connected_field; | ||
| 71 | static jfieldID s_player_input_buttons_field; | ||
| 72 | static jfieldID s_player_input_analogs_field; | ||
| 73 | static jfieldID s_player_input_motions_field; | ||
| 74 | static jfieldID s_player_input_vibration_enabled_field; | ||
| 75 | static jfieldID s_player_input_vibration_strength_field; | ||
| 76 | static jfieldID s_player_input_body_color_left_field; | ||
| 77 | static jfieldID s_player_input_body_color_right_field; | ||
| 78 | static jfieldID s_player_input_button_color_left_field; | ||
| 79 | static jfieldID s_player_input_button_color_right_field; | ||
| 80 | static jfieldID s_player_input_profile_name_field; | ||
| 81 | static jfieldID s_player_input_use_system_vibrator_field; | ||
| 82 | |||
| 83 | static jclass s_yuzu_input_device_interface; | ||
| 84 | static jmethodID s_yuzu_input_device_get_name; | ||
| 85 | static jmethodID s_yuzu_input_device_get_guid; | ||
| 86 | static jmethodID s_yuzu_input_device_get_port; | ||
| 87 | static jmethodID s_yuzu_input_device_get_supports_vibration; | ||
| 88 | static jmethodID s_yuzu_input_device_vibrate; | ||
| 89 | static jmethodID s_yuzu_input_device_get_axes; | ||
| 90 | static jmethodID s_yuzu_input_device_has_keys; | ||
| 91 | |||
| 68 | static constexpr jint JNI_VERSION = JNI_VERSION_1_6; | 92 | static constexpr jint JNI_VERSION = JNI_VERSION_1_6; |
| 69 | 93 | ||
| 70 | namespace Common::Android { | 94 | namespace Common::Android { |
| @@ -276,6 +300,94 @@ jfieldID GetBooleanValueField() { | |||
| 276 | return s_boolean_value_field; | 300 | return s_boolean_value_field; |
| 277 | } | 301 | } |
| 278 | 302 | ||
| 303 | jclass GetPlayerInputClass() { | ||
| 304 | return s_player_input_class; | ||
| 305 | } | ||
| 306 | |||
| 307 | jmethodID GetPlayerInputConstructor() { | ||
| 308 | return s_player_input_constructor; | ||
| 309 | } | ||
| 310 | |||
| 311 | jfieldID GetPlayerInputConnectedField() { | ||
| 312 | return s_player_input_connected_field; | ||
| 313 | } | ||
| 314 | |||
| 315 | jfieldID GetPlayerInputButtonsField() { | ||
| 316 | return s_player_input_buttons_field; | ||
| 317 | } | ||
| 318 | |||
| 319 | jfieldID GetPlayerInputAnalogsField() { | ||
| 320 | return s_player_input_analogs_field; | ||
| 321 | } | ||
| 322 | |||
| 323 | jfieldID GetPlayerInputMotionsField() { | ||
| 324 | return s_player_input_motions_field; | ||
| 325 | } | ||
| 326 | |||
| 327 | jfieldID GetPlayerInputVibrationEnabledField() { | ||
| 328 | return s_player_input_vibration_enabled_field; | ||
| 329 | } | ||
| 330 | |||
| 331 | jfieldID GetPlayerInputVibrationStrengthField() { | ||
| 332 | return s_player_input_vibration_strength_field; | ||
| 333 | } | ||
| 334 | |||
| 335 | jfieldID GetPlayerInputBodyColorLeftField() { | ||
| 336 | return s_player_input_body_color_left_field; | ||
| 337 | } | ||
| 338 | |||
| 339 | jfieldID GetPlayerInputBodyColorRightField() { | ||
| 340 | return s_player_input_body_color_right_field; | ||
| 341 | } | ||
| 342 | |||
| 343 | jfieldID GetPlayerInputButtonColorLeftField() { | ||
| 344 | return s_player_input_button_color_left_field; | ||
| 345 | } | ||
| 346 | |||
| 347 | jfieldID GetPlayerInputButtonColorRightField() { | ||
| 348 | return s_player_input_button_color_right_field; | ||
| 349 | } | ||
| 350 | |||
| 351 | jfieldID GetPlayerInputProfileNameField() { | ||
| 352 | return s_player_input_profile_name_field; | ||
| 353 | } | ||
| 354 | |||
| 355 | jfieldID GetPlayerInputUseSystemVibratorField() { | ||
| 356 | return s_player_input_use_system_vibrator_field; | ||
| 357 | } | ||
| 358 | |||
| 359 | jclass GetYuzuInputDeviceInterface() { | ||
| 360 | return s_yuzu_input_device_interface; | ||
| 361 | } | ||
| 362 | |||
| 363 | jmethodID GetYuzuDeviceGetName() { | ||
| 364 | return s_yuzu_input_device_get_name; | ||
| 365 | } | ||
| 366 | |||
| 367 | jmethodID GetYuzuDeviceGetGUID() { | ||
| 368 | return s_yuzu_input_device_get_guid; | ||
| 369 | } | ||
| 370 | |||
| 371 | jmethodID GetYuzuDeviceGetPort() { | ||
| 372 | return s_yuzu_input_device_get_port; | ||
| 373 | } | ||
| 374 | |||
| 375 | jmethodID GetYuzuDeviceGetSupportsVibration() { | ||
| 376 | return s_yuzu_input_device_get_supports_vibration; | ||
| 377 | } | ||
| 378 | |||
| 379 | jmethodID GetYuzuDeviceVibrate() { | ||
| 380 | return s_yuzu_input_device_vibrate; | ||
| 381 | } | ||
| 382 | |||
| 383 | jmethodID GetYuzuDeviceGetAxes() { | ||
| 384 | return s_yuzu_input_device_get_axes; | ||
| 385 | } | ||
| 386 | |||
| 387 | jmethodID GetYuzuDeviceHasKeys() { | ||
| 388 | return s_yuzu_input_device_has_keys; | ||
| 389 | } | ||
| 390 | |||
| 279 | #ifdef __cplusplus | 391 | #ifdef __cplusplus |
| 280 | extern "C" { | 392 | extern "C" { |
| 281 | #endif | 393 | #endif |
| @@ -387,6 +499,55 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) { | |||
| 387 | s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z"); | 499 | s_boolean_value_field = env->GetFieldID(boolean_class, "value", "Z"); |
| 388 | env->DeleteLocalRef(boolean_class); | 500 | env->DeleteLocalRef(boolean_class); |
| 389 | 501 | ||
| 502 | const jclass player_input_class = | ||
| 503 | env->FindClass("org/yuzu/yuzu_emu/features/input/model/PlayerInput"); | ||
| 504 | s_player_input_class = reinterpret_cast<jclass>(env->NewGlobalRef(player_input_class)); | ||
| 505 | s_player_input_constructor = env->GetMethodID( | ||
| 506 | player_input_class, "<init>", | ||
| 507 | "(Z[Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;ZIJJJJLjava/lang/String;Z)V"); | ||
| 508 | s_player_input_connected_field = env->GetFieldID(player_input_class, "connected", "Z"); | ||
| 509 | s_player_input_buttons_field = | ||
| 510 | env->GetFieldID(player_input_class, "buttons", "[Ljava/lang/String;"); | ||
| 511 | s_player_input_analogs_field = | ||
| 512 | env->GetFieldID(player_input_class, "analogs", "[Ljava/lang/String;"); | ||
| 513 | s_player_input_motions_field = | ||
| 514 | env->GetFieldID(player_input_class, "motions", "[Ljava/lang/String;"); | ||
| 515 | s_player_input_vibration_enabled_field = | ||
| 516 | env->GetFieldID(player_input_class, "vibrationEnabled", "Z"); | ||
| 517 | s_player_input_vibration_strength_field = | ||
| 518 | env->GetFieldID(player_input_class, "vibrationStrength", "I"); | ||
| 519 | s_player_input_body_color_left_field = | ||
| 520 | env->GetFieldID(player_input_class, "bodyColorLeft", "J"); | ||
| 521 | s_player_input_body_color_right_field = | ||
| 522 | env->GetFieldID(player_input_class, "bodyColorRight", "J"); | ||
| 523 | s_player_input_button_color_left_field = | ||
| 524 | env->GetFieldID(player_input_class, "buttonColorLeft", "J"); | ||
| 525 | s_player_input_button_color_right_field = | ||
| 526 | env->GetFieldID(player_input_class, "buttonColorRight", "J"); | ||
| 527 | s_player_input_profile_name_field = | ||
| 528 | env->GetFieldID(player_input_class, "profileName", "Ljava/lang/String;"); | ||
| 529 | s_player_input_use_system_vibrator_field = | ||
| 530 | env->GetFieldID(player_input_class, "useSystemVibrator", "Z"); | ||
| 531 | env->DeleteLocalRef(player_input_class); | ||
| 532 | |||
| 533 | const jclass yuzu_input_device_interface = | ||
| 534 | env->FindClass("org/yuzu/yuzu_emu/features/input/YuzuInputDevice"); | ||
| 535 | s_yuzu_input_device_interface = | ||
| 536 | reinterpret_cast<jclass>(env->NewGlobalRef(yuzu_input_device_interface)); | ||
| 537 | s_yuzu_input_device_get_name = | ||
| 538 | env->GetMethodID(yuzu_input_device_interface, "getName", "()Ljava/lang/String;"); | ||
| 539 | s_yuzu_input_device_get_guid = | ||
| 540 | env->GetMethodID(yuzu_input_device_interface, "getGUID", "()Ljava/lang/String;"); | ||
| 541 | s_yuzu_input_device_get_port = env->GetMethodID(yuzu_input_device_interface, "getPort", "()I"); | ||
| 542 | s_yuzu_input_device_get_supports_vibration = | ||
| 543 | env->GetMethodID(yuzu_input_device_interface, "getSupportsVibration", "()Z"); | ||
| 544 | s_yuzu_input_device_vibrate = env->GetMethodID(yuzu_input_device_interface, "vibrate", "(F)V"); | ||
| 545 | s_yuzu_input_device_get_axes = | ||
| 546 | env->GetMethodID(yuzu_input_device_interface, "getAxes", "()[Ljava/lang/Integer;"); | ||
| 547 | s_yuzu_input_device_has_keys = | ||
| 548 | env->GetMethodID(yuzu_input_device_interface, "hasKeys", "([I)[Z"); | ||
| 549 | env->DeleteLocalRef(yuzu_input_device_interface); | ||
| 550 | |||
| 390 | // Initialize Android Storage | 551 | // Initialize Android Storage |
| 391 | Common::FS::Android::RegisterCallbacks(env, s_native_library_class); | 552 | Common::FS::Android::RegisterCallbacks(env, s_native_library_class); |
| 392 | 553 | ||
| @@ -416,6 +577,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved) { | |||
| 416 | env->DeleteGlobalRef(s_double_class); | 577 | env->DeleteGlobalRef(s_double_class); |
| 417 | env->DeleteGlobalRef(s_integer_class); | 578 | env->DeleteGlobalRef(s_integer_class); |
| 418 | env->DeleteGlobalRef(s_boolean_class); | 579 | env->DeleteGlobalRef(s_boolean_class); |
| 580 | env->DeleteGlobalRef(s_player_input_class); | ||
| 581 | env->DeleteGlobalRef(s_yuzu_input_device_interface); | ||
| 419 | 582 | ||
| 420 | // UnInitialize applets | 583 | // UnInitialize applets |
| 421 | SoftwareKeyboard::CleanupJNI(env); | 584 | SoftwareKeyboard::CleanupJNI(env); |
diff --git a/src/common/android/id_cache.h b/src/common/android/id_cache.h index 47802f96c..cd2844dcc 100644 --- a/src/common/android/id_cache.h +++ b/src/common/android/id_cache.h | |||
| @@ -85,4 +85,28 @@ jclass GetBooleanClass(); | |||
| 85 | jmethodID GetBooleanConstructor(); | 85 | jmethodID GetBooleanConstructor(); |
| 86 | jfieldID GetBooleanValueField(); | 86 | jfieldID GetBooleanValueField(); |
| 87 | 87 | ||
| 88 | jclass GetPlayerInputClass(); | ||
| 89 | jmethodID GetPlayerInputConstructor(); | ||
| 90 | jfieldID GetPlayerInputConnectedField(); | ||
| 91 | jfieldID GetPlayerInputButtonsField(); | ||
| 92 | jfieldID GetPlayerInputAnalogsField(); | ||
| 93 | jfieldID GetPlayerInputMotionsField(); | ||
| 94 | jfieldID GetPlayerInputVibrationEnabledField(); | ||
| 95 | jfieldID GetPlayerInputVibrationStrengthField(); | ||
| 96 | jfieldID GetPlayerInputBodyColorLeftField(); | ||
| 97 | jfieldID GetPlayerInputBodyColorRightField(); | ||
| 98 | jfieldID GetPlayerInputButtonColorLeftField(); | ||
| 99 | jfieldID GetPlayerInputButtonColorRightField(); | ||
| 100 | jfieldID GetPlayerInputProfileNameField(); | ||
| 101 | jfieldID GetPlayerInputUseSystemVibratorField(); | ||
| 102 | |||
| 103 | jclass GetYuzuInputDeviceInterface(); | ||
| 104 | jmethodID GetYuzuDeviceGetName(); | ||
| 105 | jmethodID GetYuzuDeviceGetGUID(); | ||
| 106 | jmethodID GetYuzuDeviceGetPort(); | ||
| 107 | jmethodID GetYuzuDeviceGetSupportsVibration(); | ||
| 108 | jmethodID GetYuzuDeviceVibrate(); | ||
| 109 | jmethodID GetYuzuDeviceGetAxes(); | ||
| 110 | jmethodID GetYuzuDeviceHasKeys(); | ||
| 111 | |||
| 88 | } // namespace Common::Android | 112 | } // namespace Common::Android |
diff --git a/src/common/demangle.cpp b/src/common/demangle.cpp index 6e117cb41..b2c9d126a 100644 --- a/src/common/demangle.cpp +++ b/src/common/demangle.cpp | |||
| @@ -20,7 +20,9 @@ std::string DemangleSymbol(const std::string& mangled) { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | char* demangled = nullptr; | 22 | char* demangled = nullptr; |
| 23 | SCOPE_EXIT({ std::free(demangled); }); | 23 | SCOPE_EXIT { |
| 24 | std::free(demangled); | ||
| 25 | }; | ||
| 24 | 26 | ||
| 25 | if (is_itanium(mangled)) { | 27 | if (is_itanium(mangled)) { |
| 26 | demangled = llvm::itaniumDemangle(mangled.c_str()); | 28 | demangled = llvm::itaniumDemangle(mangled.c_str()); |
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 860c39e6a..e0b5a6a67 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -430,11 +430,11 @@ public: | |||
| 430 | explicit Impl(size_t backing_size_, size_t virtual_size_) | 430 | explicit Impl(size_t backing_size_, size_t virtual_size_) |
| 431 | : backing_size{backing_size_}, virtual_size{virtual_size_} { | 431 | : backing_size{backing_size_}, virtual_size{virtual_size_} { |
| 432 | bool good = false; | 432 | bool good = false; |
| 433 | SCOPE_EXIT({ | 433 | SCOPE_EXIT { |
| 434 | if (!good) { | 434 | if (!good) { |
| 435 | Release(); | 435 | Release(); |
| 436 | } | 436 | } |
| 437 | }); | 437 | }; |
| 438 | 438 | ||
| 439 | long page_size = sysconf(_SC_PAGESIZE); | 439 | long page_size = sysconf(_SC_PAGESIZE); |
| 440 | if (page_size != 0x1000) { | 440 | if (page_size != 0x1000) { |
diff --git a/src/common/page_table.cpp b/src/common/page_table.cpp index 85dc18c11..3205eb7da 100644 --- a/src/common/page_table.cpp +++ b/src/common/page_table.cpp | |||
| @@ -24,10 +24,10 @@ bool PageTable::ContinueTraversal(TraversalEntry* out_entry, TraversalContext* c | |||
| 24 | out_entry->block_size = page_size; | 24 | out_entry->block_size = page_size; |
| 25 | 25 | ||
| 26 | // Regardless of whether the page was mapped, advance on exit. | 26 | // Regardless of whether the page was mapped, advance on exit. |
| 27 | SCOPE_EXIT({ | 27 | SCOPE_EXIT { |
| 28 | context->next_page += 1; | 28 | context->next_page += 1; |
| 29 | context->next_offset += page_size; | 29 | context->next_offset += page_size; |
| 30 | }); | 30 | }; |
| 31 | 31 | ||
| 32 | // Validate that we can read the actual entry. | 32 | // Validate that we can read the actual entry. |
| 33 | const auto page = context->next_page; | 33 | const auto page = context->next_page; |
diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index e9c789c88..f3e88cde9 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h | |||
| @@ -7,29 +7,61 @@ | |||
| 7 | #include "common/common_funcs.h" | 7 | #include "common/common_funcs.h" |
| 8 | 8 | ||
| 9 | namespace detail { | 9 | namespace detail { |
| 10 | template <typename Func> | 10 | template <class F> |
| 11 | struct ScopeExitHelper { | 11 | class ScopeGuard { |
| 12 | explicit ScopeExitHelper(Func&& func_) : func(std::move(func_)) {} | 12 | YUZU_NON_COPYABLE(ScopeGuard); |
| 13 | ~ScopeExitHelper() { | 13 | |
| 14 | private: | ||
| 15 | F f; | ||
| 16 | bool active; | ||
| 17 | |||
| 18 | public: | ||
| 19 | constexpr ScopeGuard(F f_) : f(std::move(f_)), active(true) {} | ||
| 20 | constexpr ~ScopeGuard() { | ||
| 14 | if (active) { | 21 | if (active) { |
| 15 | func(); | 22 | f(); |
| 16 | } | 23 | } |
| 17 | } | 24 | } |
| 18 | 25 | constexpr void Cancel() { | |
| 19 | void Cancel() { | ||
| 20 | active = false; | 26 | active = false; |
| 21 | } | 27 | } |
| 22 | 28 | ||
| 23 | Func func; | 29 | constexpr ScopeGuard(ScopeGuard&& rhs) : f(std::move(rhs.f)), active(rhs.active) { |
| 24 | bool active{true}; | 30 | rhs.Cancel(); |
| 31 | } | ||
| 32 | |||
| 33 | ScopeGuard& operator=(ScopeGuard&& rhs) = delete; | ||
| 25 | }; | 34 | }; |
| 26 | 35 | ||
| 27 | template <typename Func> | 36 | template <class F> |
| 28 | ScopeExitHelper<Func> ScopeExit(Func&& func) { | 37 | constexpr ScopeGuard<F> MakeScopeGuard(F f) { |
| 29 | return ScopeExitHelper<Func>(std::forward<Func>(func)); | 38 | return ScopeGuard<F>(std::move(f)); |
| 30 | } | 39 | } |
| 40 | |||
| 41 | enum class ScopeGuardOnExit {}; | ||
| 42 | |||
| 43 | template <typename F> | ||
| 44 | constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) { | ||
| 45 | return ScopeGuard<F>(std::forward<F>(f)); | ||
| 46 | } | ||
| 47 | |||
| 31 | } // namespace detail | 48 | } // namespace detail |
| 32 | 49 | ||
| 50 | #define CONCATENATE_IMPL(s1, s2) s1##s2 | ||
| 51 | #define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2) | ||
| 52 | |||
| 53 | #ifdef __COUNTER__ | ||
| 54 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __COUNTER__) | ||
| 55 | #else | ||
| 56 | #define ANONYMOUS_VARIABLE(pref) CONCATENATE(pref, __LINE__) | ||
| 57 | #endif | ||
| 58 | |||
| 59 | /** | ||
| 60 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be | ||
| 61 | * used when the caller might want to cancel the ScopeExit. | ||
| 62 | */ | ||
| 63 | #define SCOPE_GUARD detail::ScopeGuardOnExit() + [&]() | ||
| 64 | |||
| 33 | /** | 65 | /** |
| 34 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy | 66 | * This macro allows you to conveniently specify a block of code that will run on scope exit. Handy |
| 35 | * for doing ad-hoc clean-up tasks in a function with multiple returns. | 67 | * for doing ad-hoc clean-up tasks in a function with multiple returns. |
| @@ -38,7 +70,7 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { | |||
| 38 | * \code | 70 | * \code |
| 39 | * const int saved_val = g_foo; | 71 | * const int saved_val = g_foo; |
| 40 | * g_foo = 55; | 72 | * g_foo = 55; |
| 41 | * SCOPE_EXIT({ g_foo = saved_val; }); | 73 | * SCOPE_EXIT{ g_foo = saved_val; }; |
| 42 | * | 74 | * |
| 43 | * if (Bar()) { | 75 | * if (Bar()) { |
| 44 | * return 0; | 76 | * return 0; |
| @@ -47,10 +79,4 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { | |||
| 47 | * } | 79 | * } |
| 48 | * \endcode | 80 | * \endcode |
| 49 | */ | 81 | */ |
| 50 | #define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body) | 82 | #define SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE_) = SCOPE_GUARD |
| 51 | |||
| 52 | /** | ||
| 53 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be | ||
| 54 | * used when the caller might want to cancel the ScopeExit. | ||
| 55 | */ | ||
| 56 | #define SCOPE_GUARD(body) detail::ScopeExit([&]() body) | ||
diff --git a/src/common/settings_input.h b/src/common/settings_input.h index 53a95ef8f..a99bb0892 100644 --- a/src/common/settings_input.h +++ b/src/common/settings_input.h | |||
| @@ -395,6 +395,10 @@ struct PlayerInput { | |||
| 395 | u32 button_color_left; | 395 | u32 button_color_left; |
| 396 | u32 button_color_right; | 396 | u32 button_color_right; |
| 397 | std::string profile_name; | 397 | std::string profile_name; |
| 398 | |||
| 399 | // This is meant to tell the Android frontend whether to use a device's built-in vibration | ||
| 400 | // motor or a controller's vibrations. | ||
| 401 | bool use_system_vibrator; | ||
| 398 | }; | 402 | }; |
| 399 | 403 | ||
| 400 | struct TouchscreenInput { | 404 | struct TouchscreenInput { |