diff --git a/.gitmodules b/.gitmodules
index acfb6c7..208c5b3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,6 @@
[submodule "lib/rt64"]
path = lib/rt64
url = https://github.com/rt64/rt64
+[submodule "lib/RecompFrontend"]
+ path = lib/RecompFrontend
+ url = https://github.com/N64Recomp/RecompFrontend.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index cbcc0f4..9ec6b60 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,15 +51,7 @@ endif()
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/rt64 ${CMAKE_BINARY_DIR}/rt64)
-# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF)
-SET(LUNASVG_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
-add_subdirectory(${CMAKE_SOURCE_DIR}/lib/lunasvg)
-# set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
-SET(RMLUI_SVG_PLUGIN ON CACHE BOOL "" FORCE)
-SET(RMLUI_TESTS_ENABLED OFF CACHE BOOL "" FORCE)
-add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RmlUi)
-target_compile_definitions(rmlui_core PRIVATE LUNASVG_BUILD_STATIC)
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime)
@@ -148,85 +140,47 @@ add_custom_command(OUTPUT
add_executable(Starfox64Recompiled)
set (SOURCES
+ ${CMAKE_SOURCE_DIR}/src/main/launcher_animation.cpp
${CMAKE_SOURCE_DIR}/src/main/main.cpp
${CMAKE_SOURCE_DIR}/src/main/support.cpp
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
- ${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp
+ ${CMAKE_SOURCE_DIR}/src/main/theme.cpp
- ${CMAKE_SOURCE_DIR}/src/game/input.cpp
- ${CMAKE_SOURCE_DIR}/src/game/controls.cpp
${CMAKE_SOURCE_DIR}/src/game/config.cpp
- ${CMAKE_SOURCE_DIR}/src/game/scene_table.cpp
- ${CMAKE_SOURCE_DIR}/src/game/debug.cpp
- ${CMAKE_SOURCE_DIR}/src/game/quicksaving.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_api.cpp
- ${CMAKE_SOURCE_DIR}/src/game/recomp_actor_api.cpp
${CMAKE_SOURCE_DIR}/src/game/recomp_data_api.cpp
${CMAKE_SOURCE_DIR}/src/game/rom_decompression.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_renderer.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_state.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_launcher.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_config.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_prompt.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_installer.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api_events.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api_images.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_utils.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_clickable.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_container.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_element.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_image.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_label.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_radio.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_slider.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_span.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp
-
${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp
# ${CMAKE_SOURCE_DIR}/rsp/njpgdspMain.cpp
-
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
)
-if (APPLE)
- list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/src/main/support_apple.mm)
-endif()
-
target_include_directories(Starfox64Recompiled PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/N64Recomp/include
- ${CMAKE_SOURCE_DIR}/lib/concurrentqueue
- ${CMAKE_SOURCE_DIR}/lib/GamepadMotionHelpers
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Include
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends
+ ${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/thirdparty/sse2neon
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/hlslpp/include
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/dxc/inc
${CMAKE_SOURCE_DIR}/lib/rt64/src
${CMAKE_SOURCE_DIR}/lib/rt64/src/rhi
${CMAKE_SOURCE_DIR}/lib/rt64/src/render
- ${CMAKE_SOURCE_DIR}/lib/freetype-windows-binaries/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompinput/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompui/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompui/src
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/nativefiledialog-extended/src/include
${CMAKE_SOURCE_DIR}/lib/SlotMap
- ${CMAKE_BINARY_DIR}/shaders
${CMAKE_CURRENT_BINARY_DIR}
)
+# Generate icon_bytes.c from the app icon PNG.
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
+ COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
+ DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png
+)
+target_sources(Starfox64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c)
+
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
target_compile_options(Starfox64Recompiled PRIVATE
-march=nehalem
@@ -313,15 +267,9 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
find_package(SDL2 REQUIRED)
find_package(X11 REQUIRED)
+ add_compile_definitions("PLUME_SDL_VULKAN_ENABLED")
add_compile_definitions("RT64_SDL_WINDOW_VULKAN")
- # Generate icon_bytes.c from the app icon PNG.
- add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
- COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
- DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png
- )
- target_sources(Starfox64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c)
-
message(STATUS "SDL2_FOUND = ${SDL2_FOUND}")
message(STATUS "SDL2_INCLUDE_DIRS = ${SDL2_INCLUDE_DIRS}")
@@ -351,18 +299,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(Starfox64Recompiled PRIVATE "-latomic -static-libstdc++" ${CMAKE_DL_LIBS} Threads::Threads)
endif()
-target_link_libraries(Starfox64Recompiled PRIVATE
- PatchesLib
- RecompiledFuncs
- librecomp
- ultramodern
- rt64
- RmlUi::Core
- RmlUi::Debugger
- nfd
- lunasvg
-)
-
# TODO fix the rt64 CMake script so that this doesn't need to be duplicated here
# For DXC
set (DXC_COMMON_OPTS "-I${PROJECT_SOURCE_DIR}/src")
@@ -395,8 +331,21 @@ else()
endif()
endif()
-build_vertex_shader(Starfox64Recompiled "shaders/InterfaceVS.hlsl" "shaders/InterfaceVS.hlsl")
-build_pixel_shader(Starfox64Recompiled "shaders/InterfacePS.hlsl" "shaders/InterfacePS.hlsl")
+set(RECOMP_FRONTEND_N64MODERNRUNTIME_PATH ${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime)
+set(RECOMP_FRONTEND_RT64_PATH ${CMAKE_SOURCE_DIR}/lib/rt64)
+
+add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RecompFrontend)
+
+target_link_libraries(Starfox64Recompiled PRIVATE
+ PatchesLib
+ RecompiledFuncs
+ recompui
+ recompinput
+ librecomp
+ ultramodern
+ rt64
+ nfd
+)
# Embed all .nrm files in the "mods" directory
file(GLOB NRM_FILES "${CMAKE_SOURCE_DIR}/mods/*.nrm")
diff --git a/assets/config_menu.rml b/assets/config_menu.rml
deleted file mode 100644
index 3865510..0000000
--- a/assets/config_menu.rml
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
- Inventory
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- General
-
-
-
-
-
-
- Controls
-
-
-
-
-
-
- Graphics
-
-
-
-
-
-
- Sound
-
-
-
-
-
-
- Mods
-
-
-
-
-
-
- Debug
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/config_menu/controls.rml b/assets/config_menu/controls.rml
deleted file mode 100644
index d947ae8..0000000
--- a/assets/config_menu/controls.rml
+++ /dev/null
@@ -1,360 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/config_menu/debug.rml b/assets/config_menu/debug.rml
deleted file mode 100644
index 22cb26e..0000000
--- a/assets/config_menu/debug.rml
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/config_menu/general.rml b/assets/config_menu/general.rml
deleted file mode 100644
index 9e3f934..0000000
--- a/assets/config_menu/general.rml
+++ /dev/null
@@ -1,215 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/graphics.rml b/assets/config_menu/graphics.rml
deleted file mode 100644
index a11de72..0000000
--- a/assets/config_menu/graphics.rml
+++ /dev/null
@@ -1,325 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/mods.rml b/assets/config_menu/mods.rml
deleted file mode 100644
index debab39..0000000
--- a/assets/config_menu/mods.rml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/sound.rml b/assets/config_menu/sound.rml
deleted file mode 100644
index bbbed06..0000000
--- a/assets/config_menu/sound.rml
+++ /dev/null
@@ -1,97 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/config_sub_menu.rml b/assets/config_sub_menu.rml
deleted file mode 100644
index 0022f1e..0000000
--- a/assets/config_sub_menu.rml
+++ /dev/null
@@ -1,70 +0,0 @@
-
-
-
-
- Inventory
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/icons/Caret.svg b/assets/icons/Caret.svg
new file mode 100644
index 0000000..9266f13
--- /dev/null
+++ b/assets/icons/Caret.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/Cont.svg b/assets/icons/Cont.svg
new file mode 100644
index 0000000..5959613
--- /dev/null
+++ b/assets/icons/Cont.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/Keyboard.svg b/assets/icons/Keyboard.svg
new file mode 100644
index 0000000..880ceb0
--- /dev/null
+++ b/assets/icons/Keyboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/PlusKeyboard.svg b/assets/icons/PlusKeyboard.svg
new file mode 100644
index 0000000..158c6a0
--- /dev/null
+++ b/assets/icons/PlusKeyboard.svg
@@ -0,0 +1,17 @@
+
diff --git a/assets/icons/Port.svg b/assets/icons/Port.svg
new file mode 100644
index 0000000..224a4d8
--- /dev/null
+++ b/assets/icons/Port.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/icons/Question.svg b/assets/icons/Question.svg
new file mode 100644
index 0000000..9fdcaf3
--- /dev/null
+++ b/assets/icons/Question.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/icons/RecordSpinner.svg b/assets/icons/RecordSpinner.svg
new file mode 100644
index 0000000..fb9accd
--- /dev/null
+++ b/assets/icons/RecordSpinner.svg
@@ -0,0 +1,16 @@
+
diff --git a/assets/launcher.rml b/assets/launcher.rml
deleted file mode 100644
index 8f8f7e4..0000000
--- a/assets/launcher.rml
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
- Launcher
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/recomp.rcss b/assets/recomp.rcss
index 551e60d..1ebcae5 100644
--- a/assets/recomp.rcss
+++ b/assets/recomp.rcss
@@ -1,2512 +1,5 @@
-/* stylelint-disable color-no-hex, color-hex-length */
-h1 {
- font-size: 68dp;
- letter-spacing: 4.76dp;
- line-height: 68dp;
- font-style: normal;
- font-weight: 700;
-}
-
-h2 {
- font-size: 52dp;
- letter-spacing: 3.64dp;
- line-height: 52dp;
- font-style: normal;
- font-weight: 700;
-}
-
-h3, .tab {
- font-size: 36dp;
- letter-spacing: 2.52dp;
- line-height: 36dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-lg, .menu-list-item__label, .button--large {
- font-size: 36dp;
- letter-spacing: 3.96dp;
- line-height: 36dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-md, .config-debug-option__label, .button, .config-option__title, .config-option--hz .config-option__title, .config-group__title, .control-option__label {
- font-size: 28dp;
- letter-spacing: 3.08dp;
- line-height: 28dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-sm, .config-debug__select-wrapper .config-debug__select-label, .subtitle-title__disclaimer, .config-option__range-label, .config-option-range__label, .config-option__radio-tabs .config-option__tab-label,
-.config-option__list .config-option__tab-label, .centered-page__controls > label {
- font-size: 20dp;
- letter-spacing: 2.8dp;
- line-height: 20dp;
- font-style: normal;
- font-weight: 700;
- text-transform: uppercase;
-}
-
-.config-option__details {
- font-size: 18dp;
- letter-spacing: 2.52dp;
- line-height: 18dp;
- font-style: normal;
- font-weight: 400;
-}
-
-body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p {
- font-size: 20dp;
- letter-spacing: 0dp;
- line-height: 20dp;
- font-style: normal;
- font-weight: 400;
-}
-
-.toggle__icon {
- font-family: promptfont;
- font-size: 56dp;
- font-style: normal;
- font-weight: 400;
- line-height: 56dp;
-}
-
-.prompt-font {
- font-family: promptfont;
- font-size: 40dp;
- font-style: normal;
- font-weight: 400;
- line-height: 40dp;
-}
-
-.prompt-font-sm, .input-viz__mappings div {
- font-family: promptfont;
- font-size: 32dp;
- font-style: normal;
- font-weight: 400;
- line-height: 32dp;
-}
-
/*
-@include trans-colors;
+ In order for rml to parse the base style sheet and combine with this one, any style needs to at least be present.
+ If you add styles to this file later, you can clear the current contents of this file.
*/
-/*
-@include trans-colors-opa;
-*/
-/*
-@include trans-colors-svg;
-*/
-/*
-@include trans-colors-border;
-*/
-.nav-vert, .nav-dir, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- nav-up: auto;
- nav-down: auto;
-}
-
-.nav-horiz, .nav-dir, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- nav-right: auto;
- nav-left: auto;
-}
-
-.nav-foc, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- focus: auto;
- tab-index: auto;
-}
-
-/*
-@include set-color(COLOR);
-*/
-/* stylelint-disable color-no-hex, color-hex-length */
-h1 {
- font-size: 68dp;
- letter-spacing: 4.76dp;
- line-height: 68dp;
- font-style: normal;
- font-weight: 700;
-}
-
-h2 {
- font-size: 52dp;
- letter-spacing: 3.64dp;
- line-height: 52dp;
- font-style: normal;
- font-weight: 700;
-}
-
-h3, .tab {
- font-size: 36dp;
- letter-spacing: 2.52dp;
- line-height: 36dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-lg, .menu-list-item__label, .button--large {
- font-size: 36dp;
- letter-spacing: 3.96dp;
- line-height: 36dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-md, .config-debug-option__label, .button, .config-option__title, .config-option--hz .config-option__title, .config-group__title, .control-option__label {
- font-size: 28dp;
- letter-spacing: 3.08dp;
- line-height: 28dp;
- font-style: normal;
- font-weight: 700;
-}
-
-.label-sm, .config-debug__select-wrapper .config-debug__select-label, .subtitle-title__disclaimer, .config-option__range-label, .config-option-range__label, .config-option__radio-tabs .config-option__tab-label,
-.config-option__list .config-option__tab-label, .centered-page__controls > label {
- font-size: 20dp;
- letter-spacing: 2.8dp;
- line-height: 20dp;
- font-style: normal;
- font-weight: 700;
- text-transform: uppercase;
-}
-
-.config-option__details {
- font-size: 18dp;
- letter-spacing: 2.52dp;
- line-height: 18dp;
- font-style: normal;
- font-weight: 400;
-}
-
-body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p {
- font-size: 20dp;
- letter-spacing: 0dp;
- line-height: 20dp;
- font-style: normal;
- font-weight: 400;
-}
-
-.toggle__icon {
- font-family: promptfont;
- font-size: 56dp;
- font-style: normal;
- font-weight: 400;
- line-height: 56dp;
-}
-
-.prompt-font {
- font-family: promptfont;
- font-size: 40dp;
- font-style: normal;
- font-weight: 400;
- line-height: 40dp;
-}
-
-.prompt-font-sm, .input-viz__mappings div {
- font-family: promptfont;
- font-size: 32dp;
- font-style: normal;
- font-weight: 400;
- line-height: 32dp;
-}
-
-/*
-@include trans-colors;
-*/
-/*
-@include trans-colors-opa;
-*/
-/*
-@include trans-colors-svg;
-*/
-/*
-@include trans-colors-border;
-*/
-.nav-vert, .nav-dir, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- nav-up: auto;
- nav-down: auto;
-}
-
-.nav-horiz, .nav-dir, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- nav-right: auto;
- nav-left: auto;
-}
-
-.nav-foc, .nav-all, .config-debug__select-wrapper select selectbox option, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .toggle, .subtitle-title:not(:disabled, [disabled]), .menu-list-item:not(:disabled, [disabled]), .icon-button:not([disabled]), .button:not([disabled]), .button, .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config-option__radio-tabs input.radio,
-.config-option__list input.radio, .config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox, .tab, .control-option__binding:not([disabled]) {
- focus: auto;
- tab-index: auto;
-}
-
-/*
-@include set-color(COLOR);
-*/
-/* stylelint-disable color-no-hex */
-/* stylelint-disable selector-max-id */
-* {
- box-sizing: border-box;
-}
-
-hr {
- display: block;
- padding: 1.5dp;
- background: #08070D;
-}
-
-body {
- color: #fff;
- font-family: "latolatin";
- font-size: 20dp;
- font-style: normal;
- font-weight: normal;
-}
-
-/* div {
- focus:none;
- tab-index:none;
-} */
-div#window {
- position: relative;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- border-color: rgba(255, 255, 255, 0.2);
- background-color: #121018;
-}
-
-div#content {
- z-index: 2;
- width: auto;
- height: 100%;
- overflow: hidden auto;
- text-align: center;
-}
-
-p {
- text-align: left;
-}
-
-input.submit {
- margin-left: 0;
-}
-
-input.text,
-input.password {
- box-sizing: border-box;
- height: 31dp;
- padding: 11dp 10dp 0;
- text-align: left;
- cursor: text;
-}
-
-textarea {
- padding: 14dp 12dp 10dp;
- text-align: left;
- cursor: text;
-}
-
-input.text,
-input.password,
-select,
-textarea {
- /* color: #333; */
- /* font-size: 13dp */
- height: auto;
-}
-
-table input.text {
- box-sizing: border-box;
- width: 100%;
- height: auto;
- /* height: 18dp; */
- margin: 0;
- border-width: 1.1dp;
- border-color: #000;
- background-color: #fff;
- font-size: 15dp;
- /* padding: 0 5dp; */
- line-height: 1;
- decorator: none;
- /* vertical-align: center; */
-}
-
-input.radio {
- flex: 0;
- width: 0dp;
- nav-up: auto;
- nav-right: auto;
- nav-down: auto;
- nav-left: auto;
- tab-index: auto;
- focus: auto;
-}
-
-input.checkbox {
- width: 20dp;
- height: 20dp;
- nav-up: auto;
- nav-right: auto;
- nav-down: auto;
- nav-left: auto;
- tab-index: auto;
- focus: auto;
-}
-
-scrollbarvertical, scrollbarhorizontal {
- margin: 0;
- border: 0;
-}
-scrollbarvertical slidertrack, scrollbarhorizontal slidertrack {
- background: #DABAF7;
- opacity: 0.05;
-}
-scrollbarvertical sliderbar, scrollbarhorizontal sliderbar {
- border-radius: 5dp;
- background: #DABAF7;
- opacity: 0.1;
-}
-scrollbarvertical sliderbar:hover:not(:active), scrollbarhorizontal sliderbar:hover:not(:active) {
- opacity: 0.2;
-}
-scrollbarvertical sliderbar:active, scrollbarhorizontal sliderbar:active {
- opacity: 0.3;
-}
-scrollbarvertical sliderarrowdec, scrollbarvertical sliderarrowinc, scrollbarhorizontal sliderarrowdec, scrollbarhorizontal sliderarrowinc {
- width: 0;
- height: 0;
-}
-
-scrollbarvertical {
- width: 12dp;
-}
-scrollbarvertical slidertrack {
- width: 12dp;
-}
-scrollbarvertical sliderbar {
- width: 12dp;
-}
-
-scrollbarhorizontal {
- height: 12dp;
-}
-scrollbarhorizontal slidertrack {
- height: 12dp;
-}
-scrollbarhorizontal sliderbar {
- height: 12dp;
-}
-
-.centered-page {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- padding: 64dp;
- background-color: rgba(255, 255, 255, 0.1);
-}
-
-.centered-page__modal {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: 1692.4444444444dp;
- height: 100%;
- margin: auto;
- border-width: 1.1dp;
- border-radius: 16dp;
- border-color: rgba(255, 255, 255, 0.2);
- background: rgba(8, 7, 13, 0.9);
-}
-.centered-page__modal > .tabs {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: 1692.4444444444dp;
- height: 100%;
- margin: auto;
-}
-.centered-page__modal panels {
- flex: 1 1 100%;
-}
-
-.centered-page__controls {
- display: flex;
- position: absolute;
- bottom: 24dp;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- width: 100%;
- max-width: 1692.4444444444dp;
- height: auto;
- margin: 0 auto;
-}
-.centered-page__controls > label {
- display: inline-block;
- align-items: center;
- justify-content: space-between;
- width: auto;
- height: 24dp;
-}
-.centered-page__controls > label:not(:last-child) {
- margin-right: 40dp;
-}
-.centered-page__controls > label > span:first-child {
- margin-right: 4dp;
-}
-
-.control-option {
- color: #CCCCCC;
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: auto;
- padding: 4dp 16dp 4dp 20dp;
- border-radius: 8dp;
- background-color: rgba(0, 0, 0, 0);
-}
-.control-option svg {
- image-color: #CCCCCC;
-}
-.control-option svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.control-option:focus-visible:not(:disabled, [disabled]), .control-option:hover:not(:disabled, [disabled]) {
- color: #F2F2F2;
- background-color: rgba(190, 184, 219, 0.1);
-}
-.control-option:focus-visible:not(:disabled, [disabled]) svg, .control-option:hover:not(:disabled, [disabled]) svg {
- image-color: #F2F2F2;
-}
-.control-option:disabled, .control-option[disabled] {
- opacity: 0.5;
-}
-[cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] {
- border-color: #F86039;
-}
-[cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] .control-option__binding-icon {
- opacity: 0;
-}
-[cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] .control-option__binding-recording {
- opacity: 1;
-}
-[cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] {
- border-color: #F86039;
-}
-[cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] .control-option__binding-icon {
- opacity: 0;
-}
-[cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] .control-option__binding-recording {
- opacity: 1;
-}
-.control-option .icon-button {
- flex: 1 1 auto;
-}
-
-.control-option__label {
- flex: 2 1 300dp;
- height: auto;
- white-space: nowrap;
-}
-
-.control-option__bindings {
- display: flex;
- position: relative;
- flex: 2 1 400dp;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: 56dp;
- padding: 0 12dp 0 4dp;
-}
-
-.control-option__binding {
- color: #CCCCCC;
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out;
- display: flex;
- position: relative;
- flex: 1 1 100%;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: 56dp;
- margin: 0 4dp;
- padding: 8dp;
- border-width: 1.1dp;
- border-radius: 8dp;
- border-color: rgba(190, 184, 219, 0.1);
- background-color: rgba(190, 184, 219, 0.1);
-}
-.control-option__binding svg {
- image-color: #CCCCCC;
-}
-.control-option__binding svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.control-option__binding:focus, .control-option__binding:hover {
- color: #F2F2F2;
- border-color: #F2F2F2;
- background-color: rgba(255, 255, 255, 0.1);
-}
-.control-option__binding:focus svg, .control-option__binding:hover svg {
- image-color: #F2F2F2;
-}
-.control-option__binding:active {
- color: rgb(244.6, 244.6, 244.6);
-}
-.control-option__binding:active svg {
- image-color: rgb(244.6, 244.6, 244.6);
-}
-.control-option__binding:disabled, .control-option__binding[disabled] {
- color: #CCCCCC;
- opacity: 0.5;
-}
-.control-option__binding:disabled svg, .control-option__binding[disabled] svg {
- image-color: #CCCCCC;
-}
-.control-option__binding:not([disabled]) {
- cursor: pointer;
-}
-
-.control-option__binding-icon {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- opacity: 1;
-}
-
-@keyframes control-option__binding-recording-scale {
- 0% {
- transform: scale(1);
- }
- 50% {
- transform: scale(0.85);
- }
- 100% {
- transform: scale(1);
- }
-}
-.control-option__binding-recording {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
- opacity: 0;
-}
-.control-option__binding-recording .control-option__binding-circle {
- width: 24dp;
- height: 24dp;
- animation: 1.5s sine-in-out infinite control-option__binding-recording-scale;
- border-radius: 24dp;
- background-color: #F86039;
-}
-.control-option__binding-recording .control-option__binding-edge {
- position: absolute;
- top: 50%;
- left: 50%;
- width: 36dp;
- height: 36dp;
- transform: translate(-50%, -50%);
-}
-.control-option__binding-recording .control-option__binding-edge > svg.control-option__binding-edge-svg {
- width: 36dp;
- height: 36dp;
- image-color: #F86039;
-}
-
-/*
- Example:
-
- Graphics
-
-
-*/
-.tabs tabs {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
-}
-
-.tab {
- display: block;
- position: relative;
- margin: 0;
- padding: 20dp 24dp;
- opacity: 0.9;
- background-color: rgba(0, 0, 0, 0);
- color: rgba(255, 255, 255, 0.6);
-}
-.tab:selected {
- color: #F2F2F2;
-}
-.tab:selected .tab__indicator {
- background-color: rgba(255, 255, 255, 0.6);
-}
-.tab:selected:hover {
- cursor: default;
-}
-.rmlui-window:not([mouse-active]) .tab:focus {
- transition: none;
- animation: blue-pulse 0.75s infinite;
-}
-.rmlui-window:not([mouse-active]) .tab:focus:selected .tab__indicator {
- animation: blue-pulse-background 0.75s infinite;
-}
-.tab:focus, .tab:hover {
- opacity: 1;
- color: #F2F2F2;
- cursor: pointer;
-}
-
-.tab__indicator {
- position: absolute;
- right: 0;
- bottom: 2dp;
- left: 0;
- height: 2dp;
- background-color: rgba(0, 0, 0, 0);
-}
-
-.config__icon-buttons {
- display: flex;
- position: absolute;
- top: 8dp;
- right: 0dp;
- flex-direction: row;
- align-items: center;
- justify-content: flex-end;
- width: auto;
-}
-.config__icon-buttons .icon-button {
- margin: 0 8dp;
-}
-
-.config__form {
- border-top-width: 1.1dp;
- border-top-color: rgba(255, 255, 255, 0.1);
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- border-bottom-right-radius: 16dp;
- border-bottom-left-radius: 16dp;
-}
-
-.config__wrapper {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: 16dp;
- border-radius: 0dp;
- border-bottom-right-radius: 16dp;
- border-bottom-left-radius: 16dp;
- background-color: rgba(0, 0, 0, 0.35);
- text-align: left;
-}
-.config__wrapper p {
- padding: 16dp;
- line-height: 28dp;
- white-space: pre-line;
-}
-.config__wrapper p b {
- color: #B97DF2;
-}
-.config__wrapper p i {
- color: #E9CD35;
- font-style: normal;
-}
-
-.config__hz-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- width: 100%;
- height: 100%;
- border-radius: 0dp;
- text-align: left;
-}
-
-.config__header, .config__footer {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- background-color: rgba(0, 0, 0, 0.35);
-}
-
-.config__header {
- border-bottom-width: 1.1dp;
- border-bottom-color: rgba(255, 255, 255, 0.1);
- padding: 12dp 20dp;
-}
-
-.config__footer {
- border-top-width: 1.1dp;
- border-top-color: rgba(255, 255, 255, 0.1);
- padding: 20dp 20dp;
- border-bottom-right-radius: 16dp;
- border-bottom-left-radius: 16dp;
-}
-
-.config__header-left {
- display: flex;
- flex: 1 1 auto;
- flex-direction: row;
-}
-.config__header-left > :not(:first-child) {
- margin-left: 8dp;
-}
-
-.config__row {
- display: flex;
- flex-direction: row;
-}
-
-.config-group {
- position: relative;
-}
-.config-group--scrollable {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: 0 0 0 16dp;
-}
-.config-group--scrollable .config-group__wrapper {
- max-height: 100%;
- overflow-y: auto;
-}
-.config-group__title {
- color: #B97DF2;
-}
-.config-group__title--hidden {
- display: none;
-}
-.config-group__wrapper {
- padding: 16dp 0;
-}
-
-.config-option {
- display: flex;
- flex: 1;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
- margin: 16dp 0dp 24dp;
-}
-.config-option--hz {
- flex-direction: row-reverse;
- align-items: center;
- margin-top: 4dp;
- margin-bottom: 4dp;
-}
-.config-option--hz .config-option__title {
- flex: 1 1 100%;
-}
-.config-option--hz .config-option__list {
- flex: 1 1 auto;
- width: auto;
-}
-.config-option--hz:first-child {
- margin-top: 0;
-}
-.config-option--hz:last-child {
- margin-bottom: 0;
-}
-
-.config-option__title {
- padding: 0 12dp;
-}
-
-.config-option__radio-tabs,
-.config-option__list {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: 0;
-}
-.config-option__radio-tabs input:first-of-type,
-.config-option__list input:first-of-type {
- nav-left: none;
-}
-.config-option__radio-tabs input:last-of-type,
-.config-option__list input:last-of-type {
- nav-right: none;
-}
-.config-option__radio-tabs .config-option__tab-label,
-.config-option__list .config-option__tab-label {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- display: block;
- position: relative;
- height: auto;
- margin: 4dp 12dp 0;
- padding: 8dp 0;
- color: rgba(255, 255, 255, 0.6);
- tab-index: none;
-}
-.config-option__radio-tabs .config-option__tab-label:hover,
-.config-option__list .config-option__tab-label:hover {
- color: #F2F2F2;
- cursor: pointer;
-}
-.config-option__radio-tabs .config-option__checkbox-wrapper,
-.config-option__list .config-option__checkbox-wrapper {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- width: 32dp;
- height: 32dp;
- margin: 4dp 12dp 0;
- border-radius: 8dp;
- opacity: 0.5;
- background-color: rgba(190, 184, 219, 0.1);
- cursor: pointer;
-}
-.config-option__radio-tabs .config-option__checkbox-wrapper:hover,
-.config-option__list .config-option__checkbox-wrapper:hover {
- opacity: 1;
-}
-.config-option__radio-tabs .config-option__checkbox-wrapper[checked],
-.config-option__list .config-option__checkbox-wrapper[checked] {
- background-color: #3333FF;
-}
-.config-option__radio-tabs .config-option__checkbox,
-.config-option__list .config-option__checkbox {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- visibility: visible;
- width: 0;
- height: 0;
-}
-.config-option__radio-tabs input.radio,
-.config-option__list input.radio {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- visibility: visible;
- width: 0;
- height: 0;
-}
-.config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label,
-.config-option__list input.radio:not(:disabled):checked + .config-option__tab-label {
- border-bottom: 1dp;
- border-color: #F2F2F2;
- color: #F2F2F2;
-}
-.config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label:hover,
-.config-option__list input.radio:not(:disabled):checked + .config-option__tab-label:hover {
- cursor: default;
-}
-.rmlui-window:not([mouse-active]) .config-option__radio-tabs input.radio:not(:disabled):focus + .config-option__tab-label,
-.rmlui-window:not([mouse-active]) .config-option__list input.radio:not(:disabled):focus + .config-option__tab-label {
- transition: none;
- animation: blue-pulse 0.75s infinite;
- border-color: #17D6E8;
- color: #17D6E8;
-}
-.config-option__radio-tabs input.radio:not(:disabled):focus + .config-option__tab-label, .config-option__radio-tabs input.radio:not(:disabled):hover + .config-option__tab-label,
-.config-option__list input.radio:not(:disabled):focus + .config-option__tab-label,
-.config-option__list input.radio:not(:disabled):hover + .config-option__tab-label {
- color: #F2F2F2;
-}
-.config-option__radio-tabs input.radio:disabled + .config-option__tab-label,
-.config-option__list input.radio:disabled + .config-option__tab-label {
- opacity: 0.5;
-}
-.config-option__radio-tabs input.radio:disabled + .config-option__tab-label:hover,
-.config-option__list input.radio:disabled + .config-option__tab-label:hover {
- cursor: default;
-}
-.config-option__radio-tabs input.range slidertrack,
-.config-option__list input.range slidertrack {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- height: 2dp;
- margin-top: 8dp;
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-option__radio-tabs input.range sliderbar,
-.config-option__list input.range sliderbar {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- width: 16dp;
- height: 16dp;
- margin-top: 1dp;
- margin-right: -8dp;
- margin-left: -8dp;
- transition: background-color 0.05s linear-in-out;
- border-radius: 8dp;
- background-color: #CCCCCC;
-}
-.rmlui-window:not([mouse-active]) .config-option__radio-tabs input.range sliderbar:focus,
-.rmlui-window:not([mouse-active]) .config-option__list input.range sliderbar:focus {
- border-width: 1.1dp;
- border-color: #3333FF;
- animation: blue-pulse-background 0.75s infinite;
-}
-.config-option__radio-tabs input.range sliderbar:hover,
-.config-option__list input.range sliderbar:hover {
- background-color: #F2F2F2;
- cursor: pointer;
-}
-.config-option__radio-tabs input.range sliderbar:active,
-.config-option__radio-tabs input.range slidertrack:active + sliderbar,
-.config-option__list input.range sliderbar:active,
-.config-option__list input.range slidertrack:active + sliderbar {
- background-color: #17D6E8;
-}
-.config-option__radio-tabs input.range sliderarrowdec,
-.config-option__radio-tabs input.range sliderarrowinc,
-.config-option__list input.range sliderarrowdec,
-.config-option__list input.range sliderarrowinc {
- display: none;
-}
-
-.config-option__details {
- height: 18dp;
- margin: 14dp 12dp 0;
- color: #B97DF2;
-}
-
-.config-option-color {
- width: 100%;
- max-width: 360dp;
- height: auto;
- margin-top: 4dp;
- margin-left: 12dp;
- padding: 0;
-}
-.config-option-color__preview-wrapper {
- display: flex;
- flex-direction: row;
- width: 100%;
- height: 72dp;
-}
-.config-option-color__preview-block {
- display: block;
- width: 88dp;
- height: 100%;
- border-width: 1.1dp;
- border-radius: 16dp;
- border-color: rgba(255, 255, 255, 0.2);
-}
-.config-option-color__hsv-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- width: auto;
- height: auto;
- padding-left: 8dp;
-}
-.config-option-color__hsv-wrapper .config-option-range {
- flex: 1 1 auto;
-}
-.config-option-color__hsv-wrapper .config-option-range label {
- min-width: 72dp;
-}
-.config-option-color__hsv-wrapper .config-option-range input {
- flex: 1 1 auto;
-}
-
-.config-option-range {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: 360dp;
- height: auto;
- margin-top: 4dp;
- padding: 0;
-}
-.config-option-range__label {
- display: block;
- width: 56dp;
- margin: 0 12dp;
- margin-right: 16dp;
- padding: 0;
- color: #F2F2F2;
- tab-index: none;
-}
-.config-option-range__range-input {
- flex: 1;
-}
-.config-option-range__range-input slidertrack {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- height: 2dp;
- margin-top: 8dp;
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-option-range__range-input sliderbar {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- width: 16dp;
- height: 16dp;
- margin-top: 1dp;
- margin-right: -8dp;
- margin-left: -8dp;
- transition: background-color 0.05s linear-in-out;
- border-radius: 8dp;
- background-color: #CCCCCC;
-}
-.rmlui-window:not([mouse-active]) .config-option-range__range-input sliderbar:focus {
- border-width: 1.1dp;
- border-color: #3333FF;
- animation: blue-pulse-background 0.75s infinite;
-}
-.config-option-range__range-input sliderbar:hover {
- background-color: #F2F2F2;
- cursor: pointer;
-}
-.config-option-range__range-input sliderbar:active,
-.config-option-range__range-input slidertrack:active + sliderbar {
- background-color: #17D6E8;
-}
-.config-option-range__range-input sliderarrowdec,
-.config-option-range__range-input sliderarrowinc {
- display: none;
-}
-
-.config-option__range-wrapper {
- max-width: 360dp;
- margin-top: 4dp;
-}
-
-.config-option__range-label {
- display: block;
- width: 56dp;
- margin: 0 12dp;
- margin-right: 16dp;
- padding: 0;
- color: #F2F2F2;
- tab-index: none;
-}
-
-.config-option-dropdown, .config-option-textfield {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- width: auto;
- height: auto;
- padding: 8dp 24dp 8dp 12dp;
-}
-.config-option-dropdown__select, .config-option-textfield__select {
- display: block;
- height: 48dp;
- padding: 14dp;
- cursor: pointer;
-}
-.config-option-dropdown__wrapper, .config-option-textfield__wrapper {
- display: flex;
- align-items: center;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: 2dp 0 12dp;
- cursor: text;
-}
-.config-option-dropdown__wrapper input, .config-option-textfield__wrapper input {
- width: 100%;
- height: auto;
- vertical-align: middle;
-}
-.config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out;
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.5);
- position: relative;
- box-sizing: border-box;
- flex: 1 1 100%;
- width: auto;
- border-radius: 12dp;
- background-color: rgba(255, 255, 255, 0.05);
-}
-.config-option-dropdown__select svg, .config-option-dropdown__wrapper svg, .config-option-textfield__select svg, .config-option-textfield__wrapper svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.config-option-dropdown__select:hover, .config-option-dropdown__select:focus, .config-option-dropdown__wrapper:hover, .config-option-dropdown__wrapper:focus, .config-option-textfield__select:hover, .config-option-textfield__select:focus, .config-option-textfield__wrapper:hover, .config-option-textfield__wrapper:focus {
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.8);
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-option-dropdown__select selectvalue, .config-option-dropdown__wrapper selectvalue, .config-option-textfield__select selectvalue, .config-option-textfield__wrapper selectvalue {
- display: inline;
- height: auto;
- margin: auto 0;
-}
-.config-option-dropdown__select selectbox, .config-option-dropdown__wrapper selectbox, .config-option-textfield__select selectbox, .config-option-textfield__wrapper selectbox {
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.2);
- margin-top: 2dp;
- padding: 4dp 0;
- border-radius: 12dp;
- background-color: #191622;
-}
-.config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- padding: 8dp 12dp;
- background-color: rgba(0, 0, 0, 0);
- color: #CCCCCC;
- font-weight: 400;
-}
-.config-option-dropdown__select selectbox option:hover, .config-option-dropdown__select selectbox option:focus, .config-option-dropdown__wrapper selectbox option:hover, .config-option-dropdown__wrapper selectbox option:focus, .config-option-textfield__select selectbox option:hover, .config-option-textfield__select selectbox option:focus, .config-option-textfield__wrapper selectbox option:hover, .config-option-textfield__wrapper selectbox option:focus {
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-option-dropdown__select selectbox option:hover:not(:checked), .config-option-dropdown__wrapper selectbox option:hover:not(:checked), .config-option-textfield__select selectbox option:hover:not(:checked), .config-option-textfield__wrapper selectbox option:hover:not(:checked) {
- cursor: pointer;
-}
-.config-option-dropdown__select selectbox option:checked, .config-option-dropdown__wrapper selectbox option:checked, .config-option-textfield__select selectbox option:checked, .config-option-textfield__wrapper selectbox option:checked {
- background-color: rgba(255, 255, 255, 0.05);
- color: #FFFFFF;
-}
-
-.config-description {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: 16dp;
- border-radius: 0dp;
- border-bottom-right-radius: 16dp;
- border-bottom-left-radius: 16dp;
- background-color: rgba(0, 0, 0, 0.35);
- text-align: left;
-}
-.config-description__contents {
- padding: 16dp;
- line-height: 28dp;
- white-space: pre-line;
-}
-.config-description__contents b {
- color: #B97DF2;
-}
-.config-description__contents i {
- color: #E9CD35;
- font-style: normal;
-}
-
-.input-config {
- padding: 0;
-}
-
-.input-config__horizontal-split {
- display: flex;
- position: relative;
- flex-direction: row;
- height: 100%;
-}
-
-.input-config__mappings {
- display: block;
- flex: 1 1 auto;
- min-width: 640dp;
- height: 100%;
-}
-
-.input-config__mappings-scroll {
- display: block;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.input-config__mappings-wrapper {
- padding: 8dp;
-}
-
-.input-config__visual-wrapper {
- display: block;
- flex: 1 1 100%;
- width: auto;
- max-width: 1040.4444444444dp;
- height: auto;
- max-height: 780.3333333333dp;
- margin: auto 0;
-}
-
-.input-config__visual-aspect {
- position: relative;
- width: 100%;
- margin: auto 0;
- padding-bottom: 75%;
- background-color: rgba(0, 0, 0, 0.35);
-}
-
-.input-config__visual {
- display: flex;
- position: absolute;
- top: 16dp;
- right: 16dp;
- bottom: 16dp;
- left: 16dp;
- flex-direction: column;
- border-radius: 108dp;
- background-color: rgba(255, 255, 255, 0.05);
-}
-
-.input-config__visual-half {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- padding: 6%;
-}
-.input-config__visual-half--bottom {
- align-items: flex-end;
- justify-content: space-between;
-}
-
-.input-config__visual-quarter-left {
- display: flex;
- flex: 1 1 50%;
- align-items: flex-start;
- justify-content: flex-start;
- width: auto;
-}
-
-.input-config__visual-quarter-right {
- display: flex;
- flex: 1 1 100%;
- align-items: flex-start;
- justify-content: flex-end;
-}
-
-.input-config__visual-stick-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
-}
-
-.input-viz {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
-}
-.input-viz > svg:not(.input-viz__dpad-arrow) {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-}
-[cur-input=NONE] .input-viz[visual-input] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=A] {
- opacity: 0.25;
-}
-[cur-input=A] .input-viz[visual-input~=A] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=B] {
- opacity: 0.25;
-}
-[cur-input=B] .input-viz[visual-input~=B] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=Z] {
- opacity: 0.25;
-}
-[cur-input=Z] .input-viz[visual-input~=Z] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=START] {
- opacity: 0.25;
-}
-[cur-input=START] .input-viz[visual-input~=START] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=DPAD_UP] {
- opacity: 0.25;
-}
-[cur-input=DPAD_UP] .input-viz[visual-input~=DPAD_UP] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=DPAD_DOWN] {
- opacity: 0.25;
-}
-[cur-input=DPAD_DOWN] .input-viz[visual-input~=DPAD_DOWN] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=DPAD_LEFT] {
- opacity: 0.25;
-}
-[cur-input=DPAD_LEFT] .input-viz[visual-input~=DPAD_LEFT] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=DPAD_RIGHT] {
- opacity: 0.25;
-}
-[cur-input=DPAD_RIGHT] .input-viz[visual-input~=DPAD_RIGHT] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=L] {
- opacity: 0.25;
-}
-[cur-input=L] .input-viz[visual-input~=L] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=R] {
- opacity: 0.25;
-}
-[cur-input=R] .input-viz[visual-input~=R] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=C_UP] {
- opacity: 0.25;
-}
-[cur-input=C_UP] .input-viz[visual-input~=C_UP] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=C_DOWN] {
- opacity: 0.25;
-}
-[cur-input=C_DOWN] .input-viz[visual-input~=C_DOWN] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=C_LEFT] {
- opacity: 0.25;
-}
-[cur-input=C_LEFT] .input-viz[visual-input~=C_LEFT] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=C_RIGHT] {
- opacity: 0.25;
-}
-[cur-input=C_RIGHT] .input-viz[visual-input~=C_RIGHT] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=X_AXIS_NEG] {
- opacity: 0.25;
-}
-[cur-input=X_AXIS_NEG] .input-viz[visual-input~=X_AXIS_NEG] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=X_AXIS_POS] {
- opacity: 0.25;
-}
-[cur-input=X_AXIS_POS] .input-viz[visual-input~=X_AXIS_POS] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=Y_AXIS_NEG] {
- opacity: 0.25;
-}
-[cur-input=Y_AXIS_NEG] .input-viz[visual-input~=Y_AXIS_NEG] {
- opacity: 1;
-}
-
-.input-viz[visual-input~=Y_AXIS_POS] {
- opacity: 0.25;
-}
-[cur-input=Y_AXIS_POS] .input-viz[visual-input~=Y_AXIS_POS] {
- opacity: 1;
-}
-
-.input-viz__button {
- color: #F2F2F2;
-}
-.input-viz__button svg {
- image-color: #F2F2F2;
-}
-.input-viz__button--sm {
- width: 64dp;
- height: 64dp;
-}
-.input-viz__button--sm > svg {
- width: 64dp;
- height: 64dp;
-}
-.input-viz__button--md {
- width: 76dp;
- height: 76dp;
-}
-.input-viz__button--md > svg {
- width: 76dp;
- height: 76dp;
-}
-.input-viz__button--lg {
- width: 84dp;
- height: 84dp;
-}
-.input-viz__button--lg > svg {
- width: 84dp;
- height: 84dp;
-}
-.input-viz__button--C svg {
- image-color: #E9CD35;
-}
-.input-viz__button--A {
- margin-top: auto;
-}
-.input-viz__button--A svg {
- image-color: #3333FF;
-}
-.input-viz__button--B svg {
- image-color: #45D043;
-}
-.input-viz__button--Start svg {
- image-color: #F86039;
-}
-
-.input-viz__Z {
- width: 136dp;
- height: 136dp;
-}
-.input-viz__Z svg {
- image-color: #E9CD35;
-}
-.input-viz__Z > svg {
- width: 136dp;
- height: 136dp;
-}
-
-.input-viz.input-viz__dpad {
- width: 192dp;
- height: 192dp;
- position: relative;
-}
-.input-viz.input-viz__dpad svg {
- image-color: #F2F2F2;
-}
-.input-viz.input-viz__dpad > svg {
- width: 192dp;
- height: 192dp;
-}
-
-.input-config__visual-stick {
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
- width: 200dp;
- height: 200dp;
- border-radius: 100dp;
- background-color: rgba(255, 255, 255, 0.05);
-}
-
-.input-viz__dpad-split,
-.input-viz__stick-split {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- display: flex;
- width: 100%;
- height: 100%;
-}
-.input-viz__dpad-split--vertical,
-.input-viz__stick-split--vertical {
- flex-direction: column;
- align-items: center;
- justify-content: space-between;
-}
-.input-viz__dpad-split--horizontal,
-.input-viz__stick-split--horizontal {
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-}
-.input-viz__dpad-split > div,
-.input-viz__stick-split > div {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: center;
-}
-
-.input-viz__dpad-split > div {
- width: 64dp;
- height: 64dp;
-}
-
-.input-viz__stick-split > div {
- width: 66.6666666667dp;
- height: 66.6666666667dp;
-}
-
-.input-viz__dpad-arrow {
- position: absolute;
- width: 60dp;
- height: 60dp;
-}
-.input-viz__dpad-arrow--up {
- top: 4dp;
- margin: 0 auto;
-}
-.input-viz__dpad-arrow--down {
- bottom: 4dp;
- margin: 0 auto;
- transform: rotate(180deg);
-}
-.input-viz__dpad-arrow--left {
- left: 4dp;
- margin: auto 0;
- transform: rotate(-90deg);
-}
-.input-viz__dpad-arrow--right {
- right: 4dp;
- margin: auto 0;
- transform: rotate(90deg);
-}
-
-.input-viz__R {
- width: 96dp;
- height: 96dp;
-}
-.input-viz__R svg {
- image-color: #FFFFFF;
-}
-.input-viz__R > svg {
- width: 96dp;
- height: 96dp;
-}
-
-.input-viz__L {
- width: 136dp;
- height: 136dp;
-}
-.input-viz__L svg {
- image-color: #17D6E8;
-}
-.input-viz__L > svg {
- width: 136dp;
- height: 136dp;
-}
-
-.input-config__c-buttons {
- position: relative;
- width: 208dp;
- height: 132dp;
-}
-.input-config__c-buttons-lr, .input-config__c-buttons-du {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-}
-.input-config__c-buttons-lr {
- flex-direction: row;
- align-items: flex-start;
- justify-content: space-between;
-}
-.input-config__c-buttons-du {
- flex-direction: column-reverse;
- align-items: center;
- justify-content: space-between;
-}
-.input-config__c-buttons .input-viz[visual-input=C_UP] {
- margin-top: -32dp;
-}
-
-.input-config__main-buttons {
- display: flex;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: 268dp;
- min-width: 1dp;
- height: 128dp;
- margin-right: 10dp;
-}
-
-.button {
- border-color: rgba(185, 125, 242, 0.8);
- background-color: rgba(185, 125, 242, 0.05);
- color: #CCCCCC;
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- display: block;
- width: auto;
- height: auto;
- padding: 23dp;
- border-width: 1.1dp;
- border-radius: 12dp;
-}
-.button:focus, .button:hover {
- border-color: #B97DF2;
- background-color: rgba(185, 125, 242, 0.3);
- color: #F2F2F2;
-}
-.button:disabled, .button[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button:active {
- background-color: rgba(185, 125, 242, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--primary {
- border-color: rgba(185, 125, 242, 0.8);
- background-color: rgba(185, 125, 242, 0.05);
- color: #CCCCCC;
-}
-.button--primary:focus, .button--primary:hover {
- border-color: #B97DF2;
- background-color: rgba(185, 125, 242, 0.3);
- color: #F2F2F2;
-}
-.button--primary:disabled, .button--primary[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--primary:active {
- background-color: rgba(185, 125, 242, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--secondary {
- border-color: rgba(23, 214, 232, 0.8);
- background-color: rgba(23, 214, 232, 0.05);
- color: #CCCCCC;
-}
-.button--secondary:focus, .button--secondary:hover {
- border-color: #17D6E8;
- background-color: rgba(23, 214, 232, 0.3);
- color: #F2F2F2;
-}
-.button--secondary:disabled, .button--secondary[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--secondary:active {
- background-color: rgba(23, 214, 232, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--tertiary {
- border-color: rgba(242, 242, 242, 0.8);
- background-color: rgba(242, 242, 242, 0.05);
- color: #CCCCCC;
-}
-.button--tertiary:focus, .button--tertiary:hover {
- border-color: #F2F2F2;
- background-color: rgba(242, 242, 242, 0.3);
- color: #F2F2F2;
-}
-.button--tertiary:disabled, .button--tertiary[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--tertiary:active {
- background-color: rgba(242, 242, 242, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--success {
- border-color: rgba(69, 208, 67, 0.8);
- background-color: rgba(69, 208, 67, 0.05);
- color: #CCCCCC;
-}
-.button--success:focus, .button--success:hover {
- border-color: #45D043;
- background-color: rgba(69, 208, 67, 0.3);
- color: #F2F2F2;
-}
-.button--success:disabled, .button--success[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--success:active {
- background-color: rgba(69, 208, 67, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--error {
- border-color: rgba(248, 96, 57, 0.8);
- background-color: rgba(248, 96, 57, 0.05);
- color: #CCCCCC;
-}
-.button--error:focus, .button--error:hover {
- border-color: #F86039;
- background-color: rgba(248, 96, 57, 0.3);
- color: #F2F2F2;
-}
-.button--error:disabled, .button--error[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--error:active {
- background-color: rgba(248, 96, 57, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button--warning {
- border-color: rgba(233, 205, 53, 0.8);
- background-color: rgba(233, 205, 53, 0.05);
- color: #CCCCCC;
-}
-.button--warning:focus, .button--warning:hover {
- border-color: #E9CD35;
- background-color: rgba(233, 205, 53, 0.3);
- color: #F2F2F2;
-}
-.button--warning:disabled, .button--warning[disabled] {
- color: rgba(255, 255, 255, 0.6);
-}
-.button--warning:active {
- background-color: rgba(233, 205, 53, 0.2);
- color: rgb(244.6, 244.6, 244.6);
-}
-.button:not([disabled]) {
- cursor: pointer;
-}
-.button:disabled, .button[disabled] {
- opacity: 0.5;
-}
-.button__label {
- width: auto;
- height: auto;
-}
-
-/*
-
-*/
-.icon-button {
- color: #CCCCCC;
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 53.8dp;
- min-width: 53.8dp;
- max-width: 53.8dp;
- height: 53.8dp;
- min-height: 53.8dp;
- max-height: 53.8dp;
- border-width: 1.1dp;
- border-radius: 26.9dp;
- border-color: rgba(0, 0, 0, 0);
- background-color: rgba(0, 0, 0, 0);
-}
-.icon-button svg {
- image-color: #CCCCCC;
-}
-.icon-button svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.icon-button:focus, .icon-button:hover {
- color: #F2F2F2;
- background-color: rgba(255, 255, 255, 0.2);
-}
-.icon-button:focus svg, .icon-button:hover svg {
- image-color: #F2F2F2;
-}
-.icon-button:active {
- color: rgb(244.6, 244.6, 244.6);
- background-color: rgba(255, 255, 255, 0.1);
-}
-.icon-button:active svg {
- image-color: rgb(244.6, 244.6, 244.6);
-}
-.icon-button:disabled, .icon-button[disabled] {
- color: #CCCCCC;
- opacity: 0.5;
-}
-.icon-button:disabled svg, .icon-button[disabled] svg {
- image-color: #CCCCCC;
-}
-.icon-button:not([disabled]) {
- cursor: pointer;
-}
-.icon-button svg {
- width: 32dp;
- height: 32dp;
-}
-.icon-button--primary {
- border-color: rgba(185, 125, 242, 0.8);
- background-color: rgba(185, 125, 242, 0.05);
-}
-.icon-button--primary:focus, .icon-button--primary:hover {
- border-color: #B97DF2;
- background-color: rgba(185, 125, 242, 0.3);
-}
-.icon-button--primary:active {
- background-color: rgba(185, 125, 242, 0.2);
-}
-.icon-button--secondary {
- border-color: rgba(23, 214, 232, 0.8);
- background-color: rgba(23, 214, 232, 0.05);
-}
-.icon-button--secondary:focus, .icon-button--secondary:hover {
- border-color: #17D6E8;
- background-color: rgba(23, 214, 232, 0.3);
-}
-.icon-button--secondary:active {
- background-color: rgba(23, 214, 232, 0.2);
-}
-.icon-button--tertiary {
- border-color: rgba(242, 242, 242, 0.8);
- background-color: rgba(242, 242, 242, 0.05);
-}
-.icon-button--tertiary:focus, .icon-button--tertiary:hover {
- border-color: #F2F2F2;
- background-color: rgba(242, 242, 242, 0.3);
-}
-.icon-button--tertiary:active {
- background-color: rgba(242, 242, 242, 0.2);
-}
-.icon-button--success {
- border-color: rgba(69, 208, 67, 0.8);
- background-color: rgba(69, 208, 67, 0.05);
-}
-.icon-button--success:focus, .icon-button--success:hover {
- border-color: #45D043;
- background-color: rgba(69, 208, 67, 0.3);
-}
-.icon-button--success:active {
- background-color: rgba(69, 208, 67, 0.2);
-}
-.icon-button--error {
- border-color: rgba(248, 96, 57, 0.8);
- background-color: rgba(248, 96, 57, 0.05);
-}
-.icon-button--error:focus, .icon-button--error:hover {
- border-color: #F86039;
- background-color: rgba(248, 96, 57, 0.3);
-}
-.icon-button--error:active {
- background-color: rgba(248, 96, 57, 0.2);
-}
-.icon-button--warning {
- border-color: rgba(233, 205, 53, 0.8);
- background-color: rgba(233, 205, 53, 0.05);
-}
-.icon-button--warning:focus, .icon-button--warning:hover {
- border-color: #E9CD35;
- background-color: rgba(233, 205, 53, 0.3);
-}
-.icon-button--warning:active {
- background-color: rgba(233, 205, 53, 0.2);
-}
-
-.launcher {
- display: block;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- background-color: #08070D;
-}
-
-.launcher__vertical-split {
- display: flex;
- position: absolute;
- top: 0;
- right: 50%;
- bottom: 0;
- left: 0;
- flex-direction: column;
- align-items: flex-start;
- justify-content: space-between;
-}
-.launcher__vertical-split--right {
- right: 0;
- left: 50%;
- align-items: flex-end;
-}
-
-@keyframes slide-mm-bg-over {
- 0% {
- transform: translateX(100dp);
- }
- 100% {
- transform: translateX(0dp);
- }
-}
-.launcher__background-wrapper {
- display: flex;
- position: absolute;
- top: -55vw;
- right: -100%;
- bottom: -50vw;
- left: -70vw;
- align-items: center;
- justify-content: flex-start;
- transform: translateX(0dp);
- animation: 25s cubic-out 1 slide-mm-bg-over;
-}
-
-@keyframes fade-mm-in {
- 0% {
- opacity: 0;
- }
- 100% {
- opacity: 0.1;
- }
-}
-.launcher__background-mm {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- width: auto;
- height: 100%;
- animation: 2.5s cubic-in-out 1 fade-mm-in;
- opacity: 0.15;
-}
-
-.launcher__title-quadrant {
- flex: 1 1 auto;
- width: auto;
- height: auto;
- padding-top: 96dp;
- padding-left: 96dp;
-}
-.launcher__title-quadrant--right {
- padding-right: 96dp;
- padding-left: 0;
-}
-
-.launcher__content-quadrant {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-end;
- width: 100%;
- height: auto;
- padding: 32dp;
-}
-
-/*
- Example layout:
-
- - Variants:
- .menu-list-item--right (align to right side)
- - Optional:
- -
Coming Soon™
-
-*/
-.menu-list-item {
- color: #CCCCCC;
- display: flex;
- flex-direction: row;
- align-items: center;
- width: 100%;
- height: auto;
- padding: 16dp;
- border-radius: 8dp;
- background-color: rgba(0, 0, 0, 0);
- cursor: pointer;
-}
-.menu-list-item svg {
- image-color: #CCCCCC;
-}
-.menu-list-item--right {
- flex-direction: row-reverse;
- align-content: flex-end;
-}
-.menu-list-item--right .menu-list-item__bullet {
- margin-left: 12dp;
- opacity: 1;
-}
-.menu-list-item--right.menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item--right.menu-list-item:hover:not(:disabled, [disabled]) {
- decorator: horizontal-gradient(#7A2AC600 #DABAF714);
-}
-.menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item:hover:not(:disabled, [disabled]) {
- color: #B97DF2;
- decorator: horizontal-gradient(#7A2AC614 #DABAF700);
-}
-.menu-list-item:focus:not(:disabled, [disabled]) svg, .menu-list-item:hover:not(:disabled, [disabled]) svg {
- image-color: #B97DF2;
-}
-.menu-list-item:focus:not(:disabled, [disabled]) .menu-list-item__bullet, .menu-list-item:hover:not(:disabled, [disabled]) .menu-list-item__bullet {
- opacity: 1;
-}
-.menu-list-item:disabled, .menu-list-item[disabled] {
- opacity: 0.5;
- tab-index: none;
- cursor: default;
-}
-
-.menu-list-item__bullet {
- margin-right: 12dp;
- opacity: 0;
-}
-
-/*
- Example layout:
-
-
- - Variants:
- .subtitle-title--right (align to right side)
- - Optional:
- - Coming Soon™
-
-*/
-.subtitle-title {
- display: block;
- position: relative;
- flex-direction: column;
- align-content: flex-start;
- align-items: flex-start;
- width: auto;
- height: auto;
- padding: 0;
- background-color: rgba(0, 0, 0, 0);
- color: #CCCCCC;
- text-align: left;
- cursor: pointer;
-}
-.subtitle-title--right {
- align-content: flex-end;
-}
-.subtitle-title--right, .subtitle-title--right > * {
- text-align: right;
-}
-.subtitle-title[selected] {
- color: #F2F2F2;
- cursor: default;
-}
-.subtitle-title:focus:not(:disabled, [disabled]), .subtitle-title:hover:not(:disabled, [disabled], [selected]) {
- color: #B97DF2;
-}
-.subtitle-title:disabled, .subtitle-title[disabled] {
- opacity: 0.5;
- cursor: default;
- tab-index: none;
-}
-.subtitle-title h3 {
- margin-bottom: 6dp;
-}
-.subtitle-title h1 {
- margin-top: 6dp;
-}
-.subtitle-title__disclaimer {
- margin-top: 16dp;
-}
-
-.toggle {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 162dp;
- height: 72dp;
- border-radius: 36dp;
- opacity: 0.9;
- background: rgba(0, 0, 0, 0);
- cursor: pointer;
-}
-.toggle:hover, .toggle:focus-visible, .toggle:focus {
- opacity: 1;
- background-color: rgba(23, 214, 232, 0.3);
-}
-.toggle:active {
- opacity: 1;
- background-color: rgba(23, 214, 232, 0.05);
-}
-.toggle .toggle__border {
- position: absolute;
- top: 1.1dp;
- right: 1.1dp;
- bottom: 1.1dp;
- left: 1.1dp;
- border-width: 1.1dp;
- border-color: #A2EFF6;
- display: block;
- border-radius: 36dp;
-}
-.toggle .toggle__floater {
- position: absolute;
- top: 50%;
- left: 4dp;
- width: 80dp;
- height: 64dp;
- transform: translateY(-50%);
- border-radius: 32dp;
- background: #25A1AD;
-}
-.toggle--checked .toggle__floater {
- left: 78dp;
-}
-.toggle--checked .toggle__icon.toggle__icon--left {
- opacity: 0.9;
- color: #A2EFF6;
-}
-.toggle--checked .toggle__icon.toggle__icon--right {
- opacity: 1;
- color: #F2F2F2;
-}
-
-.toggle__icons {
- display: flex;
- position: absolute;
- top: 50%;
- right: 16dp;
- left: 16dp;
- align-items: center;
- justify-content: space-between;
- height: 56dp;
- transform: translateY(-50%);
-}
-
-.toggle__icon {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 56dp;
- height: 56dp;
- color: #F2F2F2;
-}
-.toggle__icon--right {
- opacity: 1;
- color: #A2EFF6;
-}
-
-.bottom-left {
- display: flex;
- position: absolute;
- bottom: 4dp;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: 1692.4444444444dp;
- height: auto;
- margin: 0 4dp;
-}
-
-.prompt__overlay {
- background-color: rgba(190, 184, 219, 0.1);
- pointer-events: auto;
-}
-.prompt__overlay, .prompt__content-wrapper {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
-}
-.prompt__content-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
-}
-.prompt__content {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: 700dp;
- height: auto;
- margin: auto;
- border-width: 1.1dp;
- border-radius: 16dp;
- border-color: rgba(255, 255, 255, 0.2);
- background: rgba(8, 7, 13, 0.9);
-}
-.prompt__content h3, .prompt__content p {
- margin: 24dp;
-}
-.prompt__content p {
- margin-top: 0;
-}
-.prompt__controls {
- display: flex;
- flex-direction: row;
- justify-content: center;
- padding: 24dp 12dp;
- border-top-width: 1.1dp;
- border-top-color: rgba(255, 255, 255, 0.1);
-}
-.prompt__controls .button {
- min-width: 233.3333333333dp;
- margin: 0 12dp;
- text-align: center;
- nav-up: none;
- nav-down: none;
-}
-
-.config-debug {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- padding: 8dp;
-}
-
-.config-debug__scroll {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.config-debug-option {
- color: #CCCCCC;
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out;
- border-bottom-width: 1.1dp;
- border-bottom-color: rgba(255, 255, 255, 0.1);
- display: block;
- position: relative;
- flex-direction: column;
- width: 100%;
- height: auto;
- padding: 12dp 4dp;
- background-color: rgba(0, 0, 0, 0);
-}
-.config-debug-option svg {
- image-color: #CCCCCC;
-}
-.config-debug-option svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.config-debug-option:focus:not(:disabled, [disabled]), .config-debug-option:focus-visible:not(:disabled, [disabled]), .config-debug-option:hover:not(:disabled, [disabled]) {
- color: #F2F2F2;
- background-color: rgba(190, 184, 219, 0.1);
-}
-.config-debug-option:focus:not(:disabled, [disabled]) svg, .config-debug-option:focus-visible:not(:disabled, [disabled]) svg, .config-debug-option:hover:not(:disabled, [disabled]) svg {
- image-color: #F2F2F2;
-}
-.config-debug-option:disabled, .config-debug-option[disabled] {
- opacity: 0.5;
-}
-.config-debug-option .icon-button {
- margin-left: 8dp;
-}
-
-.config-debug__option-split {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-}
-
-.config-debug-option__label {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- padding: 4dp 16dp 12dp;
- width: auto;
- height: auto;
- white-space: nowrap;
-}
-
-.config-debug__option-controls {
- display: block;
- position: relative;
- flex: 1 1 auto;
- height: auto;
- width: auto;
- max-width: 800dp;
- padding: 0 12dp;
-}
-
-.config-debug__option-trigger {
- flex: 1 1 auto;
-}
-
-.config-debug__select-wrapper {
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- flex: 1 1 100%;
- width: auto;
- max-width: 800dp;
- height: auto;
- padding: 4dp;
-}
-.config-debug__select-wrapper .config-debug__select-label {
- padding-right: 16dp;
- flex: auto;
- width: 196dp;
-}
-.config-debug__select-wrapper .config-debug__select-label > div {
- display: inline;
- width: auto;
- height: auto;
-}
-.config-debug__select-wrapper input {
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: 20dp;
- margin: auto 0;
-}
-.config-debug__select-wrapper select {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out;
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.5);
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: 48dp;
- border-radius: 12dp;
- background-color: rgba(255, 255, 255, 0.05);
- cursor: pointer;
- align-items: center;
- justify-content: flex-start;
- padding: 14dp;
-}
-.config-debug__select-wrapper select svg {
- transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out;
-}
-.config-debug__select-wrapper select:hover, .config-debug__select-wrapper select:focus {
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.8);
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-debug__select-wrapper select selectvalue {
- display: inline;
- margin: auto 0;
- height: auto;
-}
-.config-debug__select-wrapper select selectbox {
- border-width: 1.1dp;
- border-color: rgba(255, 255, 255, 0.8);
- background-color: #191622;
- padding: 4dp 0;
- margin-top: 2dp;
- border-radius: 12dp;
-}
-.config-debug__select-wrapper select selectbox option {
- transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out;
- padding: 8dp 12dp;
- background-color: rgba(0, 0, 0, 0);
- color: #CCCCCC;
- font-weight: 400;
-}
-.config-debug__select-wrapper select selectbox option:hover, .config-debug__select-wrapper select selectbox option:focus {
- background-color: rgba(255, 255, 255, 0.2);
-}
-.config-debug__select-wrapper select selectbox option:hover:not(:checked) {
- cursor: pointer;
-}
-.config-debug__select-wrapper select selectbox option:checked {
- color: #FFFFFF;
- background-color: rgba(255, 255, 255, 0.05);
-}
-
-body {
- box-sizing: border-box;
- color: #F2F2F2;
- font-family: "latolatin";
-}
-
-.rmlui-window {
- opacity: 1;
-}
-.rmlui-window--hidden {
- opacity: 0;
-}
-.rmlui-window:not([mouse-active]) {
- pointer-events: none;
-}
-
-*, *:before, *:after {
- box-sizing: border-box;
-}
-
-button {
- background-color: #7A2AC6;
-}
-
-@keyframes blue-pulse {
- 0% {
- color: #17D6E8;
- }
- 50% {
- color: #A2EFF6;
- }
- 100% {
- color: #17D6E8;
- }
-}
-@keyframes blue-pulse-with-border {
- 0% {
- border-color: #17D6E8;
- color: #17D6E8;
- }
- 50% {
- border-color: #A2EFF6;
- color: #A2EFF6;
- }
- 100% {
- border-color: #17D6E8;
- color: #17D6E8;
- }
-}
-@keyframes blue-pulse-background {
- 0% {
- background-color: #17D6E8;
- }
- 50% {
- background-color: #A2EFF6;
- }
- 100% {
- background-color: #17D6E8;
- }
-}
+.rml-needs-something-in-this-file {}
\ No newline at end of file
diff --git a/assets/rml.rcss b/assets/rml.rcss
deleted file mode 100644
index 0905b24..0000000
--- a/assets/rml.rcss
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* Default styles for all the basic elements.
-*/
-
-div
-{
- display: block;
-}
-
-p
-{
- display: block;
-}
-
-h1
-{
- display: block;
-}
-
-em
-{
- font-style: italic;
-}
-
-strong
-{
- font-weight: bold;
-}
-
-select
-{
- text-align: left;
-}
-
-tabset tabs
-{
- display: block;
-}
-
-table {
- box-sizing: border-box;
- display: table;
-}
-tr {
- box-sizing: border-box;
- display: table-row;
-}
-td {
- box-sizing: border-box;
- display: table-cell;
-}
-col {
- box-sizing: border-box;
- display: table-column;
-}
-colgroup {
- display: table-column-group;
-}
-thead, tbody, tfoot {
- display: table-row-group;
-}
diff --git a/assets/scss/.nvmrc b/assets/scss/.nvmrc
deleted file mode 100644
index b7586d6..0000000
--- a/assets/scss/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-iron
diff --git a/assets/scss/.stylelintrc b/assets/scss/.stylelintrc
deleted file mode 100644
index 60ad85f..0000000
--- a/assets/scss/.stylelintrc
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "extends": [
- "stylelint-config-recommended",
- "stylelint-config-standard",
- "stylelint-config-sass-guidelines",
- "stylelint-config-property-sort-order-smacss",
- "stylelint-config-standard-scss"
- ],
- "plugins": ["stylelint-scss"],
- "overrides": [{
- "files": ["**/*.scss"],
- "customSyntax": "postcss-scss"
- }],
- "rules": {
- "no-descending-specificity": null,
- "declaration-empty-line-before": null,
- "declaration-colon-newline-after": null,
- "declaration-block-no-duplicate-properties": true,
- "declaration-block-trailing-semicolon": null,
- "declaration-no-important": true,
- "declaration-property-value-disallowed-list": {
- "/^transition/": ["/all/"]
- },
- "block-closing-brace-newline-after": null,
- "max-empty-lines": null,
- "selector-list-comma-newline-after": null,
- "at-rule-empty-line-before": null,
- "at-rule-semicolon-newline-after": null,
- "selector-pseudo-element-colon-notation": "single",
- "color-no-hex": true,
- "function-url-quotes": "always",
- "max-nesting-depth": [
- 4,
- {
- "ignoreAtRules": ["each", "media", "supports", "include"],
- "severity": "warning"
- }
- ],
- "number-leading-zero": null,
- "order/order": [
- [
- "custom-properties",
- "dollar-variables",
- {
- "type": "at-rule",
- "name": "extend"
- },
- {
- "type": "at-rule",
- "name": "include"
- },
- "declarations",
- "rules"
- ]
- ],
- "order/properties-alphabetical-order": null,
- "property-no-vendor-prefix": [
- true,
- {
- "severity": "warning"
- }
- ],
- "value-no-vendor-prefix": [
- true,
- {
- "severity": "warning"
- }
- ],
- "scss/selector-no-redundant-nesting-selector": null,
- "selector-class-pattern": null,
- "selector-max-compound-selectors": [
- 4,
- {
- "severity": "warning"
- }
- ],
- "selector-no-qualifying-type": null,
- "string-quotes": null,
- "max-line-length": null,
- "keyframes-name-pattern": null,
- "scss/double-slash-comment-empty-line-before": null,
- "scss/double-slash-comment-whitespace-inside": null,
- "scss/dollar-variable-empty-line-before": null,
- "scss/dollar-variable-pattern": "[a-z-]",
- "scss/at-import-partial-extension": null,
- "declaration-block-no-redundant-longhand-properties": null,
- "color-function-notation": null,
- "alpha-value-notation": null,
- "at-rule-no-unknown": null,
- "property-no-unknown": null,
- "scss/at-rule-no-unknown": true,
- "selector-pseudo-class-no-unknown": [true, { "ignorePseudoClasses": ["selected"] }],
- "font-family-no-missing-generic-family-keyword": null,
- "scss/no-global-function-names": null,
- "unit-no-unknown": [true, { "ignoreUnits": ["dp"] }],
- "selector-type-no-unknown": [true, { "ignore": ["custom-elements", "default-namespace"] }],
- "value-keyword-case": null
- }
-}
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
deleted file mode 100644
index 9d03ad3..0000000
--- a/assets/scss/main.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import "styles/base";
-@import "styles/global";
diff --git a/assets/scss/package-lock.json b/assets/scss/package-lock.json
deleted file mode 100644
index 78ab77a..0000000
--- a/assets/scss/package-lock.json
+++ /dev/null
@@ -1,2261 +0,0 @@
-{
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "sass": "^1.75.0"
- },
- "devDependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint": "^15.11.0",
- "stylelint-config-property-sort-order-smacss": "^9.1.0",
- "stylelint-config-sass-guidelines": "^10.0.0",
- "stylelint-config-scss": "^1.0.0-security",
- "stylelint-config-standard": "^34.0.0",
- "stylelint-config-standard-scss": "^11.1.0",
- "stylelint-scss": "^5.3.1"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@csstools/css-parser-algorithms": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.2.tgz",
- "integrity": "sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "@csstools/css-tokenizer": "^2.2.1"
- }
- },
- "node_modules/@csstools/css-tokenizer": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.1.tgz",
- "integrity": "sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- }
- },
- "node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.5.tgz",
- "integrity": "sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.2",
- "@csstools/css-tokenizer": "^2.2.1"
- }
- },
- "node_modules/@csstools/selector-specificity": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz",
- "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "postcss-selector-parser": "^6.0.13"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@types/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
- "dev": true
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
- "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
- "dev": true
- },
- "node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/balanced-match": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
- "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
- "dev": true
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/brace-expansion/node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/camelcase-keys": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz",
- "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==",
- "dev": true,
- "dependencies": {
- "camelcase": "^6.3.0",
- "map-obj": "^4.1.0",
- "quick-lru": "^5.1.1",
- "type-fest": "^1.2.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
- "dev": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/cosmiconfig": {
- "version": "8.3.6",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
- "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
- "dev": true,
- "dependencies": {
- "import-fresh": "^3.3.0",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.2.0",
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/d-fischer"
- },
- "peerDependencies": {
- "typescript": ">=4.9.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/css-functions-list": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz",
- "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==",
- "dev": true,
- "engines": {
- "node": ">=12 || >=16"
- }
- },
- "node_modules/css-property-sort-order-smacss": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/css-property-sort-order-smacss/-/css-property-sort-order-smacss-2.2.0.tgz",
- "integrity": "sha512-nXutswsivIEBOrPo/OZw2KQjFPLvtg68aovJf6Kqrm3L6FmTvvFPaeDrk83hh0+pRJGuP3PeKJwMS0E6DFipdQ==",
- "dev": true
- },
- "node_modules/css-tree": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
- "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
- "dev": true,
- "dependencies": {
- "mdn-data": "2.0.30",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
- "node_modules/cssesc": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
- "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
- "dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decamelize": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz",
- "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "dev": true,
- "dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys/node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
- "dev": true,
- "engines": {
- "node": ">= 4.9.1"
- }
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.2.tgz",
- "integrity": "sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==",
- "dev": true,
- "dependencies": {
- "flat-cache": "^3.2.0"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
- "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.9",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
- "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
- "dev": true
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "dev": true,
- "dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "dev": true,
- "dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globjoin": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
- "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
- "dev": true
- },
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
- "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/html-tags": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
- "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ignore": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
- "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/immutable": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
- "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw=="
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-fresh/node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/import-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/indent-string": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
- "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
- },
- "node_modules/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.13.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
- "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
- "dev": true,
- "dependencies": {
- "hasown": "^2.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-plain-obj": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
- "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
- },
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
- },
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/kind-of": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
- "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/known-css-properties": {
- "version": "0.29.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz",
- "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==",
- "dev": true
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "dev": true
- },
- "node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mathml-tag-names": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
- "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
- "dev": true,
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/mdn-data": {
- "version": "2.0.30",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
- "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
- "dev": true
- },
- "node_modules/meow": {
- "version": "10.1.5",
- "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz",
- "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==",
- "dev": true,
- "dependencies": {
- "@types/minimist": "^1.2.2",
- "camelcase-keys": "^7.0.0",
- "decamelize": "^5.0.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.2",
- "read-pkg-up": "^8.0.0",
- "redent": "^4.0.0",
- "trim-newlines": "^4.0.2",
- "type-fest": "^1.2.2",
- "yargs-parser": "^20.2.9"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
- },
- "node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-media-query-parser": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
- "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
- "dev": true
- },
- "node_modules/postcss-resolve-nested-selector": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
- "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
- "dev": true
- },
- "node_modules/postcss-safe-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
- "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
- "dev": true,
- "engines": {
- "node": ">=12.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.3.3"
- }
- },
- "node_modules/postcss-scss": {
- "version": "4.0.9",
- "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz",
- "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss-scss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.4.29"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
- "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
- "dev": true,
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-sorting": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz",
- "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==",
- "dev": true,
- "peerDependencies": {
- "postcss": "^8.4.20"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/quick-lru": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
- "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz",
- "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==",
- "dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^3.0.2",
- "parse-json": "^5.2.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz",
- "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^5.0.0",
- "read-pkg": "^6.0.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/redent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz",
- "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==",
- "dev": true,
- "dependencies": {
- "indent-string": "^5.0.0",
- "strip-indent": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/sass": {
- "version": "1.75.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz",
- "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==",
- "dependencies": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
- "source-map-js": ">=0.6.2 <2.0.0"
- },
- "bin": {
- "sass": "sass.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/slice-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
- "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
- "dev": true
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
- "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
- "dev": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
- "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
- "dev": true
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-indent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz",
- "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==",
- "dev": true,
- "dependencies": {
- "min-indent": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/style-search": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
- "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==",
- "dev": true
- },
- "node_modules/stylelint": {
- "version": "15.11.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz",
- "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==",
- "dev": true,
- "dependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/media-query-list-parser": "^2.1.4",
- "@csstools/selector-specificity": "^3.0.0",
- "balanced-match": "^2.0.0",
- "colord": "^2.9.3",
- "cosmiconfig": "^8.2.0",
- "css-functions-list": "^3.2.1",
- "css-tree": "^2.3.1",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.1",
- "fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^7.0.0",
- "global-modules": "^2.0.0",
- "globby": "^11.1.0",
- "globjoin": "^0.1.4",
- "html-tags": "^3.3.1",
- "ignore": "^5.2.4",
- "import-lazy": "^4.0.0",
- "imurmurhash": "^0.1.4",
- "is-plain-object": "^5.0.0",
- "known-css-properties": "^0.29.0",
- "mathml-tag-names": "^2.1.3",
- "meow": "^10.1.5",
- "micromatch": "^4.0.5",
- "normalize-path": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.28",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-safe-parser": "^6.0.0",
- "postcss-selector-parser": "^6.0.13",
- "postcss-value-parser": "^4.2.0",
- "resolve-from": "^5.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "style-search": "^0.1.0",
- "supports-hyperlinks": "^3.0.0",
- "svg-tags": "^1.0.0",
- "table": "^6.8.1",
- "write-file-atomic": "^5.0.1"
- },
- "bin": {
- "stylelint": "bin/stylelint.mjs"
- },
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/stylelint"
- }
- },
- "node_modules/stylelint-config-property-sort-order-smacss": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-property-sort-order-smacss/-/stylelint-config-property-sort-order-smacss-9.1.0.tgz",
- "integrity": "sha512-TijYeDoDgHAFjpn9NnziQrmUCGrm2AM4e1HzsdI2mCWBRkQRuewc343YqDwdFgQ5eHoMZ3JRL02i72W3vktuDA==",
- "dev": true,
- "dependencies": {
- "css-property-sort-order-smacss": "~2.2.0",
- "stylelint-order": "^6.0.2"
- },
- "peerDependencies": {
- "stylelint": "^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/stylelint-config-recommended": {
- "version": "13.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz",
- "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==",
- "dev": true,
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "peerDependencies": {
- "stylelint": "^15.10.0"
- }
- },
- "node_modules/stylelint-config-recommended-scss": {
- "version": "13.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.1.0.tgz",
- "integrity": "sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==",
- "dev": true,
- "dependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint-config-recommended": "^13.0.0",
- "stylelint-scss": "^5.3.0"
- },
- "peerDependencies": {
- "postcss": "^8.3.3",
- "stylelint": "^15.10.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- }
- }
- },
- "node_modules/stylelint-config-sass-guidelines": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-sass-guidelines/-/stylelint-config-sass-guidelines-10.0.0.tgz",
- "integrity": "sha512-+Rr2Dd4b72CWA4qoj1Kk+y449nP/WJsrD0nzQAWkmPPIuyVcy2GMIcfNr0Z8JJOLjRvtlkKxa49FCNXMePBikQ==",
- "dev": true,
- "dependencies": {
- "postcss-scss": "^4.0.6",
- "stylelint-scss": "^4.4.0"
- },
- "engines": {
- "node": "^14.13.1 || >=16.13.0 || >=18.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.4.21",
- "stylelint": "^15.2.0"
- }
- },
- "node_modules/stylelint-config-sass-guidelines/node_modules/stylelint-scss": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz",
- "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==",
- "dev": true,
- "dependencies": {
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-selector-parser": "^6.0.11",
- "postcss-value-parser": "^4.2.0"
- },
- "peerDependencies": {
- "stylelint": "^14.5.1 || ^15.0.0"
- }
- },
- "node_modules/stylelint-config-scss": {
- "version": "1.0.0-security",
- "resolved": "https://registry.npmjs.org/stylelint-config-scss/-/stylelint-config-scss-1.0.0-security.tgz",
- "integrity": "sha512-8Pgul2mNpzTeK2KCuyV5RcDC1BgzWzU7dCLVJWuxpkKgmxrMqCvjqgyosaKbAVZy2AiaMU0zfHBt7prg7/NaxA==",
- "dev": true
- },
- "node_modules/stylelint-config-standard": {
- "version": "34.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz",
- "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==",
- "dev": true,
- "dependencies": {
- "stylelint-config-recommended": "^13.0.0"
- },
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "peerDependencies": {
- "stylelint": "^15.10.0"
- }
- },
- "node_modules/stylelint-config-standard-scss": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.1.0.tgz",
- "integrity": "sha512-5gnBgeNTgRVdchMwiFQPuBOtj9QefYtfXiddrOMJA2pI22zxt6ddI2s+e5Oh7/6QYl7QLJujGnaUR5YyGq72ow==",
- "dev": true,
- "dependencies": {
- "stylelint-config-recommended-scss": "^13.1.0",
- "stylelint-config-standard": "^34.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.3.3",
- "stylelint": "^15.10.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- }
- }
- },
- "node_modules/stylelint-order": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz",
- "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==",
- "dev": true,
- "dependencies": {
- "postcss": "^8.4.21",
- "postcss-sorting": "^8.0.2"
- },
- "peerDependencies": {
- "stylelint": "^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/stylelint-scss": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.1.tgz",
- "integrity": "sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==",
- "dev": true,
- "dependencies": {
- "known-css-properties": "^0.29.0",
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-selector-parser": "^6.0.13",
- "postcss-value-parser": "^4.2.0"
- },
- "peerDependencies": {
- "stylelint": "^14.5.1 || ^15.0.0"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/supports-hyperlinks": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
- "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0",
- "supports-color": "^7.0.0"
- },
- "engines": {
- "node": ">=14.18"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/svg-tags": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
- "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
- "dev": true
- },
- "node_modules/table": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
- "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
- "dev": true,
- "dependencies": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/trim-newlines": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz",
- "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/type-fest": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
- "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true
- },
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
- "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
- "dev": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
- "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
- "dev": true,
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "which": "bin/which"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "node_modules/write-file-atomic": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
- "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
- "dev": true,
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
- "node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- }
-}
diff --git a/assets/scss/package.json b/assets/scss/package.json
deleted file mode 100644
index 1055122..0000000
--- a/assets/scss/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "npm run watch",
- "watch": "sass --no-source-map --no-charset --style=compressed main.scss ..\\recomp.rcss --watch",
- "watch:debug": "sass --no-source-map --no-charset main.scss ..\\recomp.rcss --watch",
- "build": "sass --no-source-map --no-charset --style=compressed main.scss ..\\recomp.rcss",
- "build:debug": "sass --no-source-map --no-charset main.scss ..\\recomp.rcss",
- "lint": "stylelint '.\\**\\*.scss'"
- },
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint": "^15.11.0",
- "stylelint-config-property-sort-order-smacss": "^9.1.0",
- "stylelint-config-sass-guidelines": "^10.0.0",
- "stylelint-config-scss": "^1.0.0-security",
- "stylelint-config-standard": "^34.0.0",
- "stylelint-config-standard-scss": "^11.1.0",
- "stylelint-scss": "^5.3.1"
- },
- "dependencies": {
- "sass": "^1.75.0"
- }
-}
diff --git a/assets/scss/styles/base.scss b/assets/scss/styles/base.scss
deleted file mode 100644
index 88e158e..0000000
--- a/assets/scss/styles/base.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-@use 'sass:math';
-@import "./functions/spacing";
-@import "./vars/spacing";
-@import "./vars/colors";
-@import "./vars/borders";
-@import "./vars/gradients";
-@import "./vars/transitions";
-@import "./vars/animations";
-@import "./mixins/typography";
-@import "./mixins/transitions";
-@import "./mixins/helpers";
diff --git a/assets/scss/styles/components/BottomLeft.scss b/assets/scss/styles/components/BottomLeft.scss
deleted file mode 100644
index 28821c8..0000000
--- a/assets/scss/styles/components/BottomLeft.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@use 'sass:math';
-
-.bottom-left {
- display: flex;
- position: absolute;
- bottom: space(4);
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: auto;
- margin: 0 space(4);
-}
diff --git a/assets/scss/styles/components/Button.scss b/assets/scss/styles/components/Button.scss
deleted file mode 100644
index d5d1514..0000000
--- a/assets/scss/styles/components/Button.scss
+++ /dev/null
@@ -1,81 +0,0 @@
-@use 'sass:color';
-
-@mixin create-button-variation($base-col) {
- border-color: rgba($base-col, 0.8);
- background-color: rgba($base-col, 0.05);
- color: $color-text-dim;
-
- &:focus, &:hover {
- border-color: $base-col;
- background-color: rgba($base-col, 0.3);
- color: $color-text;
- }
-
- &:disabled,&[disabled] {
- color: $color-text-inactive;
- }
-
- &:active {
- background-color: rgba($base-col, 0.2);
- color: color.scale($color-text, $lightness: 20%);
- }
-}
-
-.button {
- @extend %label-md;
- @extend %nav-all;
- @include create-button-variation($color-primary);
- @include trans-colors;
-
- display: block;
- width: auto;
- height: auto;
- // leave 1dp room for border expansion
- padding: space(24 - 1);
- border-width: $border-width-thickness;
-
- border-radius: $border-radius-md;
-
- // Setting it by default for convenience
- &--primary {
- @include create-button-variation($color-primary);
- }
-
- &--large {
- @extend %label-lg;
- }
-
- &--secondary {
- @include create-button-variation($color-secondary);
- }
-
- &--tertiary {
- @include create-button-variation($color-text);
- }
-
- &--success {
- @include create-button-variation($color-success);
- }
-
- &--error {
- @include create-button-variation($color-error);
- }
-
- &--warning {
- @include create-button-variation($color-warning);
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-
- &:disabled,&[disabled] {
- opacity: 0.5;
- }
-
- &__label {
- width: auto;
- height: auto;
- }
-}
diff --git a/assets/scss/styles/components/CenteredPage.scss b/assets/scss/styles/components/CenteredPage.scss
deleted file mode 100644
index a724472..0000000
--- a/assets/scss/styles/components/CenteredPage.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-@use 'sass:math';
-
-.centered-page {
- display: flex;
- // visibility: hidden;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- padding: space($page-margin);
- background-color: $color-border-soft;
-}
-
-.centered-page__modal {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: 100%;
- margin: auto;
- border-width: $border-width-thickness;
- border-radius: $border-radius-modal;
- border-color: $color-border;
- background: $color-modal-overlay;
-
- > .tabs {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: 100%;
- margin: auto;
- }
-
- panels {
- flex: 1 1 100%;
- }
-}
-
-.centered-page__controls {
- display: flex;
- position: absolute;
- bottom: space(24);
- flex-direction: row;
- align-items: center;
- justify-content: center;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: auto;
- margin: 0 auto;
-
- > label {
- @extend %label-sm;
- display: inline-block;
- align-items: center;
- justify-content: space-between;
- width: auto;
- height: space(24);
-
- &:not(:last-child) {
- margin-right: space(40);
- }
-
- > span:first-child {
- margin-right: space(4);
- }
- }
-}
diff --git a/assets/scss/styles/components/Config.scss b/assets/scss/styles/components/Config.scss
deleted file mode 100644
index 54c6e1d..0000000
--- a/assets/scss/styles/components/Config.scss
+++ /dev/null
@@ -1,101 +0,0 @@
-
-.config__icon-buttons {
- display: flex;
- position: absolute;
- top: space(8);
- right: space(0);
- flex-direction: row;
- align-items: center;
- justify-content: flex-end;
- width: auto;
-
- .icon-button {
- margin: 0 space(8);
- }
-}
-
-.config__form {
- @include border-top($color-border-soft);
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
-}
-
-.config__wrapper {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: space(16);
- border-radius: 0dp;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
- background-color: $color-bg-shadow;
- text-align: left;
-
- p {
- @extend %body;
- padding: space(16);
- line-height: space(28);
- white-space: pre-line;
-
- b {
- color: $color-primary;
- }
-
- i {
- color: $color-warning;
- font-style: normal;
- }
- }
-}
-
-.config__hz-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- width: 100%;
- height: 100%;
- border-radius: 0dp;
- text-align: left;
-}
-
-.config__header, .config__footer {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- background-color: $color-bg-shadow;
-}
-
-.config__header {
- @include border-bottom($color-border-soft);
- padding: space(12) space(20);
-}
-
-.config__footer {
- @include border-top($color-border-soft);
- padding: space(20) space(20);
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
-}
-
-.config__header-left {
- display: flex;
- flex: 1 1 auto;
- flex-direction: row;
-
- > :not(:first-child) {
- margin-left: space(8);
- }
-}
-
-.config__row {
- display: flex;
- flex-direction: row;
-}
-
diff --git a/assets/scss/styles/components/ConfigDescription.scss b/assets/scss/styles/components/ConfigDescription.scss
deleted file mode 100644
index 2f4966f..0000000
--- a/assets/scss/styles/components/ConfigDescription.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-.config-description {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: space(16);
- border-radius: 0dp;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
- background-color: $color-bg-shadow;
- text-align: left;
-
- &__contents {
- @extend %body;
- padding: space(16);
- line-height: space(28);
- white-space: pre-line;
-
- b {
- color: $color-primary;
- }
-
- i {
- color: $color-warning;
- font-style: normal;
- }
- }
-}
diff --git a/assets/scss/styles/components/ConfigGroup.scss b/assets/scss/styles/components/ConfigGroup.scss
deleted file mode 100644
index 9f6444b..0000000
--- a/assets/scss/styles/components/ConfigGroup.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-
-.config-group {
- position: relative;
-
- &--scrollable {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: 0 0 0 space(16);
-
- .config-group__wrapper {
- max-height: 100%;
- overflow-y: auto;
- }
- }
-
- &__title {
- @extend %label-md;
- color: $color-primary;
-
- &--hidden {
- display: none;
- }
- }
-
- &__wrapper {
- padding: space(16) 0;
- }
-}
diff --git a/assets/scss/styles/components/ConfigOption.scss b/assets/scss/styles/components/ConfigOption.scss
deleted file mode 100644
index 26acd85..0000000
--- a/assets/scss/styles/components/ConfigOption.scss
+++ /dev/null
@@ -1,413 +0,0 @@
-.config-option {
- display: flex;
- flex: 1;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
- margin: space(16) space(0) space(24);
-
- &--hz {
- flex-direction: row-reverse;
- align-items: center;
- margin-top: space(4);
- margin-bottom: space(4);
-
- .config-option__title {
- @extend %label-md;
- flex: 1 1 100%;
- }
-
- .config-option__list {
- flex: 1 1 auto;
- width: auto;
- }
-
- &:first-child {
- margin-top: 0;
- }
-
- &:last-child {
- margin-bottom: 0;
- }
- }
-}
-
-.config-option__title {
- @extend %label-md;
- padding: 0 space(12);
-}
-
-.config-option__radio-tabs,
-.config-option__list {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: 0;
-
- input:first-of-type {
- nav-left: none;
- }
-
- input:last-of-type {
- nav-right: none;
- }
-
- .config-option__tab-label {
- @extend %label-sm;
- @include trans-colors-opa;
- display: block;
- position: relative;
- height: auto;
- margin: space(4) space(12) 0;
- padding: space(8) 0;
- color: $color-text-inactive;
- tab-index: none;
-
- &:hover {
- color: $color-text;
- cursor: pointer;
- }
- }
-
- .config-option__checkbox-wrapper {
- @include trans-colors-opa;
- width: space(32);
- height: space(32);
- margin: space(4) space(12) 0;
- border-radius: $border-radius-sm;
- opacity: 0.5;
- background-color: $color-bg-overlay;
- cursor: pointer;
-
- &:hover {
- opacity: 1;
- }
-
- &[checked] {
- background-color: $color-a;
- }
- }
-
- .config-option__checkbox {
- @extend %nav-all;
- @include trans-colors-opa;
- visibility: visible;
- width: 0;
- height: 0;
- }
-
- // TODO: Remove & Replace old stylings
- input.radio {
- @extend %nav-all;
- @include trans-colors-opa;
- visibility: visible;
- width: 0;
- height: 0;
-
- &:not(:disabled) {
- &:checked + .config-option__tab-label {
- border-bottom: 1dp;
- border-color: $color-text;
- color: $color-text;
-
- &:hover {
- cursor: default;
- }
- }
-
- .rmlui-window:not([mouse-active]) &:focus + .config-option__tab-label {
- transition: none;
- animation: $focus-anim-border;
- border-color: $color-secondary;
- color: $color-secondary;
- }
-
- &:focus + .config-option__tab-label,
- &:hover + .config-option__tab-label {
- color: $color-text;
- }
- }
-
- &:disabled + .config-option__tab-label {
- opacity: 0.5;
-
- &:hover {
- cursor: default;
- }
- }
- }
-
- input.range slidertrack {
- @include trans-colors;
- height: 2dp;
- margin-top: space(8);
- background-color: $color-border;
- }
-
- input.range sliderbar {
- @include trans-colors;
- width: space(16);
- height: space(16);
- margin-top: space(1);
- margin-right: space(-8);
- margin-left: space(-8);
- transition: background-color $transition-quick;
- border-radius: 8dp;
- background-color: $color-text-dim;
-
- .rmlui-window:not([mouse-active]) &:focus {
- @include border($color-a);
- animation: $focus-anim-bg;
- }
-
- &:hover {
- background-color: $color-text;
- cursor: pointer;
- }
- }
-
- input.range sliderbar:active,
- input.range slidertrack:active + sliderbar {
- background-color: $color-secondary;
- }
-
- input.range sliderarrowdec,
- input.range sliderarrowinc {
- display: none;
- }
-}
-
-.config-option__details {
- @extend %label-xs;
- height: space(18);
- margin: space(14) space(12) 0;
- color: $color-primary;
-}
-
-.config-option-color {
- width: 100%;
- max-width: space(360);
- height: auto;
- margin-top: space(4);
- margin-left: space(12);
- padding: 0;
-
- &__preview-wrapper {
- display: flex;
- flex-direction: row;
- width: 100%;
- height: space(8 * 9);
- }
-
- &__preview-block {
- display: block;
- width: space(8 * 11);
- height: 100%;
- border-width: $border-width-thickness;
- border-radius: $border-radius-lg;
- border-color: $color-border;
- }
-
- &__hsv-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- width: auto;
- height: auto;
- padding-left: space(8);
-
- .config-option-range {
- flex: 1 1 auto;
-
- label {
- min-width: space(72);
- }
-
- input {
- flex: 1 1 auto;
- }
- }
- }
-}
-
-.config-option-range {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: space(360);
- height: auto;
- margin-top: space(4);
- padding: 0;
-
- &__label {
- @extend %label-sm;
-
- display: block;
- width: space(56);
- margin: 0 12dp;
- margin-right: space(16);
- padding: 0;
- color: $color-text;
- tab-index: none;
- }
-
- &__range-input {
- flex: 1;
-
- slidertrack {
- @include trans-colors;
- height: 2dp;
- margin-top: space(8);
- background-color: $color-border;
- }
-
- sliderbar {
- @include trans-colors;
- width: space(16);
- height: space(16);
- margin-top: space(1);
- margin-right: space(-8);
- margin-left: space(-8);
- transition: background-color $transition-quick;
- border-radius: 8dp;
- background-color: $color-text-dim;
-
- .rmlui-window:not([mouse-active]) &:focus {
- @include border($color-a);
- animation: $focus-anim-bg;
- }
-
- &:hover {
- background-color: $color-text;
- cursor: pointer;
- }
- }
-
- sliderbar:active,
- slidertrack:active + sliderbar {
- background-color: $color-secondary;
- }
-
- sliderarrowdec,
- sliderarrowinc {
- display: none;
- }
- }
-
-}
-
-.config-option__range-wrapper {
- max-width: space(360);
- margin-top: space(4);
-}
-
-.config-option__range-label {
- @extend %label-sm;
-
- display: block;
- // flex: 0 0 space(32);
- width: space(56);
- margin: 0 12dp;
- margin-right: space(16);
- padding: 0;
- color: $color-text;
- tab-index: none;
-}
-
-.config-option-dropdown, .config-option-textfield {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- width: auto;
- height: auto;
- padding: space(8) space(24) space(8) space(12);
-
- &__select {
- display: block;
- height: space(48);
- padding: space(14);
- cursor: pointer;
- }
-
- &__wrapper {
- // Cursed guess & check so that this appears to be the same height as the select
- $extra-space: 2;
-
- display: flex;
- align-items: center;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: space(0 + $extra-space) 0 space(10 + $extra-space);
- cursor: text;
-
- input {
- width: 100%;
- height: auto;
- vertical-align: middle;
- }
- }
-
- &__select, &__wrapper {
- @extend %body;
- @extend %nav-all;
- @include trans-colors-border;
- @include border($color-white-a50);
- position: relative;
- box-sizing: border-box;
- flex: 1 1 100%;
-
- width: auto;
- border-radius: $border-radius-md;
- background-color: $color-white-a5;
-
- &:hover, &:focus {
- @include border($color-white-a80);
- background-color: $color-white-a20;
- }
-
- selectvalue {
- display: inline;
- height: auto;
- margin: auto 0;
- }
-
- selectbox {
- @include border($color-border);
- margin-top: space(2);
- padding: space(4) 0;
- border-radius: $border-radius-md;
- background-color: $color-background-3;
-
- option {
- @extend %nav-all;
- @include trans-colors;
- padding: space(8) space(12);
- background-color: $color-transparent;
- color: $color-text-dim;
- font-weight: 400;
-
- &:hover, &:focus {
- background-color: $color-white-a20;
- }
-
- &:hover:not(:checked) {
- cursor: pointer;
- }
-
- &:checked {
- background-color: $color-white-a5;
- color: $color-white;
- }
- }
- }
- }
-}
diff --git a/assets/scss/styles/components/ControlOption.scss b/assets/scss/styles/components/ControlOption.scss
deleted file mode 100644
index 662fd63..0000000
--- a/assets/scss/styles/components/ControlOption.scss
+++ /dev/null
@@ -1,170 +0,0 @@
-@use 'sass:color';
-@use 'sass:math';
-
-.control-option {
- @include set-color($color-text-dim);
- @include trans-colors-svg;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: auto;
- padding: space(4) space(16) space(4) space(20);
- border-radius: $border-radius-sm;
- background-color: rgba(0, 0, 0, 0);
-
- &:focus-visible:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-text);
- background-color: $color-bg-overlay;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- }
-
- &--active {
- // while actively looking for inputs, set styles to the correct slots
- $valid-binding-slots: 0, 1;
- @each $slot in $valid-binding-slots {
- // global attr -> this active row -> binding slot
- [cur-binding-slot="#{$slot}"] & .control-option__binding[bind-slot="#{$slot}"] {
- border-color: $color-error;
-
- .control-option__binding-icon {
- opacity: 0;
- }
-
- .control-option__binding-recording {
- opacity: 1;
- }
- }
- }
- }
-
- .icon-button {
- flex: 1 1 auto;
- }
-}
-
-.control-option__label {
- @extend %label-md;
- flex: 2 1 space(300);
- height: auto;
- white-space: nowrap;
-}
-
-.control-option__bindings {
- display: flex;
- position: relative;
- flex: 2 1 space(400);
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: space(56);
- padding: 0 space(12) 0 space(4);
-}
-
-.control-option__binding {
- @include set-color($color-text-dim);
- @include trans-colors-border;
- display: flex;
- position: relative;
-
- flex: 1 1 100%;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: space(56);
- margin: 0 space(4);
- padding: space(8);
- border-width: $border-width-thickness;
- border-radius: $border-radius-sm;
- border-color: $color-bg-overlay;
- background-color: $color-bg-overlay;
-
- &:focus, &:hover {
- @include set-color($color-text);
- border-color: $color-text;
- background-color: $color-border-soft;
- }
-
- &:active {
- @include set-color(color.scale($color-text, $lightness: 20%));
- }
-
- &:disabled, &[disabled] {
- @include set-color($color-text-dim);
- opacity: 0.5;
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-}
-
-.control-option__binding-icon {
- @include trans-colors-opa;
- opacity: 1;
-}
-
-@keyframes control-option__binding-recording-scale {
- 0% {
- transform: scale(1);
- }
-
- 50% {
- transform: scale(0.85);
- }
-
- 100% {
- transform: scale(1);
- }
-}
-
-.control-option__binding-recording {
- @include trans-colors-opa;
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
- opacity: 0;
-
- .control-option__binding-circle {
- $rec-size: 24;
-
- width: space($rec-size);
- height: space($rec-size);
- animation: 1.5s sine-in-out infinite control-option__binding-recording-scale;
- border-radius: space($rec-size);
- background-color: $color-error;
- }
-
- .control-option__binding-edge {
- $edge-size: 36;
- $h-edge-size: math.div($edge-size, 2);
-
- position: absolute;
-
- top: 50%;
- left: 50%;
- width: space($edge-size);
- height: space($edge-size);
-
- transform: translate(-50%, -50%);
-
- > svg.control-option__binding-edge-svg {
- width: space($edge-size);
- height: space($edge-size);
- image-color: $color-error;
- }
- }
-}
diff --git a/assets/scss/styles/components/IconButton.scss b/assets/scss/styles/components/IconButton.scss
deleted file mode 100644
index 4e1822a..0000000
--- a/assets/scss/styles/components/IconButton.scss
+++ /dev/null
@@ -1,92 +0,0 @@
-@use 'sass:color';
-
-/*
-
-*/
-@mixin create-icon-button-variation($base-col) {
- border-color: rgba($base-col, 0.8);
- background-color: rgba($base-col, 0.05);
-
- &:focus, &:hover {
- border-color: $base-col;
- background-color: rgba($base-col, 0.3);
- }
-
- &:active {
- background-color: rgba($base-col, 0.2);
- }
-}
-
-$icon-button-size: 56 - ($border-width-thickness-num * 2);
-
-.icon-button {
- @include set-color($color-text-dim);
- @include trans-colors-border;
-
- display: flex;
- align-items: center;
- justify-content: center;
- width: space($icon-button-size);
- min-width: space($icon-button-size);
- max-width: space($icon-button-size);
- height: space($icon-button-size);
- min-height: space($icon-button-size);
- max-height: space($icon-button-size);
- border-width: $border-width-thickness;
- border-radius: space($icon-button-size * 0.5);
- border-color: $color-transparent;
- background-color: $color-transparent;
-
- &:focus, &:hover {
- @include set-color($color-text);
- background-color: $color-border;
- }
-
- &:active {
- @include set-color(color.scale($color-text, $lightness: 20%));
- background-color: $color-border-soft;
- }
-
- &:disabled,&[disabled] {
- @include set-color($color-text-dim);
- opacity: 0.5;
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-
- svg {
- width: space(32);
- height: space(32);
- }
-
- &--primary {
- @include create-icon-button-variation($color-primary);
- }
-
- &--secondary {
- @include create-icon-button-variation($color-secondary);
- }
-
- &--tertiary {
- @include create-icon-button-variation($color-text);
- }
-
- &--success {
- @include create-icon-button-variation($color-success);
- }
-
- &--error {
- @include create-icon-button-variation($color-error);
- }
-
- &--warning {
- @include create-icon-button-variation($color-warning);
- }
-}
diff --git a/assets/scss/styles/components/InputConfig.scss b/assets/scss/styles/components/InputConfig.scss
deleted file mode 100644
index c01374e..0000000
--- a/assets/scss/styles/components/InputConfig.scss
+++ /dev/null
@@ -1,349 +0,0 @@
-@use 'sass:math';
-
-// Probably will need to adjust for other langs...
-$mapping-min-width: 80 * 8;
-$visual-max-width: $base-modal-max-width - $mapping-min-width - $scrollbar-width;
-
-.input-config {
- padding: 0;
-}
-
-.input-config__horizontal-split {
- display: flex;
- position: relative;
- flex-direction: row;
- height: 100%;
-}
-
-.input-config__mappings {
- display: block;
- flex: 1 1 auto;
- min-width: space($mapping-min-width);
- height: 100%;
-}
-
-.input-config__mappings-scroll {
- display: block;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.input-config__mappings-wrapper {
- padding: space(8);
-}
-
-.input-config__visual-wrapper {
- display: block;
- flex: 1 1 100%;
- width: auto;
- max-width: space($visual-max-width);
- height: auto;
- max-height: space(math.div($visual-max-width, 4) * 3);
- margin: auto 0;
-}
-
-.input-config__visual-aspect {
- position: relative;
- width: 100%;
- margin: auto 0;
- padding-bottom: 75%;
- background-color: $color-bg-shadow;
-}
-
-.input-config__visual {
- display: flex;
- position: absolute;
- top: space(16);
- right: space(16);
- bottom: space(16);
- left: space(16);
- flex-direction: column;
- border-radius: space(108);
- background-color: $color-white-a5;
-}
-
-.input-config__visual-half {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- padding: 6%;
-
- &--bottom {
- align-items: flex-end;
- justify-content: space-between;
- }
-}
-
-.input-config__visual-quarter-left {
- display: flex;
- flex: 1 1 50%;
- align-items: flex-start;
- justify-content: flex-start;
- width: auto;
-}
-
-.input-config__visual-quarter-right {
- display: flex;
- flex: 1 1 100%;
- align-items: flex-start;
- justify-content: flex-end;
-}
-
-.input-config__visual-stick-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
-}
-
-.input-viz {
- @include trans-colors-opa;
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
-
- > svg:not(.input-viz__dpad-arrow) {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &__mappings div {
- @extend %prompt-font-sm;
- }
-}
-
-$all-inputs: A,
- B,
- Z,
- START,
- DPAD_UP,
- DPAD_DOWN,
- DPAD_LEFT,
- DPAD_RIGHT,
- L,
- R,
- C_UP,
- C_DOWN,
- C_LEFT,
- C_RIGHT,
- X_AXIS_NEG,
- X_AXIS_POS,
- Y_AXIS_NEG,
- Y_AXIS_POS;
-
-// Show default state while no inputs are active
-[cur-input="NONE"] .input-viz[visual-input] {
- opacity: 1;
-}
-
-@each $inp in $all-inputs {
- .input-viz[visual-input~="#{$inp}"] {
- opacity: 0.25;
-
- [cur-input="#{$inp}"] & {
- opacity: 1.0;
- }
- }
-}
-
-@mixin set-sizes($sz) {
- width: space($sz);
- height: space($sz);
-
- > svg {
- width: space($sz);
- height: space($sz);
- }
-}
-
-.input-viz__button {
- @include set-color($color-text);
-
- &--sm {
- @include set-sizes(64);
- }
-
- &--md {
- @include set-sizes(76);
- }
-
- &--lg {
- @include set-sizes(84);
- }
-
- &--C {
- @include set-svgs-color($color-warning);
- }
-
- &--A {
- @include set-svgs-color($color-a);
- margin-top: auto;
- }
-
- &--B {
- @include set-svgs-color($color-success);
- }
-
- &--Start {
- @include set-svgs-color($color-error);
- }
-}
-
-.input-viz__Z {
- @include set-svgs-color($color-warning);
- @include set-sizes(136);
-}
-
-$dpad-size: 192;
-
-.input-viz.input-viz__dpad {
- @include set-svgs-color($color-text);
- @include set-sizes($dpad-size);
- position: relative;
-}
-
-$stick-size: 200;
-
-.input-config__visual-stick {
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
- width: space($stick-size);
- height: space($stick-size);
- border-radius: space(math.div($stick-size, 2));
- background-color: $color-white-a5;
-}
-
-.input-viz__dpad-split,
-.input-viz__stick-split {
- @include inset-block(0);
- display: flex;
- width: 100%;
- height: 100%;
-
- &--vertical {
- flex-direction: column;
- align-items: center;
- justify-content: space-between;
- }
-
- &--horizontal {
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- }
-
- > div {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- }
-}
-
-.input-viz__dpad-split > div {
- width: space(math.div($dpad-size, 3));
- height: space(math.div($dpad-size, 3));
-}
-
-.input-viz__stick-split > div {
- width: space(math.div($stick-size, 3));
- height: space(math.div($stick-size, 3));
-}
-
-.input-viz__dpad-arrow {
- $edge-dist: space(4);
- position: absolute;
- width: space(60);
- height: space(60);
-
- &--up {
- top: $edge-dist;
- margin: 0 auto;
- }
-
- &--down {
- bottom: $edge-dist;
- margin: 0 auto;
- transform: rotate(180deg);
- }
-
- &--left {
- left: $edge-dist;
- margin: auto 0;
- transform: rotate(-90deg);
- }
-
- &--right {
- right: $edge-dist;
- margin: auto 0;
- transform: rotate(90deg);
- }
-}
-
-.input-viz__R {
- @include set-svgs-color($color-white);
- @include set-sizes(96);
-}
-
-.input-viz__L {
- @include set-svgs-color($color-secondary);
- @include set-sizes(136);
-}
-
-.input-config__c-buttons {
- position: relative;
- width: space(76 + 76 + 56);
- height: space(76 + 56);
-
- &-lr, &-du {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &-lr {
- flex-direction: row;
- align-items: flex-start;
- justify-content: space-between;
- }
-
- &-du {
- flex-direction: column-reverse;
- align-items: center;
- justify-content: space-between;
- }
-
- .input-viz {
- &[visual-input="C_UP"] {
- margin-top: space(-32);
- }
- }
-}
-
-.input-config__main-buttons {
- display: flex;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: space(268);
- // WORKAROUND FIX: prevents RMLui assert error
- min-width: 1dp;
- height: space(128);
- margin-right: space(10);
-}
diff --git a/assets/scss/styles/components/Launcher.scss b/assets/scss/styles/components/Launcher.scss
deleted file mode 100644
index 89e4fce..0000000
--- a/assets/scss/styles/components/Launcher.scss
+++ /dev/null
@@ -1,108 +0,0 @@
-
-// TODO: Affect all elements with launcher fade-in
-// @keyframes fade-launcher-in {
-// 0% {
-// opacity: 0;
-// }
-// to {
-// opacity: 1;
-// }
-// }
-
-.launcher {
- display: block;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- background-color: $color-background-1;
-}
-
-.launcher__vertical-split {
- display: flex;
- position: absolute;
- top: 0;
- right: 50%;
- bottom: 0;
- left: 0;
- flex-direction: column;
- align-items: flex-start;
- justify-content: space-between;
-
- &--right {
- right: 0;
- left: 50%;
- align-items: flex-end;
- }
-}
-
-
-@keyframes slide-mm-bg-over {
- 0% {
- transform: translateX(space(100));
- }
-
- 100% {
- transform: translateX(space(0));
- }
-}
-
-.launcher__background-wrapper {
- display: flex;
- position: absolute;
- top: -55vw;
- right: -100%;
- bottom: -50vw;
- left: -70vw;
- align-items: center;
- justify-content: flex-start;
- transform: translateX(space(0));
- animation: 25s cubic-out 1 slide-mm-bg-over;
-}
-
-@keyframes fade-mm-in {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 0.1;
- }
-}
-
-.launcher__background-mm {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- width: auto;
- height: 100%;
- animation: 2.5s cubic-in-out 1 fade-mm-in;
- opacity: 0.1;
-}
-
-.launcher__title-quadrant {
- flex: 1 1 auto;
- width: auto;
- height: auto;
- padding-top: space(96);
- padding-left: space(96);
-
- &--right {
- padding-right: space(96);
- padding-left: 0;
- }
-}
-
-.launcher__content-quadrant {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-end;
- width: 100%;
- height: auto;
- padding: space(32);
-}
diff --git a/assets/scss/styles/components/MenuListItem.scss b/assets/scss/styles/components/MenuListItem.scss
deleted file mode 100644
index 657f0ef..0000000
--- a/assets/scss/styles/components/MenuListItem.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- Example layout:
-
- - Variants:
- .menu-list-item--right (align to right side)
- - Optional:
- - Coming Soon™
-
-*/
-
-.menu-list-item {
- @include set-color($color-text-dim);
- display: flex;
- flex-direction: row;
- align-items: center;
- width: 100%;
- height: auto;
- padding: space(16);
- border-radius: $border-radius-sm;
- background-color: rgba(0, 0, 0, 0);
- cursor: pointer;
-
- &--right {
- flex-direction: row-reverse;
- align-content: flex-end;
-
- .menu-list-item__bullet {
- margin-left: space(12);
- opacity: 1;
- }
-
- &.menu-list-item:focus:not(:disabled, [disabled]),
- &.menu-list-item:hover:not(:disabled, [disabled]) {
- decorator: $primary-rl-fade;
- }
- }
-
- &:focus:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-primary);
- decorator: $primary-lr-fade;
-
- .menu-list-item__bullet {
- opacity: 1;
- }
- }
-
- &:not(:disabled, [disabled]) {
- @extend %nav-all;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- tab-index: none;
- cursor: default;
- }
-
-}
-
-.menu-list-item__label {
- @extend %label-lg;
-}
-
-.menu-list-item__bullet {
- margin-right: space(12);
- opacity: 0;
-}
diff --git a/assets/scss/styles/components/Prompt.scss b/assets/scss/styles/components/Prompt.scss
deleted file mode 100644
index d7b4a1d..0000000
--- a/assets/scss/styles/components/Prompt.scss
+++ /dev/null
@@ -1,70 +0,0 @@
-@use 'sass:math';
-
-$prompt-space: 24;
-
-.prompt {
- &__overlay {
- background-color: $color-bg-overlay;
- pointer-events: auto;
- }
-
- &__overlay,
- &__content-wrapper {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &__content-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
- }
-
- &__content {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space(700);
- height: auto;
- margin: auto;
- border-width: $border-width-thickness;
- border-radius: $border-radius-modal;
- border-color: $color-border;
- background: $color-modal-overlay;
-
- h3, p {
- margin: space($prompt-space);
- }
-
- p {
- margin-top: 0;
- }
- }
-
- &__controls {
- display: flex;
- flex-direction: row;
- justify-content: center;
- padding: space($prompt-space) space(math.div($prompt-space, 2));
- border-top-width: $border-width-thickness;
- border-top-color: $color-border-soft;
-
- .button {
- min-width: space(math.div(700, 3));
- margin: 0 space(math.div($prompt-space, 2));
- text-align: center;
- nav-up: none;
- nav-down: none;
- }
- }
-}
diff --git a/assets/scss/styles/components/SubtitleTitle.scss b/assets/scss/styles/components/SubtitleTitle.scss
deleted file mode 100644
index c04def6..0000000
--- a/assets/scss/styles/components/SubtitleTitle.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Example layout:
-
-
- - Variants:
- .subtitle-title--right (align to right side)
- - Optional:
- - Coming Soon™
-
-*/
-
-.subtitle-title {
- display: block;
- position: relative;
- flex-direction: column;
- align-content: flex-start;
- align-items: flex-start;
- width: auto;
- height: auto;
- padding: 0;
- background-color: rgba(0, 0, 0, 0);
- color: $color-text-dim;
- text-align: left;
- cursor: pointer;
-
- &--right {
- align-content: flex-end;
- }
-
- &--right, &--right > * {
- text-align: right;
- }
-
- &[selected] {
- color: $color-text;
- cursor: default;
- }
-
- &:focus:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled], [selected]) {
- color: $color-primary;
- }
-
- &:not(:disabled, [disabled]) {
- @extend %nav-all;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- cursor: default;
- tab-index: none;
- }
-
- h3 {
- margin-bottom: space(6);
- }
-
- h1 {
- margin-top: space(6);
- }
-
- &__disclaimer {
- @extend %label-sm;
-
- margin-top: space(16);
- }
-}
diff --git a/assets/scss/styles/components/Tabs.scss b/assets/scss/styles/components/Tabs.scss
deleted file mode 100644
index 53f09dc..0000000
--- a/assets/scss/styles/components/Tabs.scss
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Example:
-
- Graphics
-
-
-*/
-
-.tabs tabs {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
-}
-
-.tab {
- @extend %nav-all;
- @extend %header-3;
- display: block;
- position: relative;
- margin: 0;
- padding: space(20) space(24);
- opacity: 0.9;
- background-color: rgba(0,0,0,0);
- color: $color-text-inactive;
-
- &:selected {
- color: $color-text;
-
- .tab__indicator {
- background-color: $color-border-solid;
- }
-
- &:hover {
- cursor: default;
- }
- }
-
- .rmlui-window:not([mouse-active]) &:focus {
- transition: none;
- animation: $focus-anim-border;
-
- &:selected .tab__indicator {
- animation: $focus-anim-bg;
- }
- }
-
- &:focus, &:hover {
- opacity: 1;
- color: $color-text;
- cursor: pointer;
- }
-}
-
-.tab__indicator {
- position: absolute;
- right: 0;
- bottom: 2dp;
- left: 0;
- height: 2dp;
- background-color: rgba(0, 0, 0, 0);
-}
diff --git a/assets/scss/styles/components/Toggle.scss b/assets/scss/styles/components/Toggle.scss
deleted file mode 100644
index 065f92d..0000000
--- a/assets/scss/styles/components/Toggle.scss
+++ /dev/null
@@ -1,97 +0,0 @@
-@use "sass:math";
-
-$toggle-width: 162;
-$toggle-height: 72;
-
-$toggle-floater-width: 80;
-$toggle-floater-height: 64;
-$toggle-floater-margin: 4;
-$toggle-checked-left-offset: $toggle-width - $toggle-floater-margin - $toggle-floater-width;
-
-.toggle {
- @extend %nav-all;
- @include trans-colors-opa;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: space($toggle-width);
- height: space($toggle-height);
- border-radius: space(math.div($toggle-height, 2));
- opacity: 0.9;
- background: $color-transparent;
- cursor: pointer;
-
- &:hover, &:focus-visible, &:focus {
- opacity: 1;
- background-color: $color-secondary-a30;
- }
-
- &:active {
- opacity: 1;
- background-color: $color-secondary-a5;
- }
-
- .toggle__border {
- @include inner-border-block($color-secondary-l);
- border-radius: space(math.div($toggle-height, 2));
- }
-
- .toggle__floater {
- position: absolute;
- top: 50%;
- left: space($toggle-floater-margin);
- width: space($toggle-floater-width);
- height: space($toggle-floater-height);
- transform: translateY(-50%);
- border-radius: space(math.div($toggle-floater-height, 2));
- background: $color-secondary-d;
- }
-
- &--checked {
- .toggle__floater {
- left: space($toggle-checked-left-offset);
- }
-
- .toggle__icon {
- &.toggle__icon--left {
- opacity: 0.9;
- color: $color-secondary-l;
- }
-
- &.toggle__icon--right {
- opacity: 1.0;
- color: $color-text;
- }
- }
- }
-}
-
-.toggle__icons {
- display: flex;
- position: absolute;
- top: 50%;
- right: space(16);
- left: space(16);
- align-items: center;
- justify-content: space-between;
- height: space(56);
- transform: translateY(-50%);
-}
-
-.toggle__icon {
- @extend %prompt-font-lg;
- @include trans-colors;
- display: flex;
- align-items: center;
- justify-content: center;
- width: space(56);
- height: space(56);
- color: $color-text;
-
- &--right {
- opacity: 1;
- color: $color-secondary-l;
- }
-}
diff --git a/assets/scss/styles/components/_components.scss b/assets/scss/styles/components/_components.scss
deleted file mode 100644
index b4a936e..0000000
--- a/assets/scss/styles/components/_components.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-@import "./CenteredPage";
-@import "./ControlOption";
-@import "./Tabs";
-@import "./Config";
-@import "./ConfigGroup";
-@import "./ConfigOption";
-@import "./ConfigDescription";
-@import "./InputConfig";
-@import "./Button";
-@import "./IconButton";
-@import "./Launcher";
-@import "./MenuListItem";
-@import "./SubtitleTitle";
-@import "./Toggle";
-@import "./BottomLeft";
-@import "./Prompt";
diff --git a/assets/scss/styles/functions/_spacing.scss b/assets/scss/styles/functions/_spacing.scss
deleted file mode 100644
index 437a7ac..0000000
--- a/assets/scss/styles/functions/_spacing.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-
-@function space($amt) {
- @return #{$amt}dp;
-}
diff --git a/assets/scss/styles/global.scss b/assets/scss/styles/global.scss
deleted file mode 100644
index 2e98925..0000000
--- a/assets/scss/styles/global.scss
+++ /dev/null
@@ -1,132 +0,0 @@
-@import "./base";
-@import "./globals/old";
-@import "./globals/scrollbars";
-@import "./components/components";
-@import "./pages/pages";
-
-$font-size: 20dp;
-
-body
-{
- @extend %body;
- box-sizing: border-box;
- color: $color-text;
- font-family: $font-stack;
-}
-
-.rmlui-window {
- opacity: 1;
-
- &--hidden {
- opacity: 0;
- }
-
- &:not([mouse-active]) {
- pointer-events: none;
- }
-}
-
-.nav-vert {
- @extend %nav-vert;
-}
-
-.nav-horiz {
- @extend %nav-horiz;
-}
-
-.nav-dir {
- @extend %nav-dir;
-}
-
-.nav-foc {
- @extend %nav-foc;
-}
-
-.nav-all {
- @extend %nav-all;
-}
-
-*, *:before, *:after {
- box-sizing: border-box;
-}
-
-h1 {
- @extend %header-1;
-}
-
-h2 {
- @extend %header-2;
-}
-
-h3 {
- @extend %header-3;
-}
-
-.label-lg {
- @extend %label-lg;
-}
-
-.label-md {
- @extend %label-md;
-}
-
-.label-sm {
- @extend %label-sm;
-}
-
-.prompt-font {
- @extend %prompt-font;
-}
-
-.prompt-font-sm {
- @extend %prompt-font-sm;
-}
-
-button {
- background-color: $color-primary-d;
-}
-
-@keyframes blue-pulse {
- 0% {
- color: $color-secondary;
- }
-
- 50% {
- color: $color-secondary-l;
- }
-
- 100% {
- color: $color-secondary;
- }
-}
-
-@keyframes blue-pulse-with-border {
- 0% {
- border-color: $color-secondary;
- color: $color-secondary;
- }
-
- 50% {
- border-color: $color-secondary-l;
- color: $color-secondary-l;
- }
-
- 100% {
- border-color: $color-secondary;
- color: $color-secondary;
- }
-}
-
-@keyframes blue-pulse-background {
- 0% {
- background-color: $color-secondary;
- }
-
- 50% {
- background-color: $color-secondary-l;
- }
-
- 100% {
- background-color: $color-secondary;
- }
-}
diff --git a/assets/scss/styles/globals/_old.scss b/assets/scss/styles/globals/_old.scss
deleted file mode 100644
index 20351d9..0000000
--- a/assets/scss/styles/globals/_old.scss
+++ /dev/null
@@ -1,212 +0,0 @@
-/* stylelint-disable color-no-hex */
-/* stylelint-disable selector-max-id */
-
-* {
- box-sizing:border-box;
-}
-
-hr {
- display:block;
- padding:1.5dp;
- background: $color-background-1;
-}
-
-body {
- color: #fff;
- font-family: chiaro;
- font-size: 20dp;
- font-style: normal;
- font-weight: normal
-}
-
-/* div {
- focus:none;
- tab-index:none;
-} */
-
-div#window {
- position: relative;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- border-color: $color-border;
- background-color: $color-background-2;
-}
-
-div#content {
- z-index: 2;
- width: auto;
- height: 100%;
- overflow: hidden auto;
- text-align: center
-}
-
-p {
- text-align: left;
-}
-
-input.submit {
- margin-left: 0
-}
-
-
-input.text,
-input.password {
- box-sizing: border-box;
- height: 31dp;
- padding: 11dp 10dp 0;
- text-align: left;
- cursor: text
-}
-
-textarea {
- padding: 14dp 12dp 10dp;
- text-align: left;
- cursor: text
-}
-
-input.text,
-input.password,
-select,
-textarea {
- /* color: #333; */
-
- /* font-size: 13dp */
- height: auto;
-}
-
-table input.text {
- box-sizing: border-box;
- width: 100%;
- height: auto;
-
- /* height: 18dp; */
- margin: 0;
- border-width: $border-width-thickness;
- border-color: #000;
- background-color: #fff;
- font-size: 15dp;
-
- /* padding: 0 5dp; */
- line-height: 1;
- decorator: none;
-
- /* vertical-align: center; */
-}
-
-select {
- // display: inline-block;
- // /* width: 175dp; */
- // /* height: 37dp; */
- // /* height: auto; */
- // text-align: left;
- // box-sizing:border-box;
- // /* padding: 4dp; */
- // vertical-align: center;
- // padding: 4dp;
- // border-radius: 5dp;
- // background-color: rgb(120, 120, 120);
- // width: 100%;
-}
-// select {
-// @extend %body;
-// display: flex;
-// align-items: center;
-// justify-content: flex-start;
-// box-sizing: border-box;
-// padding: space(16);
-// flex: 1 1 100%;
-// // width: auto;
-// height: space(1000);
-// border-radius: $border-radius-lg;
-// background-color: $color-white-a20;
-// }
-
-// select selectvalue {
-// height: auto;
-// /* padding: 4dp; */
-// /* margin-right: 30dp; */
-// /* height: 25dp; */
-// /* padding: 4dp; */
-// /* decorator: image(selectvalue) */
-// }
-
-// select:hover selectvalue {
-// /* margin-right: 30dp; */
-// /* height: 25dp; */
-// /* padding: 4dp; */
-// background-color: rgb(150, 150, 150);
-// /* decorator: image(selectvalue) */
-// }
-
-// select selectarrow {
-// /* width: 30dp; */
-// /* height: 37dp; */
-// /* decorator: image(selectarrow) */
-// /* background-color: black; */
-// /* appearance: none; */
-// }
-
-// select:hover selectarrow {
-// /* decorator: image(selectarrow-hover) */
-// }
-
-// select:active selectarrow,
-// select selectarrow:checked {
-// /* decorator: image(selectarrow-active) */
-// }
-
-// select selectbox {
-// /* margin-left: 1dp; */
-// /* margin-top: -7dp; */
-// /* margin-bottom: -10dp; */
-// /* width: 162dp; */
-// /* padding: 1dp 4dp 4dp 4dp */
-// }
-
-// select selectbox,
-// tbody {
-// background-color: rgb(120,120,120);
-// /* decorator: tiled-box(selectbox-tl, selectbox-t, selectbox-tr, selectbox-l, selectbox-c, auto, selectbox-bl, selectbox-b, selectbox-br) */
-// }
-
-// select selectbox option {
-// width: auto;
-// background-color: rgb(120, 120, 120)
-// }
-
-// select selectbox option:nth-child(even),
-// tr:nth-child(even) {
-// background-color: rgb(100, 100, 100)
-// }
-
-// select selectbox option:checked {
-// font-weight:bold;
-// color:rgb(255,255,255);
-// }
-
-// select selectbox option:hover {
-// background: rgb(150,150,150)
-// }
-
-input.radio {
- flex: 0;
- width:0dp;
- nav-up:auto;
- nav-right:auto;
- nav-down:auto;
- nav-left:auto;
- tab-index:auto;
- focus:auto;
-}
-
-input.checkbox {
- width: space(20);
- height: space(20);
- nav-up:auto;
- nav-right:auto;
- nav-down:auto;
- nav-left:auto;
- tab-index:auto;
- focus:auto;
-}
diff --git a/assets/scss/styles/globals/_scrollbars.scss b/assets/scss/styles/globals/_scrollbars.scss
deleted file mode 100644
index 375c164..0000000
--- a/assets/scss/styles/globals/_scrollbars.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-@use 'sass:math';
-
-$scrollbar-width: 12;
-
-@mixin _set-scroll-size($size-key) {
- #{$size-key}: space($scrollbar-width);
-
- slidertrack {
- #{$size-key}: space($scrollbar-width);
- }
-
- sliderbar {
- #{$size-key}: space($scrollbar-width);
- }
-}
-
-scrollbarvertical,scrollbarhorizontal {
- margin: 0;
- border: 0;
-
- slidertrack {
- background: $color-primary-l;
- opacity: 0.05;
- }
-
- sliderbar {
- border-radius: space(math.div($scrollbar-width, 2) - 1);
- background: $color-primary-l;
- opacity: 0.1;
-
- &:hover:not(:active) {
- opacity: 0.2;
- }
-
- &:active {
- opacity: 0.3;
- }
- }
-
- sliderarrowdec, sliderarrowinc {
- width: 0;
- height: 0;
- }
-}
-
-scrollbarvertical {
- @include _set-scroll-size(width);
-}
-
-scrollbarhorizontal {
- @include _set-scroll-size(height);
-}
diff --git a/assets/scss/styles/mixins/_helpers.scss b/assets/scss/styles/mixins/_helpers.scss
deleted file mode 100644
index 9759630..0000000
--- a/assets/scss/styles/mixins/_helpers.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-
-%nav-vert {
- nav-up: auto;
- nav-down: auto;
-}
-
-%nav-horiz {
- nav-right: auto;
- nav-left: auto;
-}
-
-%nav-dir {
- @extend %nav-vert;
- @extend %nav-horiz;
-}
-
-%nav-foc {
- focus: auto;
- tab-index: auto;
-}
-
-%nav-all {
- @extend %nav-dir;
- @extend %nav-foc;
-}
-
-@mixin set-svgs-color($col) {
- svg {
- image-color: $col;
- }
-}
-
-/*
-@include set-color(COLOR);
-*/
-@mixin set-color($col) {
- @include set-svgs-color($col);
- color: $col;
-}
diff --git a/assets/scss/styles/mixins/_transitions.scss b/assets/scss/styles/mixins/_transitions.scss
deleted file mode 100644
index 06c8677..0000000
--- a/assets/scss/styles/mixins/_transitions.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-
-/*
-@include trans-colors;
-*/
-@mixin trans-colors {
- transition: color $transition-quick, background-color $transition-quick;
-}
-
-/*
-@include trans-colors-opa;
-*/
-@mixin trans-colors-opa {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick;
-}
-
-/*
-@include trans-colors-svg;
-*/
-@mixin trans-colors-svg {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick;
-
- svg {
- transition: image-color $transition-quick, background-color $transition-quick;
- }
-}
-
-/*
-@include trans-colors-border;
-*/
-@mixin trans-colors-border {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick, border-color $transition-quick;
-
- svg {
- transition: image-color $transition-quick, background-color $transition-quick;
- }
-}
diff --git a/assets/scss/styles/mixins/_typography.scss b/assets/scss/styles/mixins/_typography.scss
deleted file mode 100644
index a638b1a..0000000
--- a/assets/scss/styles/mixins/_typography.scss
+++ /dev/null
@@ -1,83 +0,0 @@
-
-$font-stack: chiaro;
-
-@mixin set-font-sizing($sz, $spacing) {
- // font-family: $font-stack;
- $sz-add: $sz + 4;
- font-size: space($sz-add);
- letter-spacing: space($sz-add * $spacing);
- line-height: space($sz-add);
-}
-
-%header-1 {
- @include set-font-sizing(64, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%header-2 {
- @include set-font-sizing(48, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%header-3 {
- @include set-font-sizing(32, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-lg {
- @include set-font-sizing(32, 0.11);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-md {
- @include set-font-sizing(24, 0.11);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-sm {
- @include set-font-sizing(16, 0.14);
- font-style: normal;
- font-weight: 700;
- text-transform: uppercase;
-}
-
-%label-xs {
- @include set-font-sizing(14, 0.14);
- font-style: normal;
- font-weight: 400;
-}
-
-%body {
- @include set-font-sizing(16, 0.0);
- font-style: normal;
- font-weight: 400;
-}
-
-%prompt-font-lg {
- font-family: promptfont;
- font-size: space(56);
- font-style: normal;
- font-weight: 400;
- line-height: space(56);
-}
-
-%prompt-font {
- font-family: promptfont;
- font-size: space(40);
- font-style: normal;
- font-weight: 400;
- line-height: space(40);
-}
-
-%prompt-font-sm {
- font-family: promptfont;
- font-size: space(32);
- font-style: normal;
- font-weight: 400;
- line-height: space(32);
-}
diff --git a/assets/scss/styles/pages/_pages.scss b/assets/scss/styles/pages/_pages.scss
deleted file mode 100644
index 16e2e18..0000000
--- a/assets/scss/styles/pages/_pages.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "./config/config";
diff --git a/assets/scss/styles/pages/config/_config.scss b/assets/scss/styles/pages/config/_config.scss
deleted file mode 100644
index c4e69bc..0000000
--- a/assets/scss/styles/pages/config/_config.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "./debug";
diff --git a/assets/scss/styles/pages/config/debug.scss b/assets/scss/styles/pages/config/debug.scss
deleted file mode 100644
index 997bfc0..0000000
--- a/assets/scss/styles/pages/config/debug.scss
+++ /dev/null
@@ -1,178 +0,0 @@
-
-.config-debug {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- padding: space(8);
-}
-
-.config-debug__scroll {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.config-debug-option {
- @include set-color($color-text-dim);
- @include trans-colors-svg;
- @include border-bottom($color-border-soft);
- display: block;
- position: relative;
- flex-direction: column;
- width: 100%;
- height: auto;
- padding: space(12) space(4);
- background-color: rgba(0, 0, 0, 0);
-
- &:focus:not(:disabled, [disabled]),
- &:focus-visible:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-text);
- background-color: $color-bg-overlay;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- }
-
- .icon-button {
- margin-left: space(8);
- }
-}
-
-.config-debug__option-split {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-}
-
-.config-debug-option__label {
- @extend %label-md;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- padding: space(4) space(16) space(12);
- width: auto;
- height: auto;
- white-space: nowrap;
-}
-
-.config-debug__option-controls {
- display: block;
- position: relative;
- flex: 1 1 auto;
- height: auto;
- width: auto;
- max-width: space(800);
- padding: 0 space(12);
-}
-
-.config-debug__option-trigger {
- flex: 1 1 auto;
-}
-
-.config-debug__select-wrapper {
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- flex: 1 1 100%;
- width: auto;
- max-width: space(800);
- height: auto;
- padding: space(4);
-
- .config-debug__select-label {
- @extend %label-sm;
- padding-right: space(16);
- flex: auto;
- width: space(196);
-
- > div {
- display: inline;
- width: auto;
- height: auto;
- }
- }
-
- input {
- @extend %body;
- @extend %nav-all;
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: space(20);
- margin: auto 0;
- }
-
- select {
- @extend %body;
- @extend %nav-all;
- @include trans-colors-border;
- @include border($color-white-a50);
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: space(48);
- border-radius: $border-radius-md;
- background-color: $color-white-a5;
- cursor: pointer;
-
- align-items: center;
- justify-content: flex-start;
- padding: space(14);
-
- &:hover, &:focus {
- @include border($color-white-a80);
- background-color: $color-white-a20;
- }
-
- selectvalue {
- display: inline;
- margin: auto 0;
- height: auto;
- }
-
- selectbox {
- @include border($color-white-a80);
- background-color: $color-background-3;
- padding: space(4) 0;
- margin-top: space(2);
- border-radius: $border-radius-md;
-
- option {
- @extend %nav-all;
- @include trans-colors;
- padding: space(8) space(12);
- background-color: $color-transparent;
- color: $color-text-dim;
- font-weight: 400;
-
- &:hover, &:focus {
- background-color: $color-white-a20;
- }
-
- &:hover:not(:checked) {
- cursor: pointer;
- }
-
- &:checked {
- color: $color-white;
- background-color: $color-white-a5;
- }
- }
- }
- }
-}
diff --git a/assets/scss/styles/vars/_animations.scss b/assets/scss/styles/vars/_animations.scss
deleted file mode 100644
index 9315f4d..0000000
--- a/assets/scss/styles/vars/_animations.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-
-$focus-anim: blue-pulse-with-border 0.75s infinite;
-$focus-anim-border: blue-pulse 0.75s infinite;
-$focus-anim-bg: blue-pulse-background 0.75s infinite;
diff --git a/assets/scss/styles/vars/_borders.scss b/assets/scss/styles/vars/_borders.scss
deleted file mode 100644
index 5088285..0000000
--- a/assets/scss/styles/vars/_borders.scss
+++ /dev/null
@@ -1,42 +0,0 @@
-
-$border-radius-sm: 8dp;
-$border-radius-md: 12dp;
-// modals/pages
-$border-radius-lg: 16dp;
-
-$border-radius-modal: $border-radius-lg;
-
-$border-width-thickness-num: 1.1;
-// $border-width-thickness-num: 1.5;
-$border-width-thickness: space($border-width-thickness-num);
-
-@mixin border($col: $color-border) {
- border-width: $border-width-thickness;
- border-color: $col;
-}
-
-@mixin border-top($col: $color-border) {
- border-top-width: $border-width-thickness;
- border-top-color: $col;
-}
-
-@mixin border-bottom($col: $color-border) {
- border-bottom-width: $border-width-thickness;
- border-bottom-color: $col;
-}
-
-@mixin inset-block($inset-amt) {
- position: absolute;
- top: $inset-amt;
- right: $inset-amt;
- bottom: $inset-amt;
- left: $inset-amt;
-}
-
-// add this to a child of the container that needs a border.
-// parent must have `position: relative`
-@mixin inner-border-block($col: $color-border) {
- @include inset-block($border-width-thickness);
- @include border($col);
- display: block;
-}
diff --git a/assets/scss/styles/vars/_colors.scss b/assets/scss/styles/vars/_colors.scss
deleted file mode 100644
index 0b5cfd7..0000000
--- a/assets/scss/styles/vars/_colors.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-/* stylelint-disable color-no-hex, color-hex-length */
-
-$color-background-1: #08070D;
-$color-background-2: #121018;
-$color-background-3: #191622;
-$color-bg-overlay: rgba(190, 184, 219, 0.1000);
-$color-modal-overlay: rgba(8, 7, 13, 0.9000);
-$color-bg-shadow: rgba(0, 0, 0, 0.3500);
-$color-bg-shadow-2: rgba(8, 7, 13, 0.7200);
-$color-text: #F2F2F2;
-$color-text-dim: #CCCCCC;
-$color-text-inactive: rgba(255, 255, 255, 0.6000);
-$color-primary: #B97DF2;
-$color-primary-l: #DABAF7;
-$color-primary-d: #7A2AC6;
-$color-primary-a5: rgba(185, 125, 242, 0.0500);
-$color-primary-a20: rgba(185, 125, 242, 0.2000);
-$color-primary-a30: rgba(185, 125, 242, 0.3000);
-$color-primary-a50: rgba(185, 125, 242, 0.5000);
-$color-primary-a80: rgba(185, 125, 242, 0.8000);
-$color-secondary: #17D6E8;
-$color-secondary-l: #A2EFF6;
-$color-secondary-d: #25A1AD;
-$color-secondary-a5: rgba(23, 214, 232, 0.0500);
-$color-secondary-a20: rgba(23, 214, 232, 0.2000);
-$color-secondary-a30: rgba(23, 214, 232, 0.3000);
-$color-secondary-a50: rgba(23, 214, 232, 0.5000);
-$color-secondary-a80: rgba(23, 214, 232, 0.8000);
-$color-warning: #E9CD35;
-$color-warning-l: #F9E57C;
-$color-warning-d: #C5AA16;
-$color-warning-a5: rgba(233, 205, 53, 0.0500);
-$color-warning-a20: rgba(233, 205, 53, 0.2000);
-$color-warning-a30: rgba(233, 205, 53, 0.3000);
-$color-warning-a50: rgba(233, 205, 53, 0.5000);
-$color-warning-a80: rgba(233, 205, 53, 0.8000);
-$color-error: #F86039;
-$color-error-l: #FE8667;
-$color-error-d: #B23919;
-$color-error-a5: rgba(248, 96, 57, 0.0500);
-$color-error-a20: rgba(248, 96, 57, 0.2000);
-$color-error-a30: rgba(248, 96, 57, 0.3000);
-$color-error-a50: rgba(248, 96, 57, 0.5000);
-$color-error-a80: rgba(248, 96, 57, 0.8000);
-$color-success: #45D043;
-$color-success-l: #AAEAA9;
-$color-success-d: #2CA72A;
-$color-success-a5: rgba(69, 208, 67, 0.0500);
-$color-success-a20: rgba(69, 208, 67, 0.2000);
-$color-success-a30: rgba(69, 208, 67, 0.3000);
-$color-success-a50: rgba(69, 208, 67, 0.5000);
-$color-success-a80: rgba(69, 208, 67, 0.8000);
-$color-border: rgba(255, 255, 255, 0.2000);
-$color-border-soft: rgba(255, 255, 255, 0.1000);
-$color-border-hard: rgba(255, 255, 255, 0.3000);
-$color-border-solid: rgba(255, 255, 255, 0.6000);
-$color-transparent: rgba(0, 0, 0, 0.0000);
-$color-a: #3333FF;
-$color-a-l: #B2B2FF;
-$color-a-d: #2020AC;
-$color-a-a5: rgba(51, 51, 255, 0.0500);
-$color-a-a20: rgba(51, 51, 255, 0.2000);
-$color-a-a30: rgba(51, 51, 255, 0.3000);
-$color-a-a50: rgba(51, 51, 255, 0.5000);
-$color-a-a80: rgba(51, 51, 255, 0.8000);
-$color-white: #FFFFFF;
-$color-white-a5: rgba(255, 255, 255, 0.0500);
-$color-white-a20: rgba(255, 255, 255, 0.2000);
-$color-white-a30: rgba(255, 255, 255, 0.3000);
-$color-white-a50: rgba(255, 255, 255, 0.5000);
-$color-white-a80: rgba(255, 255, 255, 0.8000);
diff --git a/assets/scss/styles/vars/_gradients.scss b/assets/scss/styles/vars/_gradients.scss
deleted file mode 100644
index 1cdebd5..0000000
--- a/assets/scss/styles/vars/_gradients.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-
-// Not supported yet, need to use decorator: gradient atm
-// $primary-lr-fade: linear-gradient(90deg, rgba($color-primary-l, 0.08) 0%, rgba($color-primary-l, 0.00) 100%);
-// $primary-rl-fade: linear-gradient(90deg, rgba($color-primary-l, 0.00) 0%, rgba($color-primary-l, 0.08) 100%);
-
-$primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00);
-$primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14);
diff --git a/assets/scss/styles/vars/_spacing.scss b/assets/scss/styles/vars/_spacing.scss
deleted file mode 100644
index b61c8e1..0000000
--- a/assets/scss/styles/vars/_spacing.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@use 'sass:math';
-
-// $page-margin: 32;
-$page-margin: 64;
-$base-height: 1080;
-$base-modal-height: $base-height - ($page-margin * 2);
-$base-modal-max-width: math.div($base-modal-height * 16, 9);
diff --git a/assets/scss/styles/vars/_transitions.scss b/assets/scss/styles/vars/_transitions.scss
deleted file mode 100644
index 0586d88..0000000
--- a/assets/scss/styles/vars/_transitions.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-// see: lib/RmlUi/Source/Core/PropertyParserAnimation.cpp
-$transition-quick: 0.05s linear-in-out;
-// $transition-quick: 0.033s linear-in-out;
diff --git a/icons/Arrow.svg b/icons/Arrow.svg
new file mode 100644
index 0000000..f1c5219
--- /dev/null
+++ b/icons/Arrow.svg
@@ -0,0 +1,5 @@
+
diff --git a/icons/Cont.svg b/icons/Cont.svg
new file mode 100644
index 0000000..5959613
--- /dev/null
+++ b/icons/Cont.svg
@@ -0,0 +1,3 @@
+
diff --git a/icons/Keyboard.svg b/icons/Keyboard.svg
new file mode 100644
index 0000000..880ceb0
--- /dev/null
+++ b/icons/Keyboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/icons/Plus.svg b/icons/Plus.svg
new file mode 100644
index 0000000..ca00c8f
--- /dev/null
+++ b/icons/Plus.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/icons/Quit.svg b/icons/Quit.svg
new file mode 100644
index 0000000..1713672
--- /dev/null
+++ b/icons/Quit.svg
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/icons/RecordBorder.svg b/icons/RecordBorder.svg
new file mode 100644
index 0000000..28d8eac
--- /dev/null
+++ b/icons/RecordBorder.svg
@@ -0,0 +1,3 @@
+
diff --git a/icons/Reset.svg b/icons/Reset.svg
new file mode 100644
index 0000000..90dba9b
--- /dev/null
+++ b/icons/Reset.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/icons/Trash.svg b/icons/Trash.svg
new file mode 100644
index 0000000..6bb569e
--- /dev/null
+++ b/icons/Trash.svg
@@ -0,0 +1,8 @@
+
diff --git a/icons/VizMap/ButtonLarge.svg b/icons/VizMap/ButtonLarge.svg
new file mode 100644
index 0000000..b6b9210
--- /dev/null
+++ b/icons/VizMap/ButtonLarge.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/icons/VizMap/ButtonMedium.svg b/icons/VizMap/ButtonMedium.svg
new file mode 100644
index 0000000..263cf48
--- /dev/null
+++ b/icons/VizMap/ButtonMedium.svg
@@ -0,0 +1,4 @@
+
diff --git a/icons/VizMap/ButtonSmall.svg b/icons/VizMap/ButtonSmall.svg
new file mode 100644
index 0000000..4874ced
--- /dev/null
+++ b/icons/VizMap/ButtonSmall.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/icons/VizMap/DPad.svg b/icons/VizMap/DPad.svg
new file mode 100644
index 0000000..20a0517
--- /dev/null
+++ b/icons/VizMap/DPad.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/icons/VizMap/DPadArrow.svg b/icons/VizMap/DPadArrow.svg
new file mode 100644
index 0000000..3fbc085
--- /dev/null
+++ b/icons/VizMap/DPadArrow.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/icons/VizMap/Map.svg b/icons/VizMap/Map.svg
new file mode 100644
index 0000000..9a5fde4
--- /dev/null
+++ b/icons/VizMap/Map.svg
@@ -0,0 +1,4 @@
+
diff --git a/icons/VizMap/Shield.svg b/icons/VizMap/Shield.svg
new file mode 100644
index 0000000..933bb07
--- /dev/null
+++ b/icons/VizMap/Shield.svg
@@ -0,0 +1,19 @@
+
diff --git a/icons/VizMap/Target.svg b/icons/VizMap/Target.svg
new file mode 100644
index 0000000..f24a64e
--- /dev/null
+++ b/icons/VizMap/Target.svg
@@ -0,0 +1,46 @@
+
+
\ No newline at end of file
diff --git a/icons/X.svg b/icons/X.svg
new file mode 100644
index 0000000..8b35dbd
--- /dev/null
+++ b/icons/X.svg
@@ -0,0 +1,5 @@
+
+
\ No newline at end of file
diff --git a/include/zelda_config.h b/include/zelda_config.h
index 0078d22..8125752 100644
--- a/include/zelda_config.h
+++ b/include/zelda_config.h
@@ -4,97 +4,94 @@
#include
#include
#include "ultramodern/config.hpp"
-#include "recomp_input.h"
namespace zelda64 {
- constexpr std::u8string_view program_id = u8"Starfox64Recompiled";
- constexpr std::string_view program_name = "Starfox 64: Recompiled";
+ inline const std::u8string program_id = u8"Starfox64Recompiled";
+ inline const std::string program_name = "Starfox 64: Recompiled";
+
+ namespace configkeys {
+ namespace general {
+ inline const std::string debug_mode = "debug_mode";
+ inline const std::string film_grain_mode = "film_grain_mode";
+ inline const std::string invert_y_axis = "invert_y_axis";
+ inline const std::string radio_comm_mode = "radio_comm_mode";
+ #if 0
+ inline const std::string autosave_mode = "autosave_mode";
+ inline const std::string camera_invert_mode = "camera_invert_mode";
+ inline const std::string analog_cam_mode = "analog_cam_mode";
+ inline const std::string analog_camera_invert_mode = "analog_camera_invert_mode";
+ #endif
+ }
+
+ namespace sound {
+ inline const std::string bgm_volume = "bgm_volume";
+ inline const std::string sfx_volume = "sfx_volume";
+ inline const std::string voice_volume = "voice_volume";
+ #if 0
+ inline const std::string low_health_beeps = "low_health_beeps";
+ #endif
+ }
+
+ namespace graphics {
+ }
+ }
// TODO: Move loading configs to the runtime once we have a way to allow per-project customization.
- void load_config();
- void save_config();
-
- void reset_input_bindings();
- void reset_cont_input_bindings();
- void reset_kb_input_bindings();
- void reset_single_input_binding(recomp::InputDevice device, recomp::GameInput input);
-
- std::filesystem::path get_app_folder_path();
+ void init_config();
bool get_debug_mode_enabled();
- void set_debug_mode_enabled(bool enabled);
+
+ enum class AutosaveMode {
+ Off,
+ On,
+ };
+
+ AutosaveMode get_autosave_mode();
enum class FilmGrainMode {
On,
- Off,
- OptionCount
+ Off
};
+
+ FilmGrainMode get_film_grain_mode();
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::FilmGrainMode, {
- {zelda64::FilmGrainMode::On, "On"},
- {zelda64::FilmGrainMode::Off, "Off"}
- });
-
- enum class TargetingMode {
- Switch,
- Hold,
- OptionCount
+ enum class RadioCommBoxMode {
+ Expand,
+ Original
};
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::TargetingMode, {
- {zelda64::TargetingMode::Switch, "Switch"},
- {zelda64::TargetingMode::Hold, "Hold"}
- });
-
- TargetingMode get_targeting_mode();
- void set_targeting_mode(TargetingMode mode);
-
- enum class AimInvertMode {
+
+ RadioCommBoxMode get_radio_comm_mode();
+
+ enum class InvertYAxisMode {
On,
- Off,
- OptionCount
+ Off
};
+
+ InvertYAxisMode get_invert_y_axis_mode();
- enum class RadioBoxMode {
- Expand,
- Original,
- OptionCount
+ enum class CameraInvertMode {
+ InvertNone,
+ InvertX,
+ InvertY,
+ InvertBoth
};
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::RadioBoxMode, {
- {zelda64::RadioBoxMode::Expand, "Expand"},
- {zelda64::RadioBoxMode::Original, "Original"}
- });
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AimInvertMode, {
- {zelda64::AimInvertMode::On, "On"},
- {zelda64::AimInvertMode::Off, "Off"},
- });
-
- RadioBoxMode get_radio_comm_box_mode();
- void set_radio_comm_box_mode(RadioBoxMode mode);
-
- AimInvertMode get_analog_camera_invert_mode();
- void set_analog_camera_invert_mode(AimInvertMode mode);
+
+ CameraInvertMode get_camera_invert_mode();
+ CameraInvertMode get_analog_camera_invert_mode();
enum class AnalogCamMode {
- On,
Off,
- OptionCount
+ On,
};
+
+ AnalogCamMode get_analog_cam_mode();
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AnalogCamMode, {
- {zelda64::AnalogCamMode::On, "On"},
- {zelda64::AnalogCamMode::Off, "Off"}
- });
-
- FilmGrainMode get_film_grain_mode();
- void set_film_grain_mode(FilmGrainMode mode);
-
- AimInvertMode get_invert_y_axis_mode();
- void set_invert_y_axis_mode(AimInvertMode mode);
-
- void open_quit_game_prompt();
+ #if 0
+ enum class LowHealthBeepsMode {
+ Off,
+ On,
+ };
+ #endif
};
#endif
diff --git a/include/zelda_debug.h b/include/zelda_debug.h
index 4c0743e..26552f4 100644
--- a/include/zelda_debug.h
+++ b/include/zelda_debug.h
@@ -5,6 +5,11 @@
#include
namespace zelda64 {
+ namespace debug {
+ inline const std::string tab_id = "debug";
+ inline const std::string tab_name = "Debug";
+ }
+
struct SceneWarps {
int index;
std::string name;
diff --git a/include/zelda_launcher.h b/include/zelda_launcher.h
new file mode 100644
index 0000000..f88f7ee
--- /dev/null
+++ b/include/zelda_launcher.h
@@ -0,0 +1,11 @@
+#ifndef __ZELDA_LAUNCHER_H__
+#define __ZELDA_LAUNCHER_H__
+
+#include "recompui/recompui.h"
+
+namespace zelda64 {
+ void launcher_animation_setup(recompui::LauncherMenu *menu);
+ void launcher_animation_update(recompui::LauncherMenu *menu);
+}
+
+#endif
diff --git a/lib/N64ModernRuntime b/lib/N64ModernRuntime
index 9ae9dbb..c515776 160000
--- a/lib/N64ModernRuntime
+++ b/lib/N64ModernRuntime
@@ -1 +1 @@
-Subproject commit 9ae9dbbe41cafcd6f425135c726aebe80777d682
+Subproject commit c515776f9238b4c1e9bd7ff6c7740b1ab1a3106b
diff --git a/lib/RecompFrontend b/lib/RecompFrontend
new file mode 160000
index 0000000..202af5f
--- /dev/null
+++ b/lib/RecompFrontend
@@ -0,0 +1 @@
+Subproject commit 202af5f2a5eb67ecb25fb1f691aec33d1077127b
diff --git a/lib/rt64 b/lib/rt64
index aa047b8..f0d8c9f 160000
--- a/lib/rt64
+++ b/lib/rt64
@@ -1 +1 @@
-Subproject commit aa047b8158034552466175b8e8554988caa18976
+Subproject commit f0d8c9f29b579a143744f76c222899dc82c12e81
diff --git a/patches/debug.h b/patches/debug.h
index 934998f..f3c2a9e 100644
--- a/patches/debug.h
+++ b/patches/debug.h
@@ -60,7 +60,7 @@
#define DEBUG_NO_COLLISION 0
#define DEBUG_BOSS_KILLER 0
#define DEBUG_ENDING 0
-#define DEBUG_VERSUS 0
+#define DEBUG_DISABLE_VERSUS 0
// AUDIO
#define DEBUG_AUDIO_LOCALIZATION 0
diff --git a/patches/input.h b/patches/input.h
index 6f61432..3a2427e 100644
--- a/patches/input.h
+++ b/patches/input.h
@@ -12,7 +12,7 @@ extern RecompCameraMode recomp_camera_mode;
DECLARE_FUNC(void, recomp_get_gyro_deltas, float* x, float* y);
DECLARE_FUNC(void, recomp_get_mouse_deltas, float* x, float* y);
-DECLARE_FUNC(s32, recomp_get_targeting_mode);
+// DECLARE_FUNC(s32, recomp_get_targeting_mode);
DECLARE_FUNC(void, recomp_get_inverted_axes, s32* x, s32* y);
DECLARE_FUNC(s32, recomp_get_invert_y_axis_mode);
DECLARE_FUNC(s32, recomp_get_radio_comm_box_mode);
diff --git a/patches/misc_funcs.h b/patches/misc_funcs.h
index e1178fb..482e205 100644
--- a/patches/misc_funcs.h
+++ b/patches/misc_funcs.h
@@ -8,8 +8,6 @@ DECLARE_FUNC(void, recomp_puts, const char* data, u32 size);
DECLARE_FUNC(void, recomp_exit);
DECLARE_FUNC(void, recomp_handle_quicksave_actions, OSMesgQueue* enter_mq, OSMesgQueue* exit_mq);
DECLARE_FUNC(void, recomp_handle_quicksave_actions_main, OSMesgQueue* enter_mq, OSMesgQueue* exit_mq);
-DECLARE_FUNC(u16, recomp_get_pending_warp);
-DECLARE_FUNC(u32, recomp_get_pending_set_time);
DECLARE_FUNC(s32, recomp_get_film_grain_enabled);
#endif
diff --git a/patches/recompui_event_structs.h b/patches/recompui_event_structs.h
index 914160d..5495081 100644
--- a/patches/recompui_event_structs.h
+++ b/patches/recompui_event_structs.h
@@ -1,7 +1,7 @@
#ifndef __UI_FUNCS_H__
#define __UI_FUNCS_H__
-// These two enums must be kept in sync with src/ui/elements/ui_types.h!
+// These three enums must be kept in sync with src/ui/elements/ui_types.h!
typedef enum {
UI_EVENT_NONE,
UI_EVENT_CLICK,
@@ -11,6 +11,9 @@ typedef enum {
UI_EVENT_DRAG,
UI_EVENT_RESERVED1, // Would be UI_EVENT_TEXT but text events aren't usable in mods currently
UI_EVENT_UPDATE,
+ UI_EVENT_NAVIGATE,
+ UI_EVENT_MOUSE_BUTTON,
+ UI_EVENT_MENU_ACTION,
UI_EVENT_COUNT
} RecompuiEventType;
@@ -21,6 +24,16 @@ typedef enum {
UI_DRAG_END
} RecompuiDragPhase;
+typedef enum {
+ UI_MENU_ACTION_NONE,
+ UI_MENU_ACTION_ACCEPT,
+ UI_MENU_ACTION_APPLY,
+ UI_MENU_ACTION_BACK,
+ UI_MENU_ACTION_TOGGLE,
+ UI_MENU_ACTION_TAB_LEFT,
+ UI_MENU_ACTION_TAB_RIGHT
+} RecompuiMenuAction;
+
typedef struct {
RecompuiEventType type;
union {
@@ -46,6 +59,10 @@ typedef struct {
float y;
RecompuiDragPhase phase;
} drag;
+
+ struct {
+ RecompuiMenuAction action;
+ } menu_action;
} data;
} RecompuiEventData;
diff --git a/patches/sound.h b/patches/sound.h
index 46eb89d..d1ccdbf 100644
--- a/patches/sound.h
+++ b/patches/sound.h
@@ -6,6 +6,6 @@
DECLARE_FUNC(float, recomp_get_bgm_volume);
DECLARE_FUNC(float, recomp_get_sfx_volume);
DECLARE_FUNC(float, recomp_get_voice_volume);
-DECLARE_FUNC(u32, recomp_get_low_health_beeps_enabled);
+// DECLARE_FUNC(u32, recomp_get_low_health_beeps_enabled);
#endif
diff --git a/patches/syms.ld b/patches/syms.ld
index b4ad4e1..aa90106 100644
--- a/patches/syms.ld
+++ b/patches/syms.ld
@@ -10,12 +10,12 @@ osRecvMesg_recomp = 0x8F000010;
osSendMesg_recomp = 0x8F000014;
recomp_get_gyro_deltas = 0x8F000018;
recomp_get_target_aspect_ratio = 0x8F00001C;
-recomp_get_pending_warp = 0x8F000020;
+/* recomp_get_pending_warp = 0x8F000020; */
recomp_powf = 0x8F000024;
recomp_get_target_framerate = 0x8F000028;
-recomp_get_targeting_mode = 0x8F00002C;
+/* recomp_get_targeting_mode = 0x8F00002C; */
recomp_get_bgm_volume = 0x8F000030;
-recomp_get_low_health_beeps_enabled = 0x8F000034;
+/* recomp_get_low_health_beeps_enabled = 0x8F000034; */
__sinf_recomp = 0x8F000038;
__cosf_recomp = 0x8F00003C;
sqrtf_recomp = 0x8F0000B8;
@@ -28,7 +28,7 @@ bzero_recomp = 0x8F00005C;
osFlashWriteArray_recomp = 0x8F000060;
osFlashWriteBuffer_recomp = 0x8F000064;
osWritebackDCache_recomp = 0x8F000068;
-recomp_get_pending_set_time = 0x8F00006C;
+/* recomp_get_pending_set_time = 0x8F00006C; */
osContStartReadData_recomp = 0x8F000070;
osContGetReadData_recomp = 0x8F000074;
osContStartQuery_recomp = 0x8F000078;
diff --git a/patches/versus.c b/patches/versus.c
index 396bcbd..45b8120 100644
--- a/patches/versus.c
+++ b/patches/versus.c
@@ -1,5 +1,7 @@
#include "patches.h"
+#if DEBUG_DISABLE_VERSUS == 1
+
bool Option_Input_MoveCursor_Y(s32* arg0, s32 arg1, bool arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6,
s32 controllerNum, StickInputOption* stickY);
void Option_MainMenu_Setup(void);
@@ -105,11 +107,12 @@ RECOMP_PATCH void Option_MainMenu_Update(void) {
}
if (gControllerPress[gMainController].button & (A_BUTTON | START_BUTTON)) {
-#if DEBUG_VERSUS == 0
+
+ // @recomp: Disable Versus mode
if (sMainMenuCursor == 2) {
break;
}
-#endif
+
AUDIO_PLAY_SFX(NA_SE_ARWING_DECIDE, gDefaultSfxSource, 4);
sLightningYpos = sOptionCardPosY[sMainMenuCursor];
sDrawCursor = false;
@@ -203,4 +206,5 @@ RECOMP_PATCH void Option_MainMenu_Update(void) {
}
break;
}
-}
\ No newline at end of file
+}
+#endif
\ No newline at end of file
diff --git a/shaders/InterfacePS.hlsl b/shaders/InterfacePS.hlsl
deleted file mode 100644
index b8ab340..0000000
--- a/shaders/InterfacePS.hlsl
+++ /dev/null
@@ -1,11 +0,0 @@
-SamplerState gSampler : register(s1, space0);
-Texture2D gTexture : register(t2, space1);
-
-void PSMain(
- in float4 iColor : COLOR,
- in float2 iUV : TEXCOORD,
- out float4 oColor : SV_TARGET
-)
-{
- oColor = gTexture.SampleLevel(gSampler, iUV, 0) * iColor;
-}
diff --git a/shaders/InterfaceVS.hlsl b/shaders/InterfaceVS.hlsl
deleted file mode 100644
index 05fd649..0000000
--- a/shaders/InterfaceVS.hlsl
+++ /dev/null
@@ -1,23 +0,0 @@
-struct Input {
- float4x4 transform;
- float2 translation;
-};
-
-[[vk::push_constant]]
-ConstantBuffer gInput : register(b0, space0);
-
-void VSMain(
- in float2 iPosition : POSITION,
- in float4 iColor : COLOR,
- in float2 iUV : TEXCOORD,
- out float4 oColor : COLOR,
- out float2 oUV : TEXCOORD,
- out float4 oPosition : SV_Position
-)
-{
- float2 translatedPos = iPosition + gInput.translation;
- oPosition = mul(gInput.transform, float4(translatedPos, 0, 1));
-
- oColor = iColor;
- oUV = iUV;
-}
diff --git a/src/game/config.cpp b/src/game/config.cpp
index ad4ec86..6ae545c 100644
--- a/src/game/config.cpp
+++ b/src/game/config.cpp
@@ -1,10 +1,14 @@
#include "zelda_config.h"
-#include "recomp_input.h"
+#include "zelda_debug.h"
+#include "recompui/recompui.h"
+#include "recompui/config.h"
+#include "recompinput/recompinput.h"
#include "zelda_sound.h"
-#include "zelda_render.h"
#include "zelda_support.h"
#include "ultramodern/config.hpp"
#include "librecomp/files.hpp"
+#include "librecomp/config.hpp"
+#include "util/file.h"
#include
#include
#include
@@ -18,519 +22,374 @@
#include "apple/rt64_apple.h"
#endif
-constexpr std::u8string_view general_filename = u8"general.json";
-constexpr std::u8string_view graphics_filename = u8"graphics.json";
-constexpr std::u8string_view controls_filename = u8"controls.json";
-constexpr std::u8string_view sound_filename = u8"sound.json";
-
-constexpr auto res_default = ultramodern::renderer::Resolution::Auto;
-constexpr auto hr_default = ultramodern::renderer::HUDRatioMode::Clamp16x9;
-constexpr auto api_default = ultramodern::renderer::GraphicsApi::Auto;
-constexpr auto ar_default = ultramodern::renderer::AspectRatio::Expand;
-constexpr auto msaa_default = ultramodern::renderer::Antialiasing::MSAA2X;
-constexpr auto rr_default = ultramodern::renderer::RefreshRate::Display;
-constexpr auto hpfb_default = ultramodern::renderer::HighPrecisionFramebuffer::Auto;
-constexpr int ds_default = 1;
-constexpr int rr_manual_default = 60;
-constexpr bool developer_mode_default = false;
-
-static bool is_steam_deck = false;
-
-ultramodern::renderer::WindowMode wm_default() {
- return is_steam_deck ? ultramodern::renderer::WindowMode::Fullscreen : ultramodern::renderer::WindowMode::Windowed;
+bool get_general_config_bool_value(const std::string& option_id) {
+ return std::get(recompui::config::get_general_config().get_option_value(option_id));
}
-#ifdef __gnu_linux__
-void detect_steam_deck() {
- // Check if the board vendor is Valve.
- std::ifstream board_vendor_file("/sys/devices/virtual/dmi/id/board_vendor");
- std::string line;
- if (std::getline(board_vendor_file, line).good() && line == "Valve") {
- is_steam_deck = true;
- return;
- }
-
- // Check if the SteamDeck variable is set to 1.
- const char* steam_deck_env = getenv("SteamDeck");
- if (steam_deck_env != nullptr && std::string{steam_deck_env} == "1") {
- is_steam_deck = true;
- return;
- }
-
- is_steam_deck = false;
- return;
+template
+T get_general_config_enum_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_general_config().get_option_value(option_id)));
}
-#else
-void detect_steam_deck() { is_steam_deck = false; }
-#endif
-
-template
-T from_or_default(const json& j, const std::string& key, T default_value) {
- T ret;
- auto find_it = j.find(key);
- if (find_it != j.end()) {
- find_it->get_to(ret);
- }
- else {
- ret = default_value;
- }
- return ret;
+template
+T get_general_config_number_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_general_config().get_option_value(option_id)));
}
-template
-void call_if_key_exists(void (*func)(T), const json& j, const std::string& key) {
- auto find_it = j.find(key);
- if (find_it != j.end()) {
- T val;
- find_it->get_to(val);
- func(val);
- }
+template
+T get_graphics_config_enum_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_graphics_config().get_option_value(option_id)));
}
-namespace ultramodern {
- void to_json(json& j, const renderer::GraphicsConfig& config) {
- j = json{
- {"res_option", config.res_option},
- {"wm_option", config.wm_option},
- {"hr_option", config.hr_option},
- {"api_option", config.api_option},
- {"ds_option", config.ds_option},
- {"ar_option", config.ar_option},
- {"msaa_option", config.msaa_option},
- {"rr_option", config.rr_option},
- {"hpfb_option", config.hpfb_option},
- {"rr_manual_value", config.rr_manual_value},
- {"developer_mode", config.developer_mode},
- };
- }
-
- void from_json(const json& j, renderer::GraphicsConfig& config) {
- config.res_option = from_or_default(j, "res_option", res_default);
- config.wm_option = from_or_default(j, "wm_option", wm_default());
- config.hr_option = from_or_default(j, "hr_option", hr_default);
- config.api_option = from_or_default(j, "api_option", api_default);
- config.ds_option = from_or_default(j, "ds_option", ds_default);
- config.ar_option = from_or_default(j, "ar_option", ar_default);
- config.msaa_option = from_or_default(j, "msaa_option", msaa_default);
- config.rr_option = from_or_default(j, "rr_option", rr_default);
- config.hpfb_option = from_or_default(j, "hpfb_option", hpfb_default);
- config.rr_manual_value = from_or_default(j, "rr_manual_value", rr_manual_default);
- config.developer_mode = from_or_default(j, "developer_mode", developer_mode_default);
- }
+template
+T get_graphics_config_number_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_graphics_config().get_option_value(option_id)));
}
-namespace recomp {
- void to_json(json& j, const InputField& field) {
- j = json{ {"input_type", field.input_type}, {"input_id", field.input_id} };
- }
+template
+T get_sound_config_enum_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_sound_config().get_option_value(option_id)));
+}
- void from_json(const json& j, InputField& field) {
- j.at("input_type").get_to(field.input_type);
- j.at("input_id").get_to(field.input_id);
- }
+template
+T get_sound_config_number_value(const std::string& option_id) {
+ return static_cast(std::get(recompui::config::get_sound_config().get_option_value(option_id)));
}
-std::filesystem::path zelda64::get_app_folder_path() {
- // directly check for portable.txt (windows and native linux binary)
- if (std::filesystem::exists("portable.txt")) {
- return std::filesystem::current_path();
- }
-
-#if defined(__APPLE__)
- // Check for portable file in the directory containing the app bundle.
- const auto app_bundle_path = zelda64::get_bundle_directory().parent_path();
- if (std::filesystem::exists(app_bundle_path / "portable.txt")) {
- return app_bundle_path;
- }
-#endif
+static void add_general_options(recomp::config::Config &config) {
+ using EnumOptionVector = const std::vector;
- std::filesystem::path recomp_dir{};
+ // debug_mode
+ config.add_bool_option(
+ zelda64::configkeys::general::debug_mode,
+ "Debug Mode",
+ "Controls whether the debug menu is visible",
+ false,
+ true
+ );
-#if defined(_WIN32)
- // Deduce local app data path.
- PWSTR known_path = NULL;
- HRESULT result = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &known_path);
- if (result == S_OK) {
- recomp_dir = std::filesystem::path{known_path} / zelda64::program_id;
- }
-
- CoTaskMemFree(known_path);
-#elif defined(__linux__) || defined(__APPLE__)
- // check for APP_FOLDER_PATH env var
- if (getenv("APP_FOLDER_PATH") != nullptr) {
- return std::filesystem::path{getenv("APP_FOLDER_PATH")};
- }
-
-#if defined(__APPLE__)
- const auto supportdir = zelda64::get_application_support_directory();
- if (supportdir) {
- return *supportdir / zelda64::program_id;
- }
-#endif
+ // Film Grain
+ static EnumOptionVector film_grain_options = {
+ {zelda64::FilmGrainMode::On, "On"},
+ {zelda64::FilmGrainMode::Off, "Off"},
+ };
+
+ config.add_enum_option(
+ zelda64::configkeys::general::film_grain_mode,
+ "Film Grain",
+ "Adds a visual effect that simulates the random grain you see in old film or high-ISO camera footage. On is the default and matches the original game.",
+ film_grain_options,
+ zelda64::InvertYAxisMode::On
+ );
- const char *homedir;
+ // Invert Y Axis
+ static EnumOptionVector invert_y_axis_options = {
+ {zelda64::InvertYAxisMode::On, "On"},
+ {zelda64::InvertYAxisMode::Off, "Off"},
+ };
+
+ config.add_enum_option(
+ zelda64::configkeys::general::invert_y_axis,
+ "Invert Y Axis",
+ "Inverts the Y axis aiming controls. On is the default and matches the original game.",
+ invert_y_axis_options,
+ zelda64::InvertYAxisMode::On
+ );
- if ((homedir = getenv("HOME")) == nullptr) {
- #if defined(__linux__)
- homedir = getpwuid(getuid())->pw_dir;
- #elif defined(__APPLE__)
- homedir = GetHomeDirectory();
- #endif
- }
+ // Radio Communication Box
+ static EnumOptionVector radio_comm_options = {
+ {zelda64::RadioCommBoxMode::Expand, "Expand"},
+ {zelda64::RadioCommBoxMode::Original, "Original"},
+ };
+
+ config.add_enum_option(
+ zelda64::configkeys::general::radio_comm_mode,
+ "Radio Communication Box",
+ "Radio Communication Box Alignment.",
+ radio_comm_options,
+ zelda64::RadioCommBoxMode::Original
+ );
- if (homedir != nullptr) {
- recomp_dir = std::filesystem::path{homedir} / (std::u8string{u8".config/"} + std::u8string{zelda64::program_id});
- }
-#endif
+ #if 0
+
+ // autosave_mode
+ static EnumOptionVector autosave_mode_options = {
+ {zelda64::AutosaveMode::Off, "Off"},
+ {zelda64::AutosaveMode::On, "On"},
+ };
+ config.add_enum_option(
+ zelda64::configkeys::general::autosave_mode,
+ "Autosaving",
+ "Turns on autosaving and prevents owl saves from being deleted on load. Autosaves act as owl saves and take up the same slot as they do.\n"
+ "\n"
+ "Loading an autosave will place you in Clock Town or at the entrance of the current dungeon if you were in one.\n"
+ "\n"
+ "\n"
+ "If autosaving is disabled, existing autosaves will be deleted when loaded.",
+ autosave_mode_options,
+ zelda64::AutosaveMode::On
+ );
- return recomp_dir;
-}
+ // camera_invert_mode
+ static EnumOptionVector camera_invert_mode_options = {
+ {zelda64::CameraInvertMode::InvertNone, "None"},
+ {zelda64::CameraInvertMode::InvertX, "Invert X"},
+ {zelda64::CameraInvertMode::InvertY, "Invert Y"},
+ {zelda64::CameraInvertMode::InvertBoth, "Invert Both"},
+ };
+ config.add_enum_option(
+ zelda64::configkeys::general::camera_invert_mode,
+ "Aiming Camera Mode",
+ "Inverts the camera controls for first-person aiming. Invert Y is the default and matches the original game.",
+ camera_invert_mode_options,
+ zelda64::CameraInvertMode::InvertY
+ );
-bool read_json(std::ifstream input_file, nlohmann::json& json_out) {
- if (!input_file.good()) {
- return false;
- }
+ // analog_cam_mode
+ static EnumOptionVector analog_cam_mode_options = {
+ {zelda64::AnalogCamMode::Off, "Off"},
+ {zelda64::AnalogCamMode::On, "On"},
+ };
+ config.add_enum_option(
+ zelda64::configkeys::general::analog_cam_mode,
+ "Analog Camera",
+ "Enables an analog \"free\" camera similar to later entries in the series that's mapped to the right analog stick on the controller.\n"
+ "\n"
+ "When you move the right stick, the camera will enter free mode and stop centering behind Link. Press the Target button at any time to go back into the normal camera mode. The camera will also return to normal mode after a cutscene plays or when you move between areas.\n"
+ "\n"
+ "This option also enables right stick control while looking and aiming.",
+ analog_cam_mode_options,
+ zelda64::AnalogCamMode::Off
+ );
- try {
- input_file >> json_out;
- }
- catch (nlohmann::json::parse_error&) {
- return false;
- }
- return true;
+ // analog_camera_invert_mode
+ static EnumOptionVector analog_camera_invert_mode_options = {
+ {zelda64::CameraInvertMode::InvertNone, "None"},
+ {zelda64::CameraInvertMode::InvertX, "Invert X"},
+ {zelda64::CameraInvertMode::InvertY, "Invert Y"},
+ {zelda64::CameraInvertMode::InvertBoth, "Invert Both"},
+ };
+ config.add_enum_option(
+ zelda64::configkeys::general::analog_camera_invert_mode,
+ "Analog Camera Mode",
+ "Inverts the camera controls for the analog camera if it's enabled. None is the default.",
+ analog_camera_invert_mode_options,
+ zelda64::CameraInvertMode::InvertNone
+ );
+ #endif
}
-bool read_json_with_backups(const std::filesystem::path& path, nlohmann::json& json_out) {
- // Try reading and parsing the base file.
- if (read_json(std::ifstream{path}, json_out)) {
- return true;
- }
-
- // Try reading and parsing the backup file.
- if (read_json(recomp::open_input_backup_file(path), json_out)) {
- return true;
- }
-
- // Both reads failed.
- return false;
+bool zelda64::get_debug_mode_enabled() {
+ return get_general_config_bool_value(zelda64::configkeys::general::debug_mode);
}
-bool save_json_with_backups(const std::filesystem::path& path, const nlohmann::json& json_data) {
- {
- std::ofstream output_file = recomp::open_output_file_with_backup(path);
- if (!output_file.good()) {
- return false;
- }
-
- output_file << std::setw(4) << json_data;
- }
- return recomp::finalize_output_file_with_backup(path);
+zelda64::FilmGrainMode zelda64::get_film_grain_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::film_grain_mode);
}
-bool save_general_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
-
- zelda64::to_json(config_json["targeting_mode"], zelda64::get_targeting_mode());
- recomp::to_json(config_json["background_input_mode"], recomp::get_background_input_mode());
- config_json["rumble_strength"] = recomp::get_rumble_strength();
- config_json["gyro_sensitivity"] = recomp::get_gyro_sensitivity();
- config_json["mouse_sensitivity"] = recomp::get_mouse_sensitivity();
- config_json["joystick_deadzone"] = recomp::get_joystick_deadzone();
- config_json["film_grain_mode"] = zelda64::get_film_grain_mode();
- config_json["radio_comm_box_mode"] = zelda64::get_radio_comm_box_mode();
- config_json["invert_y_axis_mode"] = zelda64::get_invert_y_axis_mode();
- config_json["analog_camera_invert_mode"] = zelda64::get_analog_camera_invert_mode();
- config_json["debug_mode"] = zelda64::get_debug_mode_enabled();
-
- return save_json_with_backups(path, config_json);
+zelda64::RadioCommBoxMode zelda64::get_radio_comm_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::radio_comm_mode);
}
-void set_general_settings_from_json(const nlohmann::json& config_json) {
- zelda64::set_targeting_mode(from_or_default(config_json, "targeting_mode", zelda64::TargetingMode::Switch));
- recomp::set_background_input_mode(from_or_default(config_json, "background_input_mode", recomp::BackgroundInputMode::On));
- recomp::set_rumble_strength(from_or_default(config_json, "rumble_strength", 50));
- recomp::set_gyro_sensitivity(from_or_default(config_json, "gyro_sensitivity", 50));
- recomp::set_mouse_sensitivity(from_or_default(config_json, "mouse_sensitivity", is_steam_deck ? 50 : 0));
- recomp::set_joystick_deadzone(from_or_default(config_json, "joystick_deadzone", 0));
- zelda64::set_film_grain_mode(from_or_default(config_json, "film_grain_mode", zelda64::FilmGrainMode::On));
- zelda64::set_radio_comm_box_mode(from_or_default(config_json, "radio_comm_box_mode", zelda64::RadioBoxMode::Original));
- zelda64::set_invert_y_axis_mode(from_or_default(config_json, "invert_y_axis_mode", zelda64::AimInvertMode::On));
- zelda64::set_analog_camera_invert_mode(from_or_default(config_json, "analog_camera_invert_mode", zelda64::AimInvertMode::On));
- zelda64::set_debug_mode_enabled(from_or_default(config_json, "debug_mode", false));
+zelda64::InvertYAxisMode zelda64::get_invert_y_axis_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::invert_y_axis);
}
-bool load_general_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
- if (!read_json_with_backups(path, config_json)) {
- return false;
- }
-
- set_general_settings_from_json(config_json);
- return true;
+#if 0
+zelda64::CameraInvertMode zelda64::get_camera_invert_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::camera_invert_mode);
}
-void assign_mapping(recomp::InputDevice device, recomp::GameInput input, const std::vector& value) {
- for (size_t binding_index = 0; binding_index < std::min(value.size(), recomp::bindings_per_input); binding_index++) {
- recomp::set_input_binding(input, binding_index, device, value[binding_index]);
- }
-};
-
-// same as assign_mapping, except will clear unassigned bindings if not in value
-void assign_mapping_complete(recomp::InputDevice device, recomp::GameInput input, const std::vector& value) {
- for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
- if (binding_index >= value.size()) {
- recomp::set_input_binding(input, binding_index, device, recomp::InputField{});
- } else {
- recomp::set_input_binding(input, binding_index, device, value[binding_index]);
- }
- }
-};
-
-void assign_all_mappings(recomp::InputDevice device, const recomp::DefaultN64Mappings& values) {
- assign_mapping_complete(device, recomp::GameInput::A, values.a);
- assign_mapping_complete(device, recomp::GameInput::B, values.b);
- assign_mapping_complete(device, recomp::GameInput::Z, values.z);
- assign_mapping_complete(device, recomp::GameInput::START, values.start);
- assign_mapping_complete(device, recomp::GameInput::DPAD_UP, values.dpad_up);
- assign_mapping_complete(device, recomp::GameInput::DPAD_DOWN, values.dpad_down);
- assign_mapping_complete(device, recomp::GameInput::DPAD_LEFT, values.dpad_left);
- assign_mapping_complete(device, recomp::GameInput::DPAD_RIGHT, values.dpad_right);
- assign_mapping_complete(device, recomp::GameInput::L, values.l);
- assign_mapping_complete(device, recomp::GameInput::R, values.r);
- assign_mapping_complete(device, recomp::GameInput::C_UP, values.c_up);
- assign_mapping_complete(device, recomp::GameInput::C_DOWN, values.c_down);
- assign_mapping_complete(device, recomp::GameInput::C_LEFT, values.c_left);
- assign_mapping_complete(device, recomp::GameInput::C_RIGHT, values.c_right);
-
- assign_mapping_complete(device, recomp::GameInput::X_AXIS_NEG, values.analog_left);
- assign_mapping_complete(device, recomp::GameInput::X_AXIS_POS, values.analog_right);
- assign_mapping_complete(device, recomp::GameInput::Y_AXIS_NEG, values.analog_down);
- assign_mapping_complete(device, recomp::GameInput::Y_AXIS_POS, values.analog_up);
-
- assign_mapping_complete(device, recomp::GameInput::TOGGLE_MENU, values.toggle_menu);
- assign_mapping_complete(device, recomp::GameInput::ACCEPT_MENU, values.accept_menu);
- assign_mapping_complete(device, recomp::GameInput::APPLY_MENU, values.apply_menu);
-};
-
-void zelda64::reset_input_bindings() {
- assign_all_mappings(recomp::InputDevice::Keyboard, recomp::default_n64_keyboard_mappings);
- assign_all_mappings(recomp::InputDevice::Controller, recomp::default_n64_controller_mappings);
+zelda64::AnalogCamMode zelda64::get_analog_cam_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::analog_cam_mode);
}
-void zelda64::reset_cont_input_bindings() {
- assign_all_mappings(recomp::InputDevice::Controller, recomp::default_n64_controller_mappings);
-}
-void zelda64::reset_kb_input_bindings() {
- assign_all_mappings(recomp::InputDevice::Keyboard, recomp::default_n64_keyboard_mappings);
+zelda64::CameraInvertMode zelda64::get_analog_camera_invert_mode() {
+ return get_general_config_enum_value(zelda64::configkeys::general::analog_camera_invert_mode);
}
+#endif
-void zelda64::reset_single_input_binding(recomp::InputDevice device, recomp::GameInput input) {
- assign_mapping_complete(
- device,
- input,
- recomp::get_default_mapping_for_input(
- device == recomp::InputDevice::Keyboard ?
- recomp::default_n64_keyboard_mappings :
- recomp::default_n64_controller_mappings,
- input
- )
- );
-}
+static void add_graphics_options(recomp::config::Config &config) {
+ using EnumOptionVector = const std::vector;
-void reset_graphics_options() {
- ultramodern::renderer::GraphicsConfig new_config{};
- new_config.res_option = res_default;
- new_config.wm_option = wm_default();
- new_config.hr_option = hr_default;
- new_config.ds_option = ds_default;
- new_config.ar_option = ar_default;
- new_config.msaa_option = msaa_default;
- new_config.rr_option = rr_default;
- new_config.hpfb_option = hpfb_default;
- new_config.rr_manual_value = rr_manual_default;
- new_config.developer_mode = developer_mode_default;
- ultramodern::renderer::set_graphics_config(new_config);
+ // Nothing to do here.
}
-bool save_graphics_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
- ultramodern::to_json(config_json, ultramodern::renderer::get_graphics_config());
- return save_json_with_backups(path, config_json);
-}
+static void add_sound_options(recomp::config::Config &config) {
+ using EnumOptionVector = const std::vector;
-bool load_graphics_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
- if (!read_json_with_backups(path, config_json)) {
- return false;
- }
+ // bgm_volume
+ config.add_percent_number_option(
+ zelda64::configkeys::sound::bgm_volume,
+ "Background Music Volume",
+ "Controls the overall volume of background music.",
+ 100.0f
+ );
- ultramodern::renderer::GraphicsConfig new_config{};
- ultramodern::from_json(config_json, new_config);
- ultramodern::renderer::set_graphics_config(new_config);
- return true;
-}
+ // voice_volume
+ config.add_percent_number_option(
+ zelda64::configkeys::sound::voice_volume,
+ "Voice Volume",
+ "Controls the overall volume of voices.",
+ 100.0f
+ );
-void add_input_bindings(nlohmann::json& out, recomp::GameInput input, recomp::InputDevice device) {
- const std::string& input_name = recomp::get_input_enum_name(input);
- nlohmann::json& out_array = out[input_name];
- out_array = nlohmann::json::array();
- for (size_t binding_index = 0; binding_index < recomp::bindings_per_input; binding_index++) {
- out_array[binding_index] = recomp::get_input_binding(input, binding_index, device);
- }
-};
+ // sfx_volume
+ config.add_percent_number_option(
+ zelda64::configkeys::sound::sfx_volume,
+ "Sound Effects Volume",
+ "Controls the overall volume of sound effects.",
+ 100.0f
+ );
-bool save_controls_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
+ #if 0
+ // low_health_beeps
+ static EnumOptionVector low_health_beeps_mode_options = {
+ {zelda64::LowHealthBeepsMode::Off, "Off"},
+ {zelda64::LowHealthBeepsMode::On, "On"},
+ };
+ config.add_enum_option(
+ zelda64::configkeys::sound::low_health_beeps,
+ "Low Health Beeps",
+ "Toggles whether or not the low-health beeping sound plays.",
+ low_health_beeps_mode_options,
+ zelda64::LowHealthBeepsMode::On
+ );
+ #endif
+}
- config_json["keyboard"] = {};
- config_json["controller"] = {};
+int zelda64::get_bgm_volume() {
+ return get_sound_config_number_value(zelda64::configkeys::sound::bgm_volume);
+}
- for (size_t i = 0; i < recomp::get_num_inputs(); i++) {
- recomp::GameInput cur_input = static_cast(i);
+int zelda64::get_sfx_volume() {
+ return get_sound_config_number_value(zelda64::configkeys::sound::sfx_volume);
+}
- add_input_bindings(config_json["keyboard"], cur_input, recomp::InputDevice::Keyboard);
- add_input_bindings(config_json["controller"], cur_input, recomp::InputDevice::Controller);
- }
+int zelda64::get_voice_volume() {
+ return get_sound_config_number_value(zelda64::configkeys::sound::voice_volume);
+}
- return save_json_with_backups(path, config_json);
+#if 0
+bool zelda64::get_low_health_beeps_enabled() {
+ return get_sound_config_enum_value(zelda64::configkeys::sound::low_health_beeps) == zelda64::LowHealthBeepsMode::On;
}
+#endif
-bool load_input_device_from_json(const nlohmann::json& config_json, recomp::InputDevice device, const std::string& key) {
- // Check if the json object for the given key exists.
- auto find_it = config_json.find(key);
- if (find_it == config_json.end()) {
- return false;
- }
+static void set_control_defaults() {
+ using namespace recompinput;
- const nlohmann::json& mappings_json = *find_it;
-
- for (size_t i = 0; i < recomp::get_num_inputs(); i++) {
- recomp::GameInput cur_input = static_cast(i);
- const std::string& input_name = recomp::get_input_enum_name(cur_input);
-
- // Check if the json object for the given input exists and that it's an array.
- auto find_input_it = mappings_json.find(input_name);
- if (find_input_it == mappings_json.end() || !find_input_it->is_array()) {
- assign_mapping(
- device,
- cur_input,
- recomp::get_default_mapping_for_input(
- device == recomp::InputDevice::Keyboard ?
- recomp::default_n64_keyboard_mappings :
- recomp::default_n64_controller_mappings,
- cur_input
- )
- );
- continue;
+ set_default_mapping_for_controller(
+ GameInput::C_DOWN,
+ {
+ InputField::controller_digital(SDL_CONTROLLER_BUTTON_EAST),
+ InputField::controller_analog(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT, true)
}
- const nlohmann::json& input_json = *find_input_it;
+ );
- // Deserialize all the bindings from the json array (up to the max number of bindings per input).
- for (size_t binding_index = 0; binding_index < std::min(recomp::bindings_per_input, input_json.size()); binding_index++) {
- recomp::InputField cur_field{};
- recomp::from_json(input_json[binding_index], cur_field);
- recomp::set_input_binding(cur_input, binding_index, device, cur_field);
+ set_default_mapping_for_controller(
+ GameInput::C_LEFT,
+ {
+ InputField::controller_digital(SDL_CONTROLLER_BUTTON_NORTH),
+ InputField::controller_analog(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT, true)
}
- }
-
- return true;
-}
-
-bool load_controls_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
- if (!read_json_with_backups(path, config_json)) {
- return false;
- }
-
- if (!load_input_device_from_json(config_json, recomp::InputDevice::Keyboard, "keyboard")) {
- assign_all_mappings(recomp::InputDevice::Keyboard, recomp::default_n64_keyboard_mappings);
- }
+ );
- if (!load_input_device_from_json(config_json, recomp::InputDevice::Controller, "controller")) {
- assign_all_mappings(recomp::InputDevice::Controller, recomp::default_n64_controller_mappings);
- }
- return true;
-}
+ set_default_mapping_for_controller(
+ GameInput::C_RIGHT,
+ {
+ InputField::controller_analog(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX, true),
+ InputField::controller_digital(SDL_CONTROLLER_BUTTON_EAST)
+ }
+ );
-bool save_sound_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
+ set_default_mapping_for_controller(
+ GameInput::Z,
+ {
+ InputField::controller_digital(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER)
+ }
+ );
- config_json["main_volume"] = zelda64::get_main_volume();
- config_json["bgm_volume"] = zelda64::get_bgm_volume();
- config_json["sfx_volume"] = zelda64::get_sfx_volume();
- config_json["voice_volume"] = zelda64::get_voice_volume();
- config_json["low_health_beeps"] = zelda64::get_low_health_beeps_enabled();
+ set_default_mapping_for_controller(
+ GameInput::R,
+ {
+ InputField::controller_digital(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)
+ }
+ );
- return save_json_with_backups(path, config_json);
+ // L3 -> L | Unused in SF64 but can be used in mods
+ set_default_mapping_for_controller(GameInput::L, { InputField::controller_digital(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK) });
}
-bool load_sound_config(const std::filesystem::path& path) {
- nlohmann::json config_json{};
- if (!read_json_with_backups(path, config_json)) {
- return false;
- }
-
- zelda64::reset_sound_settings();
- call_if_key_exists(zelda64::set_main_volume, config_json, "main_volume");
- call_if_key_exists(zelda64::set_bgm_volume, config_json, "bgm_volume");
- call_if_key_exists(zelda64::set_sfx_volume, config_json, "sfx_volume");
- call_if_key_exists(zelda64::set_voice_volume, config_json, "voice_volume");
- call_if_key_exists(zelda64::set_low_health_beeps_enabled, config_json, "low_health_beeps");
- return true;
+static void set_control_descriptions() {
+ recompinput::set_game_input_name(recompinput::GameInput::A, "Laser | (A)");
+ recompinput::set_game_input_name(recompinput::GameInput::B, "Smart Bomb | (B)");
+ recompinput::set_game_input_name(recompinput::GameInput::Z, "Tilt Left | (Z)");
+ recompinput::set_game_input_name(recompinput::GameInput::R, "Tilt Right | (R)");
+ recompinput::set_game_input_name(recompinput::GameInput::START, "Pause | (Start)");
+ recompinput::set_game_input_name(recompinput::GameInput::C_UP, "Camera | (C-UP)");
+ recompinput::set_game_input_name(recompinput::GameInput::C_LEFT, "Turbo | (C-LEFT)");
+ recompinput::set_game_input_name(recompinput::GameInput::C_DOWN, "Brake | (C-DOWN)");
+ recompinput::set_game_input_name(recompinput::GameInput::C_RIGHT, "ROB Message | (C-RIGHT)");
+ recompinput::set_game_input_name(recompinput::GameInput::L, "MOD | (L)");
+
+ recompinput::set_game_input_description(recompinput::GameInput::Y_AXIS_POS, "Used to Aim and steering. Y Axis inversion can be configured in the General tab.");
+ recompinput::set_game_input_description(recompinput::GameInput::Y_AXIS_NEG, "Used to Aim and steering. Y Axis inversion can be configured in the General tab.");
+ recompinput::set_game_input_description(recompinput::GameInput::X_AXIS_NEG, "Used to Aim and steering.");
+ recompinput::set_game_input_description(recompinput::GameInput::X_AXIS_POS, "Used to Aim and steering.");
+ recompinput::set_game_input_description(recompinput::GameInput::A, "Used to shoot.");
+ recompinput::set_game_input_description(recompinput::GameInput::B, "Used to shoot smart bombs");
+ recompinput::set_game_input_description(recompinput::GameInput::Z, "Arwing: Tilt Left. Landmaster: Left thruster. Double tap to Do a Barrel Roll!");
+ recompinput::set_game_input_description(recompinput::GameInput::R, "Arwing: Tilt Right. Landmaster: Left thruster. Double tap to Do a Barrel Roll!");
+ recompinput::set_game_input_description(recompinput::GameInput::L, "Unused. Mods may use it for additional features.");
+ recompinput::set_game_input_description(recompinput::GameInput::START, "Used for pausing and for skipping certain cutscenes.");
+ recompinput::set_game_input_description(recompinput::GameInput::C_UP, "Used to change the camera mode.");
+ recompinput::set_game_input_description(recompinput::GameInput::C_DOWN, "Used to Brake.");
+ recompinput::set_game_input_description(recompinput::GameInput::C_LEFT, "Used to Accelerate.");
+ recompinput::set_game_input_description(recompinput::GameInput::C_RIGHT, "Used to respond to incoming messages from ROB.");
+ recompinput::set_game_input_description(recompinput::GameInput::DPAD_UP, "Used for in-game menu navigation.");
+ recompinput::set_game_input_description(recompinput::GameInput::DPAD_DOWN, "Used for in-game menu navigation.");
+ recompinput::set_game_input_description(recompinput::GameInput::DPAD_LEFT, "Used for in-game menu navigation.");
+ recompinput::set_game_input_description(recompinput::GameInput::DPAD_RIGHT, "Used for in-game menu navigation.");
}
-void zelda64::load_config() {
- detect_steam_deck();
-
- std::filesystem::path recomp_dir = zelda64::get_app_folder_path();
- std::filesystem::path general_path = recomp_dir / general_filename;
- std::filesystem::path graphics_path = recomp_dir / graphics_filename;
- std::filesystem::path controls_path = recomp_dir / controls_filename;
- std::filesystem::path sound_path = recomp_dir / sound_filename;
+void zelda64::init_config() {
+ std::filesystem::path recomp_dir = recompui::file::get_app_folder_path();
if (!recomp_dir.empty()) {
std::filesystem::create_directories(recomp_dir);
}
- // TODO error handling for failing to save config files after resetting them.
+ recompui::config::GeneralTabOptions general_options{};
+ general_options.has_rumble_strength = true;
+ general_options.has_gyro_sensitivity = false;
+ general_options.has_mouse_sensitivity = false;
- if (!load_general_config(general_path)) {
- // Set the general settings from an empty json to use defaults.
- set_general_settings_from_json({});
- save_general_config(general_path);
- }
+ auto &general_config = recompui::config::create_general_tab(general_options);
+ add_general_options(general_config);
- if (!load_graphics_config(graphics_path)) {
- reset_graphics_options();
- save_graphics_config(graphics_path);
- }
+ set_control_defaults();
+ set_control_descriptions();
+ recompui::config::create_controls_tab();
- if (!load_controls_config(controls_path)) {
- zelda64::reset_input_bindings();
- save_controls_config(controls_path);
- }
+ auto &graphics_config = recompui::config::create_graphics_tab();
+ add_graphics_options(graphics_config);
- if (!load_sound_config(sound_path)) {
- zelda64::reset_sound_settings();
- save_sound_config(sound_path);
- }
-}
-
-void zelda64::save_config() {
- std::filesystem::path recomp_dir = zelda64::get_app_folder_path();
+ auto &sound_config = recompui::config::create_sound_tab();
+ add_sound_options(sound_config);
- if (recomp_dir.empty()) {
- return;
- }
+ recompui::config::create_mods_tab();
- std::filesystem::create_directories(recomp_dir);
+ recompui::config::create_tab(
+ zelda64::debug::tab_name,
+ zelda64::debug::tab_id,
+ [](recompui::ContextId context, recompui::Element* parent) {
+ // TODO implement debug tab
+ }
+ );
- // TODO error handling for failing to save config files.
+ recompui::config::finalize();
- save_general_config(recomp_dir / general_filename);
- save_graphics_config(recomp_dir / graphics_filename);
- save_controls_config(recomp_dir / controls_filename);
- save_sound_config(recomp_dir / sound_filename);
+ recompui::config::set_tab_visible(zelda64::debug::tab_id, get_debug_mode_enabled());
}
diff --git a/src/game/controls.cpp b/src/game/controls.cpp
deleted file mode 100644
index 72380e4..0000000
--- a/src/game/controls.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-#include
-
-#include "librecomp/helpers.hpp"
-#include "recomp_input.h"
-#include "ultramodern/ultramodern.hpp"
-
-// Arrays that hold the mappings for every input for keyboard and controller respectively.
-using input_mapping = std::array;
-using input_mapping_array = std::array(recomp::GameInput::COUNT)>;
-static input_mapping_array keyboard_input_mappings{};
-static input_mapping_array controller_input_mappings{};
-
-// Make the button value array, which maps a button index to its bit field.
-#define DEFINE_INPUT(name, value, readable) uint16_t(value##u),
-static const std::array n64_button_values = {
- DEFINE_N64_BUTTON_INPUTS()
-};
-#undef DEFINE_INPUT
-
-// Make the input name array.
-#define DEFINE_INPUT(name, value, readable) readable,
-static const std::vector input_names = {
- DEFINE_ALL_INPUTS()
-};
-#undef DEFINE_INPUT
-
-// Make the input enum name array.
-#define DEFINE_INPUT(name, value, readable) #name,
-static const std::vector input_enum_names = {
- DEFINE_ALL_INPUTS()
-};
-#undef DEFINE_INPUT
-
-size_t recomp::get_num_inputs() {
- return (size_t)GameInput::COUNT;
-}
-
-const std::string& recomp::get_input_name(GameInput input) {
- return input_names.at(static_cast(input));
-}
-
-const std::string& recomp::get_input_enum_name(GameInput input) {
- return input_enum_names.at(static_cast(input));
-}
-
-recomp::GameInput recomp::get_input_from_enum_name(const std::string_view enum_name) {
- auto find_it = std::find(input_enum_names.begin(), input_enum_names.end(), enum_name);
- if (find_it == input_enum_names.end()) {
- return recomp::GameInput::COUNT;
- }
-
- return static_cast(find_it - input_enum_names.begin());
-}
-
-// Due to an RmlUi limitation this can't be const. Ideally it would return a const reference or even just a straight up copy.
-recomp::InputField& recomp::get_input_binding(GameInput input, size_t binding_index, recomp::InputDevice device) {
- input_mapping_array& device_mappings = (device == recomp::InputDevice::Controller) ? controller_input_mappings : keyboard_input_mappings;
- input_mapping& cur_input_mapping = device_mappings.at(static_cast(input));
-
- if (binding_index < cur_input_mapping.size()) {
- return cur_input_mapping[binding_index];
- }
- else {
- static recomp::InputField dummy_field = {};
- return dummy_field;
- }
-}
-
-void recomp::set_input_binding(recomp::GameInput input, size_t binding_index, recomp::InputDevice device, recomp::InputField value) {
- input_mapping_array& device_mappings = (device == recomp::InputDevice::Controller) ? controller_input_mappings : keyboard_input_mappings;
- input_mapping& cur_input_mapping = device_mappings.at(static_cast(input));
-
- if (binding_index < cur_input_mapping.size()) {
- cur_input_mapping[binding_index] = value;
- }
-}
-
-bool recomp::get_n64_input(int controller_num, uint16_t* buttons_out, float* x_out, float* y_out) {
- uint16_t cur_buttons = 0;
- float cur_x = 0.0f;
- float cur_y = 0.0f;
-
- if (controller_num != 0) {
- return false;
- }
-
- if (!recomp::game_input_disabled()) {
- for (size_t i = 0; i < n64_button_values.size(); i++) {
- size_t input_index = (size_t)GameInput::N64_BUTTON_START + i;
- cur_buttons |= recomp::get_input_digital(keyboard_input_mappings[input_index]) ? n64_button_values[i] : 0;
- cur_buttons |= recomp::get_input_digital(controller_input_mappings[input_index]) ? n64_button_values[i] : 0;
- }
-
- float joystick_deadzone = recomp::get_joystick_deadzone() / 100.0f;
-
- float joystick_x = recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::X_AXIS_POS])
- - recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::X_AXIS_NEG]);
-
- float joystick_y = recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::Y_AXIS_POS])
- - recomp::get_input_analog(controller_input_mappings[(size_t)GameInput::Y_AXIS_NEG]);
-
- recomp::apply_joystick_deadzone(joystick_x, joystick_y, &joystick_x, &joystick_y);
-
- cur_x = recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::X_AXIS_POS])
- - recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::X_AXIS_NEG]) + joystick_x;
-
- cur_y = recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::Y_AXIS_POS])
- - recomp::get_input_analog(keyboard_input_mappings[(size_t)GameInput::Y_AXIS_NEG]) + joystick_y;
- }
-
- *buttons_out = cur_buttons;
- *x_out = std::clamp(cur_x * 0.65f, -1.0f, 1.0f);
- *y_out = std::clamp(cur_y * 0.65f, -1.0f, 1.0f);
-
- return true;
-}
diff --git a/src/game/debug.cpp b/src/game/debug.cpp
deleted file mode 100644
index 4b58d87..0000000
--- a/src/game/debug.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include
-#include "zelda_debug.h"
-#include "librecomp/helpers.hpp"
-// #include "../patches/input.h"
-
-std::atomic pending_warp = 0xFFFF;
-std::atomic pending_set_time = 0xFFFF;
-
-void zelda64::do_warp(int area, int scene, int entrance) {
- const zelda64::SceneWarps game_scene = zelda64::game_warps[area].scenes[scene];
- int game_scene_index = game_scene.index;
- pending_warp.store(((game_scene_index & 0xFF) << 8) | ((entrance & 0x0F) << 4));
-}
-
-extern "C" void recomp_get_pending_warp(uint8_t* rdram, recomp_context* ctx) {
- // Return the current warp value and reset it.
- _return(ctx, pending_warp.exchange(0xFFFF));
-}
-
-void zelda64::set_time(uint8_t day, uint8_t hour, uint8_t minute) {
- pending_set_time.store((day << 16) | (uint16_t(hour) << 8) | minute);
-}
-
-extern "C" void recomp_get_pending_set_time(uint8_t* rdram, recomp_context* ctx) {
- // Return the current set time value and reset it.
- _return(ctx, pending_set_time.exchange(0xFFFF));
-}
diff --git a/src/game/input.cpp b/src/game/input.cpp
deleted file mode 100644
index 9456af0..0000000
--- a/src/game/input.cpp
+++ /dev/null
@@ -1,909 +0,0 @@
-#include
-#include
-
-#include "ultramodern/ultramodern.hpp"
-#include "recomp.h"
-#include "recomp_input.h"
-#include "zelda_config.h"
-#include "recomp_ui.h"
-#include "SDL.h"
-#include "promptfont.h"
-#include "GamepadMotion.hpp"
-
-constexpr float axis_threshold = 0.5f;
-
-struct ControllerState {
- SDL_GameController* controller;
- std::array latest_accelerometer;
- GamepadMotion motion;
- uint32_t prev_gyro_timestamp;
- ControllerState() : controller{}, latest_accelerometer{}, motion{}, prev_gyro_timestamp{} {
- motion.Reset();
- motion.SetCalibrationMode(GamepadMotionHelpers::CalibrationMode::Stillness | GamepadMotionHelpers::CalibrationMode::SensorFusion);
- };
-};
-
-static struct {
- const Uint8* keys = nullptr;
- SDL_Keymod keymod = SDL_Keymod::KMOD_NONE;
- int numkeys = 0;
- std::atomic_int32_t mouse_wheel_pos = 0;
- std::mutex cur_controllers_mutex;
- std::vector cur_controllers{};
- std::unordered_map controller_states;
-
- std::array rotation_delta{};
- std::array mouse_delta{};
- std::mutex pending_input_mutex;
- std::array pending_rotation_delta{};
- std::array pending_mouse_delta{};
-
- float cur_rumble;
- bool rumble_active;
-} InputState;
-
-static struct {
- std::list files_dropped;
-} DropState;
-
-std::atomic scanning_device = recomp::InputDevice::COUNT;
-std::atomic scanned_input;
-
-enum class InputType {
- None = 0, // Using zero for None ensures that default initialized InputFields are unbound.
- Keyboard,
- Mouse,
- ControllerDigital,
- ControllerAnalog // Axis input_id values are the SDL value + 1
-};
-
-void set_scanned_input(recomp::InputField value) {
- scanning_device.store(recomp::InputDevice::COUNT);
- scanned_input.store(value);
-}
-
-recomp::InputField recomp::get_scanned_input() {
- recomp::InputField ret = scanned_input.load();
- scanned_input.store({});
- return ret;
-}
-
-void recomp::start_scanning_input(recomp::InputDevice device) {
- scanned_input.store({});
- scanning_device.store(device);
-}
-
-void recomp::stop_scanning_input() {
- scanning_device.store(recomp::InputDevice::COUNT);
-}
-
-void queue_if_enabled(SDL_Event* event) {
- if (!recomp::all_input_disabled()) {
- recompui::queue_event(*event);
- }
-}
-
-static std::atomic_bool cursor_enabled = true;
-
-void recompui::set_cursor_visible(bool visible) {
- cursor_enabled.store(visible);
-}
-
-bool should_override_keystate(SDL_Scancode key, SDL_Keymod mod) {
- // Override Enter when Alt is held.
- if (key == SDL_Scancode::SDL_SCANCODE_RETURN) {
- if (mod & SDL_Keymod::KMOD_ALT) {
- return true;
- }
- }
-
- return false;
-}
-
-bool sdl_event_filter(void* userdata, SDL_Event* event) {
- switch (event->type) {
- case SDL_EventType::SDL_KEYDOWN:
- {
- SDL_KeyboardEvent* keyevent = &event->key;
-
- // Skip repeated events when not in the menu
- if (!recompui::is_context_capturing_input() &&
- event->key.repeat) {
- break;
- }
-
- if ((keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_RETURN && (keyevent->keysym.mod & SDL_Keymod::KMOD_ALT)) ||
- keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_F11
- ) {
- recompui::toggle_fullscreen();
- }
- if (scanning_device != recomp::InputDevice::COUNT) {
- if (keyevent->keysym.scancode == SDL_Scancode::SDL_SCANCODE_ESCAPE) {
- recomp::cancel_scanning_input();
- } else if (scanning_device == recomp::InputDevice::Keyboard) {
- set_scanned_input({(uint32_t)InputType::Keyboard, keyevent->keysym.scancode});
- }
- } else {
- if (!should_override_keystate(keyevent->keysym.scancode, static_cast(keyevent->keysym.mod))) {
- queue_if_enabled(event);
- }
- }
- }
- break;
- case SDL_EventType::SDL_CONTROLLERDEVICEADDED:
- {
- SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
- SDL_GameController* controller = SDL_GameControllerOpen(controller_event->which);
- printf("Controller added: %d\n", controller_event->which);
- if (controller != nullptr) {
- printf(" Instance ID: %d\n", SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller)));
- ControllerState& state = InputState.controller_states[SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))];
- state.controller = controller;
-
- if (SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_GYRO) && SDL_GameControllerHasSensor(controller, SDL_SensorType::SDL_SENSOR_ACCEL)) {
- SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_GYRO, SDL_TRUE);
- SDL_GameControllerSetSensorEnabled(controller, SDL_SensorType::SDL_SENSOR_ACCEL, SDL_TRUE);
- }
- }
- }
- break;
- case SDL_EventType::SDL_CONTROLLERDEVICEREMOVED:
- {
- SDL_ControllerDeviceEvent* controller_event = &event->cdevice;
- printf("Controller removed: %d\n", controller_event->which);
- InputState.controller_states.erase(controller_event->which);
- }
- break;
- case SDL_EventType::SDL_QUIT: {
- if (!ultramodern::is_game_started()) {
- ultramodern::quit();
- return true;
- }
-
- zelda64::open_quit_game_prompt();
- recompui::activate_mouse();
- break;
- }
- case SDL_EventType::SDL_MOUSEWHEEL:
- {
- SDL_MouseWheelEvent* wheel_event = &event->wheel;
- InputState.mouse_wheel_pos.fetch_add(wheel_event->y * (wheel_event->direction == SDL_MOUSEWHEEL_FLIPPED ? -1 : 1));
- }
- queue_if_enabled(event);
- break;
- case SDL_EventType::SDL_CONTROLLERBUTTONDOWN:
- if (scanning_device != recomp::InputDevice::COUNT) {
- auto menuToggleBinding0 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 0, recomp::InputDevice::Controller);
- auto menuToggleBinding1 = recomp::get_input_binding(recomp::GameInput::TOGGLE_MENU, 1, recomp::InputDevice::Controller);
- // note - magic number: 0 is InputType::None
- if ((menuToggleBinding0.input_type != 0 && event->cbutton.button == menuToggleBinding0.input_id) ||
- (menuToggleBinding1.input_type != 0 && event->cbutton.button == menuToggleBinding1.input_id)) {
- recomp::cancel_scanning_input();
- } else if (scanning_device == recomp::InputDevice::Controller) {
- SDL_ControllerButtonEvent* button_event = &event->cbutton;
- auto scanned_input_index = recomp::get_scanned_input_index();
- if ((scanned_input_index == static_cast(recomp::GameInput::TOGGLE_MENU) ||
- scanned_input_index == static_cast(recomp::GameInput::ACCEPT_MENU) ||
- scanned_input_index == static_cast(recomp::GameInput::APPLY_MENU)) && (
- button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP ||
- button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN ||
- button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT ||
- button_event->button == SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) {
- break;
- }
-
- set_scanned_input({(uint32_t)InputType::ControllerDigital, button_event->button});
- }
- } else {
- queue_if_enabled(event);
- }
- break;
- case SDL_EventType::SDL_CONTROLLERAXISMOTION:
- if (scanning_device == recomp::InputDevice::Controller) {
- auto scanned_input_index = recomp::get_scanned_input_index();
- if (scanned_input_index == static_cast(recomp::GameInput::TOGGLE_MENU) ||
- scanned_input_index == static_cast(recomp::GameInput::ACCEPT_MENU) ||
- scanned_input_index == static_cast(recomp::GameInput::APPLY_MENU)) {
- break;
- }
-
- SDL_ControllerAxisEvent* axis_event = &event->caxis;
- float axis_value = axis_event->value * (1/32768.0f);
- if (axis_value > axis_threshold) {
- SDL_Event set_stick_return_event;
- set_stick_return_event.type = SDL_USEREVENT;
- set_stick_return_event.user.code = axis_event->axis;
- set_stick_return_event.user.data1 = nullptr;
- set_stick_return_event.user.data2 = nullptr;
- recompui::queue_event(set_stick_return_event);
-
- set_scanned_input({(uint32_t)InputType::ControllerAnalog, axis_event->axis + 1});
- }
- else if (axis_value < -axis_threshold) {
- SDL_Event set_stick_return_event;
- set_stick_return_event.type = SDL_USEREVENT;
- set_stick_return_event.user.code = axis_event->axis;
- set_stick_return_event.user.data1 = nullptr;
- set_stick_return_event.user.data2 = nullptr;
- recompui::queue_event(set_stick_return_event);
-
- set_scanned_input({(uint32_t)InputType::ControllerAnalog, -axis_event->axis - 1});
- }
- } else {
- queue_if_enabled(event);
- }
- break;
- case SDL_EventType::SDL_CONTROLLERSENSORUPDATE:
- if (event->csensor.sensor == SDL_SensorType::SDL_SENSOR_ACCEL) {
- // Convert acceleration to g's.
- float x = event->csensor.data[0] / SDL_STANDARD_GRAVITY;
- float y = event->csensor.data[1] / SDL_STANDARD_GRAVITY;
- float z = event->csensor.data[2] / SDL_STANDARD_GRAVITY;
- ControllerState& state = InputState.controller_states[event->csensor.which];
- state.latest_accelerometer[0] = x;
- state.latest_accelerometer[1] = y;
- state.latest_accelerometer[2] = z;
- }
- else if (event->csensor.sensor == SDL_SensorType::SDL_SENSOR_GYRO) {
- // constexpr float gyro_threshold = 0.05f;
- // Convert rotational velocity to degrees per second.
- constexpr float rad_to_deg = 180.0f / M_PI;
- float x = event->csensor.data[0] * rad_to_deg;
- float y = event->csensor.data[1] * rad_to_deg;
- float z = event->csensor.data[2] * rad_to_deg;
- ControllerState& state = InputState.controller_states[event->csensor.which];
- uint64_t cur_timestamp = event->csensor.timestamp;
- uint32_t delta_ms = cur_timestamp - state.prev_gyro_timestamp;
- state.motion.ProcessMotion(x, y, z, state.latest_accelerometer[0], state.latest_accelerometer[1], state.latest_accelerometer[2], delta_ms * 0.001f);
- state.prev_gyro_timestamp = cur_timestamp;
-
- float rot_x = 0.0f;
- float rot_y = 0.0f;
- state.motion.GetPlayerSpaceGyro(rot_x, rot_y);
-
- {
- std::lock_guard lock{ InputState.pending_input_mutex };
- InputState.pending_rotation_delta[0] += rot_x;
- InputState.pending_rotation_delta[1] += rot_y;
- }
- }
- break;
- case SDL_EventType::SDL_MOUSEMOTION:
- if (!recomp::game_input_disabled()) {
- SDL_MouseMotionEvent* motion_event = &event->motion;
- std::lock_guard lock{ InputState.pending_input_mutex };
- InputState.pending_mouse_delta[0] += motion_event->xrel;
- InputState.pending_mouse_delta[1] += motion_event->yrel;
- }
- queue_if_enabled(event);
- break;
- case SDL_EventType::SDL_DROPBEGIN:
- DropState.files_dropped.clear();
- break;
- case SDL_EventType::SDL_DROPFILE:
- DropState.files_dropped.emplace_back(std::filesystem::path(std::u8string_view((const char8_t *)(event->drop.file))));
- SDL_free(event->drop.file);
- break;
- case SDL_EventType::SDL_DROPCOMPLETE:
- recompui::drop_files(DropState.files_dropped);
- break;
- case SDL_EventType::SDL_CONTROLLERBUTTONUP:
- // Always queue button up events to avoid missing them during binding.
- recompui::queue_event(*event);
- break;
- default:
- queue_if_enabled(event);
- break;
- }
- return false;
-}
-
-void recomp::handle_events() {
- SDL_Event cur_event;
- static bool started = false;
- static bool exited = false;
- while (SDL_PollEvent(&cur_event) && !exited) {
- exited = sdl_event_filter(nullptr, &cur_event);
-
- // Lock the cursor if all three conditions are true: mouse aiming is enabled, game input is not disabled, and the game has been started.
- bool cursor_locked = (recomp::get_mouse_sensitivity() != 0) && !recomp::game_input_disabled() && ultramodern::is_game_started();
-
- // Hide the cursor based on its enable state, but override visibility to false if the cursor is locked.
- bool cursor_visible = cursor_enabled;
- if (cursor_locked) {
- cursor_visible = false;
- }
-
- SDL_ShowCursor(cursor_visible ? SDL_ENABLE : SDL_DISABLE);
- SDL_SetRelativeMouseMode(cursor_locked ? SDL_TRUE : SDL_FALSE);
- }
-
- if (!started && ultramodern::is_game_started()) {
- started = true;
- recompui::process_game_started();
- }
-}
-
-constexpr SDL_GameControllerButton SDL_CONTROLLER_BUTTON_SOUTH = SDL_CONTROLLER_BUTTON_A;
-constexpr SDL_GameControllerButton SDL_CONTROLLER_BUTTON_EAST = SDL_CONTROLLER_BUTTON_B;
-constexpr SDL_GameControllerButton SDL_CONTROLLER_BUTTON_WEST = SDL_CONTROLLER_BUTTON_X;
-constexpr SDL_GameControllerButton SDL_CONTROLLER_BUTTON_NORTH = SDL_CONTROLLER_BUTTON_Y;
-
-const recomp::DefaultN64Mappings recomp::default_n64_keyboard_mappings = {
- .a = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_SPACE}
- },
- .b = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_LSHIFT}
- },
- .l = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_E}
- },
- .r = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_R}
- },
- .z = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_Q}
- },
- .start = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_RETURN}
- },
- .c_left = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_LEFT}
- },
- .c_right = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_RIGHT}
- },
- .c_up = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_UP}
- },
- .c_down = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_DOWN}
- },
- .dpad_left = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_J}
- },
- .dpad_right = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_L}
- },
- .dpad_up = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_I}
- },
- .dpad_down = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_K}
- },
- .analog_left = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_A}
- },
- .analog_right = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_D}
- },
- .analog_up = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_W}
- },
- .analog_down = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_S}
- },
- .toggle_menu = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_ESCAPE}
- },
- .accept_menu = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_RETURN}
- },
- .apply_menu = {
- {.input_type = (uint32_t)InputType::Keyboard, .input_id = SDL_SCANCODE_F}
- }
-};
-
-const recomp::DefaultN64Mappings recomp::default_n64_controller_mappings = {
- .a = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_SOUTH},
- },
- .b = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_WEST},
- },
- .l = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_LEFTSTICK},
- },
- .r = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER},
- },
- .z = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_LEFTSHOULDER},
- },
- .start = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_START},
- },
- .c_left = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_NORTH},
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_TRIGGERRIGHT + 1},
- },
- .c_right = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_RIGHTX + 1},
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_EAST},
- },
- .c_up = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = -(SDL_CONTROLLER_AXIS_RIGHTY + 1)},
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_RIGHTSTICK},
- },
- .c_down = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_EAST},
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_TRIGGERLEFT + 1},
- },
- .dpad_left = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_DPAD_LEFT},
- },
- .dpad_right = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
- },
- .dpad_up = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_DPAD_UP},
- },
- .dpad_down = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_DPAD_DOWN},
- },
- .analog_left = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = -(SDL_CONTROLLER_AXIS_LEFTX + 1)},
- },
- .analog_right = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_LEFTX + 1},
- },
- .analog_up = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = -(SDL_CONTROLLER_AXIS_LEFTY + 1)},
- },
- .analog_down = {
- {.input_type = (uint32_t)InputType::ControllerAnalog, .input_id = SDL_CONTROLLER_AXIS_LEFTY + 1},
- },
- .toggle_menu = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_BACK},
- },
- .accept_menu = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_SOUTH},
- },
- .apply_menu = {
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_WEST},
- {.input_type = (uint32_t)InputType::ControllerDigital, .input_id = SDL_CONTROLLER_BUTTON_START}
- }
-};
-
-void recomp::poll_inputs() {
- InputState.keys = SDL_GetKeyboardState(&InputState.numkeys);
- InputState.keymod = SDL_GetModState();
-
- {
- std::lock_guard lock{ InputState.cur_controllers_mutex };
- InputState.cur_controllers.clear();
-
- for (const auto& [id, state] : InputState.controller_states) {
- (void)id; // Avoid unused variable warning.
- SDL_GameController* controller = state.controller;
- if (controller != nullptr) {
- InputState.cur_controllers.push_back(controller);
- }
- }
- }
-
- // Read the deltas while resetting them to zero.
- {
- std::lock_guard lock{ InputState.pending_input_mutex };
-
- InputState.rotation_delta = InputState.pending_rotation_delta;
- InputState.pending_rotation_delta = { 0.0f, 0.0f };
-
- InputState.mouse_delta = InputState.pending_mouse_delta;
- InputState.pending_mouse_delta = { 0.0f, 0.0f };
- }
-
- // Quicksaving is disabled for now and will likely have more limited functionality
- // when restored, rather than allowing saving and loading at any point in time.
- #if 0
- if (InputState.keys) {
- static bool save_was_held = false;
- static bool load_was_held = false;
- bool save_is_held = InputState.keys[SDL_SCANCODE_F5] != 0;
- bool load_is_held = InputState.keys[SDL_SCANCODE_F7] != 0;
- if (save_is_held && !save_was_held) {
- zelda64::quicksave_save();
- }
- else if (load_is_held && !load_was_held) {
- zelda64::quicksave_load();
- }
- save_was_held = save_is_held;
- }
- #endif
-}
-
-void recomp::set_rumble(int controller_num, bool on) {
- if (controller_num == 0) {
- InputState.rumble_active = on;
- }
-}
-
-ultramodern::input::connected_device_info_t recomp::get_connected_device_info(int controller_num) {
- switch (controller_num) {
- case 0:
- return ultramodern::input::connected_device_info_t {
- .connected_device = ultramodern::input::Device::Controller,
- .connected_pak = ultramodern::input::Pak::RumblePak,
- };
- }
-
- return ultramodern::input::connected_device_info_t {
- .connected_device = ultramodern::input::Device::None,
- .connected_pak = ultramodern::input::Pak::None,
- };
-}
-
-static float smoothstep(float from, float to, float amount) {
- amount = (amount * amount) * (3.0f - 2.0f * amount);
- return std::lerp(from, to, amount);
-}
-
-// Update rumble to attempt to mimic the way n64 rumble ramps up and falls off
-void recomp::update_rumble() {
- // Note: values are not accurate! just approximations based on feel
- if (InputState.rumble_active) {
- InputState.cur_rumble += 0.17f;
- if (InputState.cur_rumble > 1) InputState.cur_rumble = 1;
- } else {
- InputState.cur_rumble *= 0.92f;
- InputState.cur_rumble -= 0.01f;
- if (InputState.cur_rumble < 0) InputState.cur_rumble = 0;
- }
- float smooth_rumble = smoothstep(0, 1, InputState.cur_rumble);
-
- uint16_t rumble_strength = smooth_rumble * (recomp::get_rumble_strength() * 0xFFFF / 100);
- uint32_t duration = 1000000; // Dummy duration value that lasts long enough to matter as the game will reset rumble on its own.
- {
- std::lock_guard lock{ InputState.cur_controllers_mutex };
- for (const auto& controller : InputState.cur_controllers) {
- SDL_GameControllerRumble(controller, 0, rumble_strength, duration);
- }
- }
-}
-
-bool controller_button_state(int32_t input_id) {
- if (input_id >= 0 && input_id < SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MAX) {
- SDL_GameControllerButton button = (SDL_GameControllerButton)input_id;
- bool ret = false;
- {
- std::lock_guard lock{ InputState.cur_controllers_mutex };
- for (const auto& controller : InputState.cur_controllers) {
- ret |= SDL_GameControllerGetButton(controller, button);
- }
- }
-
- return ret;
- }
- return false;
-}
-
-static std::atomic_bool right_analog_suppressed = false;
-
-float controller_axis_state(int32_t input_id, bool allow_suppression) {
- if (abs(input_id) - 1 < SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_MAX) {
- SDL_GameControllerAxis axis = (SDL_GameControllerAxis)(abs(input_id) - 1);
- bool negative_range = input_id < 0;
- float ret = 0.0f;
-
- {
- std::lock_guard lock{ InputState.cur_controllers_mutex };
- for (const auto& controller : InputState.cur_controllers) {
- float cur_val = SDL_GameControllerGetAxis(controller, axis) * (1/32768.0f);
- if (negative_range) {
- cur_val = -cur_val;
- }
-
- // Check if this input is a right analog axis and suppress it accordingly.
- if (allow_suppression && right_analog_suppressed.load() &&
- (axis == SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX || axis == SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY)) {
- cur_val = 0;
- }
- ret += std::clamp(cur_val, 0.0f, 1.0f);
- }
- }
-
- return std::clamp(ret, 0.0f, 1.0f);
- }
- return false;
-}
-
-float recomp::get_input_analog(const recomp::InputField& field) {
- switch ((InputType)field.input_type) {
- case InputType::Keyboard:
- if (InputState.keys && field.input_id >= 0 && field.input_id < InputState.numkeys) {
- if (should_override_keystate(static_cast(field.input_id), InputState.keymod)) {
- return 0.0f;
- }
- return InputState.keys[field.input_id] ? 1.0f : 0.0f;
- }
- return 0.0f;
- case InputType::ControllerDigital:
- return controller_button_state(field.input_id) ? 1.0f : 0.0f;
- case InputType::ControllerAnalog:
- return controller_axis_state(field.input_id, true);
- case InputType::Mouse:
- // TODO mouse support
- return 0.0f;
- case InputType::None:
- return false;
- }
-}
-
-float recomp::get_input_analog(const std::span fields) {
- float ret = 0.0f;
- for (const auto& field : fields) {
- ret += get_input_analog(field);
- }
- return std::clamp(ret, 0.0f, 1.0f);
-}
-
-bool recomp::get_input_digital(const recomp::InputField& field) {
- switch ((InputType)field.input_type) {
- case InputType::Keyboard:
- if (InputState.keys && field.input_id >= 0 && field.input_id < InputState.numkeys) {
- if (should_override_keystate(static_cast(field.input_id), InputState.keymod)) {
- return false;
- }
- return InputState.keys[field.input_id] != 0;
- }
- return false;
- case InputType::ControllerDigital:
- return controller_button_state(field.input_id);
- case InputType::ControllerAnalog:
- // TODO adjustable threshold
- return controller_axis_state(field.input_id, true) >= axis_threshold;
- case InputType::Mouse:
- // TODO mouse support
- return false;
- case InputType::None:
- return false;
- }
-}
-
-bool recomp::get_input_digital(const std::span fields) {
- bool ret = 0;
- for (const auto& field : fields) {
- ret |= get_input_digital(field);
- }
- return ret;
-}
-
-void recomp::get_gyro_deltas(float* x, float* y) {
- std::array cur_rotation_delta = InputState.rotation_delta;
- float sensitivity = (float)recomp::get_gyro_sensitivity() / 100.0f;
- *x = cur_rotation_delta[0] * sensitivity;
- *y = cur_rotation_delta[1] * sensitivity;
-}
-
-void recomp::get_mouse_deltas(float* x, float* y) {
- std::array cur_mouse_delta = InputState.mouse_delta;
- float sensitivity = (float)recomp::get_mouse_sensitivity() / 100.0f;
- *x = cur_mouse_delta[0] * sensitivity;
- *y = cur_mouse_delta[1] * sensitivity;
-}
-
-void recomp::apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out) {
- float joystick_deadzone = (float)recomp::get_joystick_deadzone() / 100.0f;
-
- if(fabsf(x_in) < joystick_deadzone) {
- x_in = 0.0f;
- }
- else {
- if(x_in > 0.0f) {
- x_in -= joystick_deadzone;
- }
- else {
- x_in += joystick_deadzone;
- }
-
- x_in /= (1.0f - joystick_deadzone);
- }
-
- if(fabsf(y_in) < joystick_deadzone) {
- y_in = 0.0f;
- }
- else {
- if(y_in > 0.0f) {
- y_in -= joystick_deadzone;
- }
- else {
- y_in += joystick_deadzone;
- }
-
- y_in /= (1.0f - joystick_deadzone);
- }
-
- *x_out = x_in;
- *y_out = y_in;
-}
-
-void recomp::get_right_analog(float* x, float* y) {
- float x_val =
- controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1), false) -
- controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX + 1), false);
- float y_val =
- controller_axis_state((SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1), false) -
- controller_axis_state(-(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY + 1), false);
- recomp::apply_joystick_deadzone(x_val, y_val, x, y);
-}
-
-void recomp::set_right_analog_suppressed(bool suppressed) {
- right_analog_suppressed.store(suppressed);
-}
-
-bool recomp::game_input_disabled() {
- // Disable input if any menu that blocks input is open.
- return recompui::is_context_capturing_input();
-}
-
-bool recomp::all_input_disabled() {
- // Disable all input if an input is being polled.
- return scanning_device != recomp::InputDevice::COUNT;
-}
-
-std::string controller_button_to_string(SDL_GameControllerButton button) {
- switch (button) {
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A:
- return PF_GAMEPAD_A;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B:
- return PF_GAMEPAD_B;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_X:
- return PF_GAMEPAD_X;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_Y:
- return PF_GAMEPAD_Y;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_BACK:
- return PF_XBOX_VIEW;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_GUIDE:
- return PF_GAMEPAD_HOME;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_START:
- return PF_XBOX_MENU;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSTICK:
- return PF_ANALOG_L_CLICK;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSTICK:
- return PF_ANALOG_R_CLICK;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
- return PF_XBOX_LEFT_SHOULDER;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
- return PF_XBOX_RIGHT_SHOULDER;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP:
- return PF_DPAD_UP;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN:
- return PF_DPAD_DOWN;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT:
- return PF_DPAD_LEFT;
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
- return PF_DPAD_RIGHT;
- // case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_MISC1:
- // return "";
- // case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE1:
- // return "";
- // case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE2:
- // return "";
- // case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE3:
- // return "";
- // case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_PADDLE4:
- // return "";
- case SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_TOUCHPAD:
- return PF_SONY_TOUCHPAD;
- default:
- return "Button " + std::to_string(button);
- }
-}
-
-std::unordered_map scancode_codepoints {
- {SDL_SCANCODE_LEFT, PF_KEYBOARD_LEFT},
- // NOTE: UP and RIGHT are swapped with promptfont.
- {SDL_SCANCODE_UP, PF_KEYBOARD_RIGHT},
- {SDL_SCANCODE_RIGHT, PF_KEYBOARD_UP},
- {SDL_SCANCODE_DOWN, PF_KEYBOARD_DOWN},
- {SDL_SCANCODE_A, PF_KEYBOARD_A},
- {SDL_SCANCODE_B, PF_KEYBOARD_B},
- {SDL_SCANCODE_C, PF_KEYBOARD_C},
- {SDL_SCANCODE_D, PF_KEYBOARD_D},
- {SDL_SCANCODE_E, PF_KEYBOARD_E},
- {SDL_SCANCODE_F, PF_KEYBOARD_F},
- {SDL_SCANCODE_G, PF_KEYBOARD_G},
- {SDL_SCANCODE_H, PF_KEYBOARD_H},
- {SDL_SCANCODE_I, PF_KEYBOARD_I},
- {SDL_SCANCODE_J, PF_KEYBOARD_J},
- {SDL_SCANCODE_K, PF_KEYBOARD_K},
- {SDL_SCANCODE_L, PF_KEYBOARD_L},
- {SDL_SCANCODE_M, PF_KEYBOARD_M},
- {SDL_SCANCODE_N, PF_KEYBOARD_N},
- {SDL_SCANCODE_O, PF_KEYBOARD_O},
- {SDL_SCANCODE_P, PF_KEYBOARD_P},
- {SDL_SCANCODE_Q, PF_KEYBOARD_Q},
- {SDL_SCANCODE_R, PF_KEYBOARD_R},
- {SDL_SCANCODE_S, PF_KEYBOARD_S},
- {SDL_SCANCODE_T, PF_KEYBOARD_T},
- {SDL_SCANCODE_U, PF_KEYBOARD_U},
- {SDL_SCANCODE_V, PF_KEYBOARD_V},
- {SDL_SCANCODE_W, PF_KEYBOARD_W},
- {SDL_SCANCODE_X, PF_KEYBOARD_X},
- {SDL_SCANCODE_Y, PF_KEYBOARD_Y},
- {SDL_SCANCODE_Z, PF_KEYBOARD_Z},
- {SDL_SCANCODE_0, PF_KEYBOARD_0},
- {SDL_SCANCODE_1, PF_KEYBOARD_1},
- {SDL_SCANCODE_2, PF_KEYBOARD_2},
- {SDL_SCANCODE_3, PF_KEYBOARD_3},
- {SDL_SCANCODE_4, PF_KEYBOARD_4},
- {SDL_SCANCODE_5, PF_KEYBOARD_5},
- {SDL_SCANCODE_6, PF_KEYBOARD_6},
- {SDL_SCANCODE_7, PF_KEYBOARD_7},
- {SDL_SCANCODE_8, PF_KEYBOARD_8},
- {SDL_SCANCODE_9, PF_KEYBOARD_9},
- {SDL_SCANCODE_ESCAPE, PF_KEYBOARD_ESCAPE},
- {SDL_SCANCODE_F1, PF_KEYBOARD_F1},
- {SDL_SCANCODE_F2, PF_KEYBOARD_F2},
- {SDL_SCANCODE_F3, PF_KEYBOARD_F3},
- {SDL_SCANCODE_F4, PF_KEYBOARD_F4},
- {SDL_SCANCODE_F5, PF_KEYBOARD_F5},
- {SDL_SCANCODE_F6, PF_KEYBOARD_F6},
- {SDL_SCANCODE_F7, PF_KEYBOARD_F7},
- {SDL_SCANCODE_F8, PF_KEYBOARD_F8},
- {SDL_SCANCODE_F9, PF_KEYBOARD_F9},
- {SDL_SCANCODE_F10, PF_KEYBOARD_F10},
- {SDL_SCANCODE_F11, PF_KEYBOARD_F11},
- {SDL_SCANCODE_F12, PF_KEYBOARD_F12},
- {SDL_SCANCODE_PRINTSCREEN, PF_KEYBOARD_PRINT_SCREEN},
- {SDL_SCANCODE_SCROLLLOCK, PF_KEYBOARD_SCROLL_LOCK},
- {SDL_SCANCODE_PAUSE, PF_KEYBOARD_PAUSE},
- {SDL_SCANCODE_INSERT, PF_KEYBOARD_INSERT},
- {SDL_SCANCODE_HOME, PF_KEYBOARD_HOME},
- {SDL_SCANCODE_PAGEUP, PF_KEYBOARD_PAGE_UP},
- {SDL_SCANCODE_DELETE, PF_KEYBOARD_DELETE},
- {SDL_SCANCODE_END, PF_KEYBOARD_END},
- {SDL_SCANCODE_PAGEDOWN, PF_KEYBOARD_PAGE_DOWN},
- {SDL_SCANCODE_SPACE, PF_KEYBOARD_SPACE},
- {SDL_SCANCODE_BACKSPACE, PF_KEYBOARD_BACKSPACE},
- {SDL_SCANCODE_TAB, PF_KEYBOARD_TAB},
- {SDL_SCANCODE_RETURN, PF_KEYBOARD_ENTER},
- {SDL_SCANCODE_CAPSLOCK, PF_KEYBOARD_CAPS},
- {SDL_SCANCODE_NUMLOCKCLEAR, PF_KEYBOARD_NUM_LOCK},
- {SDL_SCANCODE_LSHIFT, "L" PF_KEYBOARD_SHIFT},
- {SDL_SCANCODE_RSHIFT, "R" PF_KEYBOARD_SHIFT},
-};
-
-std::string keyboard_input_to_string(SDL_Scancode key) {
- if (scancode_codepoints.find(key) != scancode_codepoints.end()) {
- return scancode_codepoints[key];
- }
- return std::to_string(key);
-}
-
-std::string controller_axis_to_string(int axis) {
- bool positive = axis > 0;
- SDL_GameControllerAxis actual_axis = SDL_GameControllerAxis(abs(axis) - 1);
- switch (actual_axis) {
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX:
- return positive ? "\u21C0" : "\u21BC";
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY:
- return positive ? "\u21C2" : "\u21BE";
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTX:
- return positive ? "\u21C1" : "\u21BD";
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_RIGHTY:
- return positive ? "\u21C3" : "\u21BF";
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERLEFT:
- return positive ? "\u2196" : "\u21DC";
- case SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
- return positive ? "\u2197" : "\u21DD";
- default:
- return "Axis " + std::to_string(actual_axis) + (positive ? '+' : '-');
- }
-}
-
-std::string recomp::InputField::to_string() const {
- switch ((InputType)input_type) {
- case InputType::None:
- return "";
- case InputType::ControllerDigital:
- return controller_button_to_string((SDL_GameControllerButton)input_id);
- case InputType::ControllerAnalog:
- return controller_axis_to_string(input_id);
- case InputType::Keyboard:
- return keyboard_input_to_string((SDL_Scancode)input_id);
- default:
- return std::to_string(input_type) + "," + std::to_string(input_id);
- }
-}
diff --git a/src/game/quicksaving.cpp b/src/game/quicksaving.cpp
deleted file mode 100644
index 05c36a5..0000000
--- a/src/game/quicksaving.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Quicksaving is disabled for now
-
-#if 0
-
-#include "librecomp/helpers.hpp"
-#include "librecomp/input.hpp"
-#include "ultramodern/ultramodern.hpp"
-
-enum class QuicksaveAction {
- None,
- Save,
- Load
-};
-
-std::atomic cur_quicksave_action = QuicksaveAction::None;
-
-void zelda64::quicksave_save() {
- cur_quicksave_action.store(QuicksaveAction::Save);
-}
-
-void zelda64::quicksave_load() {
- cur_quicksave_action.store(QuicksaveAction::Load);
-}
-
-uint8_t saved_rdram[ultramodern::rdram_size];
-
-thread_local recomp_context saved_context;
-
-void save_context(recomp_context* ctx) {
- saved_context = *ctx;
-}
-
-void load_context(recomp_context* ctx) {
- *ctx = saved_context;
-
- // Restore the pointer to the odd floats for correctly handling mips3 float mode.
- if (ctx->mips3_float_mode) {
- // FR = 1, odd single floats point to their own registers
- ctx->f_odd = &ctx->f1.u32l;
- }
- else {
- // FR = 0, odd single floats point to the upper half of the previous register
- ctx->f_odd = &ctx->f0.u32h;
- }
-}
-
-extern "C" void recomp_handle_quicksave_actions(uint8_t* rdram, recomp_context* ctx) {
- QuicksaveAction action = cur_quicksave_action.load();
-
- if (action != QuicksaveAction::None) {
- PTR(OSMesgQueue) quicksave_enter_mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx);
- PTR(OSMesgQueue) quicksave_exit_mq = _arg<1, PTR(OSMesgQueue)>(rdram, ctx);
-
- printf("saving context for thread %d\n", TO_PTR(OSThread, ultramodern::this_thread())->id);
-
- // Save or load the thread's context as needed based on the action.
- if (action == QuicksaveAction::Save) {
- save_context(ctx);
- }
- else if (action == QuicksaveAction::Load) {
- load_context(ctx);
- }
- else {
- assert(false);
- }
-
- // Tell the main thread that one of the other permanent threads is ready for performing a quicksave action.
- osSendMesg(rdram, quicksave_enter_mq, NULLPTR, OS_MESG_NOBLOCK);
- // Wait for the main thread to signal that other permanent threads are safe to continue.
- osRecvMesg(rdram, quicksave_exit_mq, NULLPTR, OS_MESG_BLOCK);
- }
-}
-
-extern "C" void wake_threads_for_quicksave_action(uint8_t* rdram, recomp_context* ctx);
-
-extern "C" void recomp_handle_quicksave_actions_main(uint8_t* rdram, recomp_context* ctx) {
- QuicksaveAction action = cur_quicksave_action.load();
-
- if (action != QuicksaveAction::None) {
- PTR(OSMesgQueue) quicksave_enter_mq = _arg<0, PTR(OSMesgQueue)>(rdram, ctx);
- PTR(OSMesgQueue) quicksave_exit_mq = _arg<1, PTR(OSMesgQueue)>(rdram, ctx);
-
- wake_threads_for_quicksave_action(rdram, ctx);
-
- // Wait for all other permanent threads (hence the minus 1) to signal that they're ready for a quicksave action.
- for (uint32_t i = 0; i < ultramodern::permanent_thread_count() - 1; i++) {
- osRecvMesg(rdram, quicksave_enter_mq, NULLPTR, OS_MESG_BLOCK);
- }
-
- // Allow any temporary threads to complete by lowering this thread's priority to 0.
- // TODO this won't cause all temporary threads to complete if any are blocked by permanent threads
- // or events like timers. Situations like that will need to be handed on a case-by-case basis for a given game.
- if (ultramodern::temporary_thread_count() != 0) {
- OSPri old_pri = osGetThreadPri(rdram, NULLPTR);
- osSetThreadPri(rdram, NULLPTR, 0);
-
- osSetThreadPri(rdram, NULLPTR, old_pri);
- }
-
- if (action == QuicksaveAction::Save) {
- std::copy(rdram, rdram + ultramodern::rdram_size, saved_rdram);
- }
- else if (action == QuicksaveAction::Load) {
- std::copy(saved_rdram, saved_rdram + ultramodern::rdram_size, rdram);
- }
- else {
- assert(false);
- }
-
- printf("Quicksave action complete\n");
-
- cur_quicksave_action.store(QuicksaveAction::None);
-
- // Tell all other permanent threads that they're good to continue.
- for (uint32_t i = 0; i < ultramodern::permanent_thread_count() - 1; i++) {
- osSendMesg(rdram, quicksave_exit_mq, NULLPTR, OS_MESG_BLOCK);
- }
- }
-}
-
-#endif
diff --git a/src/game/recomp_actor_api.cpp b/src/game/recomp_actor_api.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/src/game/recomp_api.cpp b/src/game/recomp_api.cpp
index 5777a04..3d30a89 100644
--- a/src/game/recomp_api.cpp
+++ b/src/game/recomp_api.cpp
@@ -3,9 +3,9 @@
#include "recomp.h"
#include "librecomp/overlays.hpp"
#include "zelda_config.h"
-#include "recomp_input.h"
-#include "recomp_ui.h"
-#include "zelda_render.h"
+#include "recompinput/recompinput.h"
+#include "recompui/recompui.h"
+#include "recompui/renderer.h"
#include "zelda_sound.h"
#include "librecomp/helpers.hpp"
// #include "../patches/input.h"
@@ -15,20 +15,20 @@
#include "ultramodern/config.hpp"
extern "C" void recomp_update_inputs(uint8_t* rdram, recomp_context* ctx) {
- recomp::poll_inputs();
+ recompinput::poll_inputs();
}
extern "C" void sqrtf_recomp(uint8_t* rdram, recomp_context* ctx) {
ctx->f0.fl = sqrtf(ctx->f12.fl);
}
-extern "C" void __ll_rshift_recomp(uint8_t * rdram, recomp_context * ctx) {
+extern "C" void __ll_rshift_recomp(uint8_t* rdram, recomp_context* ctx) {
int64_t a = (ctx->r4 << 32) | ((ctx->r5 << 0) & 0xFFFFFFFFu);
int64_t b = (ctx->r6 << 32) | ((ctx->r7 << 0) & 0xFFFFFFFFu);
int64_t ret = a >> b;
- ctx->r2 = (int32_t)(ret >> 32);
- ctx->r3 = (int32_t)(ret >> 0);
+ ctx->r2 = (int32_t) (ret >> 32);
+ ctx->r3 = (int32_t) (ret >> 0);
}
extern "C" void recomp_puts(uint8_t* rdram, recomp_context* ctx) {
@@ -36,7 +36,7 @@ extern "C" void recomp_puts(uint8_t* rdram, recomp_context* ctx) {
u32 length = _arg<1, u32>(rdram, ctx);
for (u32 i = 0; i < length; i++) {
- fputc(MEM_B(i, (gpr)cur_str), stdout);
+ fputc(MEM_B(i, (gpr) cur_str), stdout);
}
}
@@ -48,14 +48,14 @@ extern "C" void recomp_get_gyro_deltas(uint8_t* rdram, recomp_context* ctx) {
float* x_out = _arg<0, float*>(rdram, ctx);
float* y_out = _arg<1, float*>(rdram, ctx);
- recomp::get_gyro_deltas(x_out, y_out);
+ recompinput::get_gyro_deltas(0, x_out, y_out);
}
extern "C" void recomp_get_mouse_deltas(uint8_t* rdram, recomp_context* ctx) {
float* x_out = _arg<0, float*>(rdram, ctx);
float* y_out = _arg<1, float*>(rdram, ctx);
- recomp::get_mouse_deltas(x_out, y_out);
+ recompinput::get_mouse_deltas(x_out, y_out);
}
extern "C" void recomp_powf(uint8_t* rdram, recomp_context* ctx) {
@@ -78,8 +78,8 @@ extern "C" void recomp_get_window_resolution(uint8_t* rdram, recomp_context* ctx
gpr width_out = _arg<0, PTR(u32)>(rdram, ctx);
gpr height_out = _arg<1, PTR(u32)>(rdram, ctx);
- MEM_W(0, width_out) = (u32)width;
- MEM_W(0, height_out) = (u32)height;
+ MEM_W(0, width_out) = (u32) width;
+ MEM_W(0, height_out) = (u32) height;
}
extern "C" void recomp_get_target_aspect_ratio(uint8_t* rdram, recomp_context* ctx) {
@@ -99,9 +99,11 @@ extern "C" void recomp_get_target_aspect_ratio(uint8_t* rdram, recomp_context* c
}
}
+#if 0
extern "C" void recomp_get_targeting_mode(uint8_t* rdram, recomp_context* ctx) {
- _return(ctx, static_cast(zelda64::get_targeting_mode()));
+ _return(ctx, static_cast(zelda64::get_invert_y_axis_mode()));
}
+#endif
extern "C" void recomp_get_bgm_volume(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, zelda64::get_bgm_volume() / 100.0f);
@@ -115,19 +117,22 @@ extern "C" void recomp_get_voice_volume(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, zelda64::get_voice_volume() / 100.0f);
}
+#if 0
extern "C" void recomp_get_low_health_beeps_enabled(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast(zelda64::get_low_health_beeps_enabled()));
}
+#endif
extern "C" void recomp_time_us(uint8_t* rdram, recomp_context* ctx) {
- _return(ctx, static_cast(std::chrono::duration_cast(ultramodern::time_since_start()).count()));
+ _return(ctx, static_cast(
+ std::chrono::duration_cast(ultramodern::time_since_start()).count()));
}
extern "C" void recomp_get_film_grain_enabled(uint8_t* rdram, recomp_context* ctx) {
_return(ctx, static_cast(zelda64::get_film_grain_mode() == zelda64::FilmGrainMode::On));
}
-extern "C" void recomp_load_overlays(uint8_t * rdram, recomp_context * ctx) {
+extern "C" void recomp_load_overlays(uint8_t* rdram, recomp_context* ctx) {
u32 rom = _arg<0, u32>(rdram, ctx);
PTR(void) ram = _arg<1, PTR(void)>(rdram, ctx);
u32 size = _arg<2, u32>(rdram, ctx);
@@ -135,8 +140,8 @@ extern "C" void recomp_load_overlays(uint8_t * rdram, recomp_context * ctx) {
load_overlays(rom, ram, size);
}
-extern "C" void recomp_high_precision_fb_enabled(uint8_t * rdram, recomp_context * ctx) {
- _return(ctx, static_cast(zelda64::renderer::RT64HighPrecisionFBEnabled()));
+extern "C" void recomp_high_precision_fb_enabled(uint8_t* rdram, recomp_context* ctx) {
+ _return(ctx, static_cast(recompui::renderer::RT64HighPrecisionFBEnabled()));
}
extern "C" void recomp_get_resolution_scale(uint8_t* rdram, recomp_context* ctx) {
@@ -147,28 +152,28 @@ extern "C" void recomp_get_inverted_axes(uint8_t* rdram, recomp_context* ctx) {
s32* x_out = _arg<0, s32*>(rdram, ctx);
s32* y_out = _arg<1, s32*>(rdram, ctx);
- zelda64::RadioBoxMode mode = zelda64::get_radio_comm_box_mode();
+ // zelda64::RadioBoxMode mode = zelda64::get_radio_comm_box_mode();
// *x_out = (mode == zelda64::AimInvertMode::InvertX || mode == zelda64::AimInvertMode::InvertBoth);
// *y_out = (mode == zelda64::AimInvertMode::InvertY || mode == zelda64::AimInvertMode::InvertBoth);
}
extern "C" void recomp_get_radio_comm_box_mode(uint8_t* rdram, recomp_context* ctx) {
- _return(ctx, zelda64::get_radio_comm_box_mode() == zelda64::RadioBoxMode::Expand);
+ _return(ctx, static_cast(zelda64::get_radio_comm_mode() == zelda64::RadioCommBoxMode::Expand));
}
extern "C" void recomp_get_analog_inverted_axes(uint8_t* rdram, recomp_context* ctx) {
s32* x_out = _arg<0, s32*>(rdram, ctx);
s32* y_out = _arg<1, s32*>(rdram, ctx);
- zelda64::AimInvertMode mode = zelda64::get_analog_camera_invert_mode();
+ // zelda64::AimInvertMode mode = zelda64::get_analog_camera_invert_mode();
// *x_out = (mode == zelda64::AimInvertMode::InvertX || mode == zelda64::AimInvertMode::InvertBoth);
// *y_out = (mode == zelda64::AimInvertMode::InvertY || mode == zelda64::AimInvertMode::InvertBoth);
}
extern "C" void recomp_get_invert_y_axis_mode(uint8_t* rdram, recomp_context* ctx) {
- _return(ctx, zelda64::get_invert_y_axis_mode() == zelda64::AimInvertMode::On);
+ _return(ctx, zelda64::get_invert_y_axis_mode() == zelda64::InvertYAxisMode::On);
}
extern "C" void recomp_get_camera_inputs(uint8_t* rdram, recomp_context* ctx) {
@@ -180,15 +185,15 @@ extern "C" void recomp_get_camera_inputs(uint8_t* rdram, recomp_context* ctx) {
float x, y;
- recomp::get_right_analog(&x, &y);
+ // TODO: Use controller number.
+ recompinput::get_right_analog(0, &x, &y);
float magnitude = sqrtf(x * x + y * y);
if (magnitude < radial_deadzone) {
*x_out = 0.0f;
*y_out = 0.0f;
- }
- else {
+ } else {
float x_normalized = x / magnitude;
float y_normalized = y / magnitude;
@@ -200,5 +205,5 @@ extern "C" void recomp_get_camera_inputs(uint8_t* rdram, recomp_context* ctx) {
extern "C" void recomp_set_right_analog_suppressed(uint8_t* rdram, recomp_context* ctx) {
s32 suppressed = _arg<0, s32>(rdram, ctx);
- recomp::set_right_analog_suppressed(suppressed);
+ recompinput::set_right_analog_suppressed(suppressed);
}
diff --git a/src/game/recomp_data_api.cpp b/src/game/recomp_data_api.cpp
index 2557abf..6aa5621 100644
--- a/src/game/recomp_data_api.cpp
+++ b/src/game/recomp_data_api.cpp
@@ -5,7 +5,7 @@
#include "slot_map.h"
#include "recomp_data.h"
-#include "recomp_ui.h"
+#include "recompui/recompui.h"
#include "librecomp/helpers.hpp"
#include "librecomp/overlays.hpp"
#include "librecomp/addresses.hpp"
diff --git a/src/game/scene_table.cpp b/src/game/scene_table.cpp
deleted file mode 100644
index af24c7b..0000000
--- a/src/game/scene_table.cpp
+++ /dev/null
@@ -1,851 +0,0 @@
-#include
-#include
-#include
-#include "zelda_debug.h"
-
-std::vector zelda64::game_warps {
- { "Clock Town", {
- {
- 0, "Mayor's Residence", {
- "Entrance",
- "Post Couple's Mask",
- }
- },
- {
- 8, "Honey & Darling's Shop", {
- "Entrance",
- }
- },
- {
- 14, "Curiosity Shop", {
- "Entrance",
- "Back Entrance",
- "Peephole",
- "Exiting peephole",
- }
- },
- {
- 36, "Milk Bar", {
- "Entrance",
- }
- },
- {
- 40, "Treasure Chest Shop", {
- "Entrance",
- "After game",
- }
- },
- {
- 44, "Clock Tower Roof", {
- "Entrance",
- "After cutscene"
- }
- },
- {
- 54, "Deku Scrub Playground", {
- "Entrance",
- "Game Finished",
- }
- },
- {
- 58, "Shooting Gallery", {
- "Entrance (with label)",
- "Entrance",
- }
- },
- {
- 86, "Post Office", {
- "Entrance",
- }
- },
- {
- 98, "Trading Post", {
- "Entrance (with label)",
- "Entrance",
- }
- },
- {
- 108, "Lottery Shop", {
- "Entrance",
- }
- },
- {
- 162, "Swordsman's School", {
- "Entrance",
- }
- },
- {
- 188, "Stock Pot Inn", {
- "Front entrance",
- "From balcony",
- "Near granny",
- "Kitchen",
- "Anju and Anju's mother cutscene",
- "After Anju cutscene",
- }
- },
- {
- 192, "Clock Tower", {
- "From lost woods (cutscene)",
- "Clock Town entrance",
- "After learning song of healing",
- "After moon falls",
- "First song of time cutscene",
- "From lost woods",
- "Happy Mask Salesman cutscene",
- }
- },
- {
- 202, "Bomb Shop", {
- "Entrance (with label)",
- "Entrance",
- }
- },
- {
- 210, "East Clock Town", {
- "From Termina Field",
- "From South Clock Town (South entrance)",
- "From Bombers' Hideout",
- "From South Clock Town (North entrance)",
- "From Treasure Chest Shop",
- "From North Clock Town",
- "From Honey & Darling's Shop",
- "From the Mayor's Residence",
- "From Town Shooting Gallery",
- "From Stock Pot Inn",
- "Stock Pot Inn balcony",
- "From Milk Bar",
- }
- },
- {
- 212, "West Clock Town", {
- "From Termina Field",
- "From South Clock Town (South entrance)",
- "From South Clock Town (North entrance)",
- "From Swordsman's School",
- "From Curiosity Shop",
- "From Trading Post",
- "From Bomb Shop",
- "From Post Office",
- "From Lottery Shop",
- "From Termina Field (?)",
- }
- },
- {
- 214, "North Clock Town", {
- "From Termina Field",
- "From East Clock Town",
- "From South Clock Town",
- "From Fairy's Fountain",
- "From Deku Scrub Playground",
- "Near Termina Field entrance",
- "Near Jim",
- "After Sakon cutscene",
- }
- },
- {
- 216, "South Clock Town", {
- "From Clock Tower",
- "From Termina Field",
- "From East Clock Town (North entrance)",
- "From West Clock Town (North entrance)",
- "From North Clock Town",
- "From West Clock Town (South entrance)",
- "From Laundry Pool",
- "From East Clock Town (South entrance)",
- "Clock Tower balcony",
- "Owl Statue",
- "First song of time cutscene"
- }
- },
- {
- 218, "Laundry Pool", {
- "From South Clock Town",
- "Curiosity Shop back entrance"
- }
- },
- }},
- { "Swamp", {
- {
- 12, "Southern Swamp (After Woodfall Temple)", {
- "From Road",
- "In Front of Boat House",
- "Froom Woodfall",
- "From Lower Deku Palace",
- "From Upper Deku Palace",
- "From Magic Hags' Potion Shop",
- "Boat Ride",
- "From Woods of Mistery",
- "From Swamp Spider House",
- "From Ikanya Canyon",
- "Owl Statue",
- }
- },
- {
- 4, "Hags' Potion Shop", {
- "Entrance",
- }
- },
- {
- 48, "Woodfall Temple", {
- "Entrance",
- "Deku Princess Room (First Visit)",
- "Deku Princess Room",
- }
- },
- {
- 56, "Odolwa Arena", {
- "Entrance",
- }
- },
- {
- 66, "Swamp Shooting Gallery", {
- "Entrance",
- }
- },
- {
- 72, "Swamp Spider House", {
- "Entrance",
- }
- },
- {
- 80, "Deku Palace", {
- "From Southern Swamp",
- "After getting caught",
- "From Deku King Chamber",
- "From Upper Deku King Chamber",
- "From Deku Shrine",
- "From Southern Swamp (Upper tunnel)",
- "From Left Grotto (Japanese)",
- "From Left Grotto Second Room (Japanese)",
- "From Right Grotto Second Room (Japanese)",
- "From Bean Seller Grotto",
- "From Right Grotto First Room (Japanese)",
- }
- },
- {
- 118, "Deku Palace Royal Chamber", {
- "From Deku Palace",
- "From Upper Deku Palace",
- "After Releasing Monkey",
- "In Front of the King",
- }
- },
- {
- 122, "Road to Southern Swamp", {
- "From Termina Field",
- "From Southern Swamp",
- "From Swamp Shooting Gallery",
- }
- },
- {
- 132, "Southern Swamp (Before Woodfall Temple)", {
- "From Road to Southern Swamp",
- "In Front of Boat House",
- "From Woodfall",
- "From Deku Palace",
- "From Deku Palace (Shortcut)",
- "From Hags' Potion Shop",
- "Boat Ride",
- "From Woods of Mistery",
- "From Swamp Spider House",
- "From Ikana Canyon",
- "Owl Statue",
- }
- },
- {
- 134, "Woodfall", {
- "From Southern Swamp",
- "In Mid-Air",
- "-From Fairy Mountain",
- "In Mid-Air (alternate)",
- "Owl Statue",
- }
- },
- {
- 158, "Deku Shrine", {
- "From Deku Palace",
- "From Deku Palace"
- }
- },
- {
- 168, "Swamp Tourist Center", {
- "Entrance",
- "Talking to Koume",
- "Talking to Tingle's Dad",
- }
- },
- {
- 194, "Woods of Mystery", {
- "Entrance",
- }
- }
- }},
- { "Snowhead", {
- {
- 50, "Road to Mountain Village", {
- "From Termina Field",
- "From Mountain Village",
- }
- },
- {
- 60, "Snowhead Temple", {
- "Entrance (First Visit)",
- "Entrance",
- }
- },
- {
- 82, "Mountain Smithy", {
- "Entrance",
- }
- },
- {
- 94, "Goron Shrine", {
- "Main Entrance (First Visit)",
- "From Shop",
- "After Goron's Lullaby cutscene",
- "Main Entrance",
- }
- },
- {
- 116, "Goron Shop", {
- "Entrance",
- }
- },
- {
- 130, "Goht Arena", {
- "Entrance",
- }
- },
- {
- 138, "Goron Village (After Snowhead Temple)", {
- "From Path to Goron Village",
- "In Mid-Air",
- "From Goron Shrine",
- "Over the Void",
- "In Front of Invisible Platforms",
- }
- },
- {
- 148, "Goron Village (Before Snowhead Temple)", {
- "From Path to Goron Village",
- "In Front of Deku Flower",
- "From Goron Shrine",
- "From Lens of Truth",
- "In Front of Invisible Platforms",
- }
- },
- {
- 150, "Goron Graveyard", {
- "-From Mountain Village",
- "-After Receiving Goron Mask",
- }
- },
- {
- 154, "Mountain Village (Before Snowhead Temple)", {
- "In Front of Mountain Smithy",
- "Mountain Smithy",
- "From Path to Goron Village",
- "From Goron Graveyard",
- "From Path to Snowhead",
- "On the lake",
- "From Path to Mountain Village",
- "On the Lake (alternate)",
- "Owl Statue",
- }
- },
- {
- 174, "Mountain Village (After Snowhead Temple)", {
- "Next to Lake",
- "From Mountain Smithy",
- "From Path to Goron Village",
- "From Goron Graveyard",
- "From Path to Snowhead",
- "Behind Waterfall",
- "From Path to Mountain Village",
- "Next to Lake (After Snowhead Cutscene)",
- "Owl Statue",
- }
- },
- {
- 178, "Snowhead", {
- "From Path to Snowhead",
- "From Snowhead Temple",
- "From Fairy Fountain",
- "Owl Statue",
- }
- },
- {
- 180, "Road to Goron Village (Before Snowhead Temple)", {
- "From Mountain Village",
- "From Goron Village",
- "From Goron Racetrack",
- }
- },
- {
- 182, "Road to Goron Village (After Snowhead Temple)", {
- "From Mountain Village",
- "From Goron Village",
- "From Goron Racetrack",
- }
- },
- {
- 208, "Goron Racetrack", {
- "From Path to Mountain Village",
- "Race Start",
- "Race End",
- }
- }
- }},
- { "Great Bay", {
- {
- 34, "Pirates' Fortress (Outdoors)", {
- "From Exterior Pirate Fortress",
- "From Lower Hookshoot Room",
- "From Upper Hookshoot Room",
- "From Silver Rupee Room",
- "From Silver Rupee Room (alternate)",
- "From Room with Barrels",
- "From Room with Barrels (alternate)",
- "From Room with Barrels and Bridge",
- "From Room with Barrels and Bridge (alternate)",
- "Out of bounds",
- "Telescope",
- "Out of bounds (alternate)",
- "From Balcony in Exterior Pirate Fortress",
- "From Upper Hookshoot Room",
- }
- },
- {
- 64, "Pirates' Fortress (Indoors)", {
- "Hookshoot Room",
- "Upper Hookshoot Room",
- "Silver Rupee Room",
- "100 Rupee Room (Next to Egg)",
- "Barrel Room",
- "Barrel Room (Next to Egg)",
- "Room with Barrels and Bridge",
- "Room with Barrels and Bridge (next to egg)",
- "Telescope",
- "Hidden Entrance ",
- "Telescope",
- "Unloaded Room",
- }
- },
- {
- 68, "Pinnacle Rock", {
- "Entrance",
- "Respawn",
- }
- },
- {
- 74, "Oceanside Spider House", {
- "Entrance",
- }
- },
- {
- 88, "Marine Research Lab", {
- "Entrance",
- }
- },
- {
- 96, "Zora Hall", {
- "From Zora Cape",
- "From Zora Cape with Turtle",
- "From Zora Shop",
- "From Lulu's Room",
- "From Evan's Room",
- "From Japa's Room",
- "From Mikau's & Tijo's Room",
- "Stage",
- "Stage (After Rehearsal)",
- }
- },
- {
- 104, "Great Bay Coast", {
- "From Termina Field",
- "-zora cape",
- "From Zora Cape",
- "From Pinnacle Rock",
- "From Fisherman's Hut",
- "From Pirates' Fortress",
- "Next to Chuchu",
- "From Marine Lab",
- "From Oceanside Spider House",
- "Beach (Zora Mask Cutscene)",
- "Beach (After Zora Mask Cutscene)",
- "Owl Statue",
- "Thrown Out Pirates' Fortress",
- "Island (After jumping game)",
- }
- },
- {
- 106, "Zora Cape", {
- "From Great Bay Coast",
- "From Zora Hall",
- "From Zora Hall with Turtle",
- "Next to Zora Game Site",
- "From Waterfall Rapids",
- "From Fairy Fountain",
- "From Owl Statue",
- "From Great Bay Temple",
- "After Beating Great Bay Temple",
- "After Beating Great Bay Temple",
- }
- },
- {
- 112, "Pirates' Fortress (Entrance)", {
- "From Great Bay Coast",
- "From Pirates' Fortress",
- "From Secret Entrance",
- "From Underwater Jet",
- "Kicked out",
- "From Hookshot Platform in Pirates' Fortress",
- "From Telescope Room",
- }
- },
- {
- 114, "Fisherman's Hut", {
- "Entrance",
- }
- },
- {
- 140, "Great Bay Temple", {
- "Entrance (After intro)",
- "Entrance (With intro)"
- }
- },
- {
- 142, "Waterfall Rapids", {
- "From Zora Cape",
- "Race Start",
- "Race End",
- "Race Won",
- }
- },
- {
- 146, "Zora Hall (Room)", {
- "Mikau's Room",
- "Japas' Room",
- "Lulu's Room",
- "Evan's Room",
- "Japa's Room (after jam session)",
- "Zora's Shop",
- "Evan's Room (after composing song)",
- }
- },
- {
- 184, "Gyorg Arena", {
- "Entrance",
- "Falling Cutscene",
- }
- },
- {
- 190, "Great Bay (Pirate and Turtle Cutscene)", {
- "From Zora Cape",
- }
- }
- }},
- { "Ikana", {
- {
- 32, "Ikana Canyon", {
- "From Ikana Road",
- "From Ghost Hut",
- "From Music Box House",
- "From Stone Tower",
- "Owl Statue",
- "From Beneath the Well",
- "From Sakon's Hideout",
- "After Beating Stone Tower Temple",
- "From Ikana Castle",
- "House Opening Cutscene",
- "Spring Water Cave (played Song of Storms)",
- "From Fairy Fountain",
- "From Secret Shrine",
- "From Spring Water Cave",
- "Spring Water Cave",
- }
- },
- {
- 10, "Beneath the Graveyard", {
- "Day 2",
- "Day 1",
- }
- },
- {
- 52, "Ancient Castle of Ikana", {
- "From Beneath the Well",
- "From Ikana Canyon",
- "Outdoors (From main entrance)",
- "Indoors (From main entrance)",
- "Indoors (From ceiling)",
- "Indoors (East Wing)",
- "Indoors (From throne room)"
- }
- },
- {
- 38, "Stone Tower Temple (Normal)", {
- "Entrance (With Intro)",
- "Entrance (After Intro)",
- }
- },
- {
- 42, "Stone Tower Temple (Inverted)", {
- "Entrance",
- "-boss room entrance"
- }
- },
- {
- 90, "Beneath the Graveyard", {
- "Dampe's House",
- "Beneath the Graveyard",
- }
- },
- {
- 102, "Twinmold Arena", {
- "Entrance",
- "Entrane (1?)"
- }
- },
- {
- 128, "Ikana Graveyard", {
- "Road to Ikana",
- "From Grave 1 ",
- "From Grave 2",
- "From Grave 3",
- "From Dampe's House",
- "Keeta Defeated Cutscene",
- }
- },
- {
- 144, "Beneath the Well", {
- "From Ikana Canyon",
- "From Ikana Castle",
- }
- },
- {
- 152, "Sakon's Hideout", {
- "Entrance",
- }
- },
- {
- 156, "Spirit House", {
- "Entrance",
- "Minigame start",
- "After minigame",
- }
- },
- {
- 160, "Road to Ikana", {
- "From Termina Field",
- "From Ikana Canyon",
- "From Ikana Graveyard",
- }
- },
- {
- 164, "Music Box House", {
- "Entrance",
- }
- },
- {
- 166, "Ancient Castle of Ikana (Throne room)", {
- "Entrance",
- }
- },
- {
- 170, "Stone Tower", {
- "From Ikana Canyon",
- "In Front of Temple",
- "From Stone Tower Temple",
- "Owl Statue",
- }
- },
- {
- 172, "Stone Tower (Inverted)", {
- "In Front of Temple (Inverting Cutscene)",
- "From Stone Tower Temple",
- }
- },
- {
- 186, "Secret Shrine behind Waterfall", {
- "Entrance",
- }
- }
- }},
- { "Overworld", {
- {
- 76, "Astral Observatory", {
- "From Clock Town",
- "From Termina Field",
- "After telescope cutscene",
- }
- },
- {
- 84, "Termina Field", {
- "From West Clock Town",
- "From Road to Southern Swapm",
- "From Great Bay Coast",
- "From Path to Mountain Village",
- "From Road to Ikana",
- "From Milk Road",
- "From South Clock Town",
- "From East Clock Town",
- "From North Clock Town",
- "From Observatory",
- "Use Telescope",
- "Near Ikana",
- "Moon Crash Cutscene (Game Over)",
- "Next to Ikana (After Cremia's Hug)",
- "Next to Road to Southern Swamp (After Skull Kid Cutscene)"
- }
- }
- }},
- { "Milk Road", {
- {
- 6, "Romani Ranch (Indoors)", {
- "Barn",
- "House",
- }
- },
- {
- 62, "Milk Road", {
- "From Termina Field",
- "From Romani Ranch",
- "From Gorman's Track (Track Exit)",
- "From Gorman's Track (Main Exit)",
- "At Owl Statue",
- "Behind Giant Rock",
- "Next to Owl Statue",
- }
- },
- {
- 100, "Romani Ranch", {
- "Entrance",
- "After practice",
- "From Barn",
- "From House",
- "From Cucco Shack",
- "From Doggy Racetrack",
- "Near Barn (6?)",
- "Near Barn (7?)",
- "Near House (8?)",
- "Near Barn (9?)",
- "Talking to Romani",
- "Near Barn (11?)",
- }
- },
- {
- 124, "Doggy Racetrack", {
- "From Romani Ranch",
- "Next to Track (After Race)",
- }
- },
- {
- 126, "Cucco Shack", {
- "From Romani Ranch",
- "Talking to Grog (Getting Bunny Hood)",
- }
- },
- {
- 206, "Gorman Track", {
- "From Milk Road",
- "Next to Gorman",
- "Next to Gorman (After Beating Race)",
- "From Milk Road (Behind Fence)",
- "From Milk Road (After Fence Cutscene)",
- "In the Middle of the Track"
- }
- }
- }},
- { "Moon", {
- {
- 2, "Majora Arena", {
- "Entrance",
- }
- },
- {
- 78, "Moon Trial (Deku)", {
- "Entrance",
- }
- },
- {
- 120, "Moon Trial (Goron)", {
- "Entrance",
- }
- },
- {
- 136, "Moon Trial (Zora)", {
- "Entrance",
- "Respawn",
- }
- },
- {
- 198, "Moon Trial (Link)", {
- "Entrance",
- }
- },
- {
- 200, "Moon", {
- "Entrance",
- }
- }
- }},
- { "Other", {
- {
- 20, "Secret Grottos", {
- "Termina Field (Great Bay Gossip Stones)",
- "Termina Field (Swamp Gossip Stones)",
- "Termina Field (Ikana Gossip Stones)",
- "Termina Field (Mountain Gossip Stones)",
- "-generic grotto",
- "Road to Goron Village (Springwater)",
- "-maze straight (a)",
- "Termina Field near Dodongos",
- "-maze vines (lower)",
- "-business scrub",
- "-cows",
- "Termina Field under boulder (Piece of Heart)",
- "Deku Palace (Bean Seller)",
- "Termina Field (Peahat)",
- "-maze straight (b)",
- "-maze grotto (upper)",
- "-lens of truth",
- }
- },
- {
- 46, "Intro Areas", {
- "Falling from Cliff Cutscene",
- "Before Entering Clock Tower",
- "After Being Transformed into Deku",
- "Before Entering Clock Tower (Void Respawn)",
- "South Clock Town (After First Song of Time)",
- }
- },
- {
- 70, "Fairy's Fountain", {
- "Clock Town",
- "Woodfall",
- "Snowhead",
- "Great Bay Coast",
- "Ikana Canyon",
- "Clock Town (After cutscene)",
- "Woodfall (After cutscene)",
- "Snowhead (After cutscene)",
- "Great Bay Coast (After cutscene)",
- "Ikana Canyon (After cutscene)",
- }
- },
- {
- 196, "Intro (Lost Woods)", {
- "Skull kid intro cutscene",
- "First Song of Time cutscene"
- }
- },
- {
- 204, "Chamber of Giants", {
- "Entrance",
- }
- }
- }},
-};
-
diff --git a/src/main/launcher_animation.cpp b/src/main/launcher_animation.cpp
new file mode 100644
index 0000000..6fb7194
--- /dev/null
+++ b/src/main/launcher_animation.cpp
@@ -0,0 +1,13 @@
+#include "zelda_launcher.h"
+#include
+
+void zelda64::launcher_animation_setup(recompui::LauncherMenu *menu) {
+ auto context = recompui::get_current_context();
+ recompui::Element *background_container = menu->get_background_container();
+ background_container->set_background_color({ 0x00, 0x00, 0x00, 0xFF });
+
+ (void)context;
+}
+
+void zelda64::launcher_animation_update(recompui::LauncherMenu *menu) {
+}
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 58c42b1..6b8d8a8 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -27,15 +27,22 @@
#undef Always
#endif
-#include "recomp_ui.h"
-#include "recomp_input.h"
+#include "recompui/recompui.h"
+#include "recompui/program_config.h"
+#include "recompui/renderer.h"
+#include "recompui/config.h"
+#include "util/file.h"
+#include "recompinput/input_events.h"
+#include "recompinput/recompinput.h"
+#include "recompinput/profiles.h"
#include "zelda_config.h"
#include "zelda_sound.h"
-#include "zelda_render.h"
#include "zelda_support.h"
#include "zelda_game.h"
+#include "zelda_launcher.h"
#include "recomp_data.h"
#include "ovl_patches.hpp"
+#include "theme.h"
#include "librecomp/game.hpp"
#include "librecomp/mods.hpp"
#include "librecomp/helpers.hpp"
@@ -58,7 +65,8 @@
const std::string version_string = "1.0.3";
-template void exit_error(const char* str, Ts... args) {
+template
+void exit_error(const char* str, Ts... args) {
// TODO pop up an error
((void) fprintf(stderr, str, args), ...);
assert(false);
@@ -74,7 +82,7 @@ ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) > 0) {
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) > 0) {
exit_error("Failed to initialize SDL2: %s\n", SDL_GetError());
}
@@ -83,9 +91,56 @@ ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
return {};
}
-#if defined(__gnu_linux__)
+#if 1
+ultramodern::input::connected_device_info_t get_connected_device_info(int controller_num) {
+ if (controller_num < recompinput::players::get_max_number_of_players()) {
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::Controller,
+ .connected_pak = ultramodern::input::Pak::RumblePak,
+ };
+ }
+
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::None,
+ .connected_pak = ultramodern::input::Pak::None,
+ };
+}
+#else
+ultramodern::input::connected_device_info_t get_connected_device_info(int controller_num) {
+ if (recompinput::players::is_single_player_mode()) {
+ if (controller_num == 0) {
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::Controller,
+ .connected_pak = ultramodern::input::Pak::RumblePak,
+ };
+ }
+ else {
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::None,
+ .connected_pak = ultramodern::input::Pak::None,
+ };
+ }
+ }
+ else {
+ if (recompinput::players::get_player_is_assigned(controller_num)) {
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::Controller,
+ .connected_pak = ultramodern::input::Pak::RumblePak,
+ };
+ }
+ else {
+ return ultramodern::input::connected_device_info_t{
+ .connected_device = ultramodern::input::Device::None,
+ .connected_pak = ultramodern::input::Pak::None,
+ };
+ }
+ }
+}
+#endif
+
#include "icon_bytes.h"
+#if defined(__gnu_linux__)
bool SetImageAsIcon(const char* filename, SDL_Window* window) {
// Read data
int width, height, bytesPerPixel;
@@ -144,16 +199,6 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
window =
SDL_CreateWindow("Starfox 64: Recompiled", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1600, 960, flags);
-#if defined(__linux__)
- SetImageAsIcon("icons/512.png", window);
- if (ultramodern::renderer::get_graphics_config().wm_option ==
- ultramodern::renderer::WindowMode::Fullscreen) { // TODO: Remove once RT64 gets native fullscreen support on
- // Linux
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
- } else {
- SDL_SetWindowFullscreen(window, 0);
- }
-#endif
if (window == nullptr) {
exit_error("Failed to create window: %s\n", SDL_GetError());
@@ -163,6 +208,10 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
SDL_VERSION(&wmInfo.version);
SDL_GetWindowWMInfo(window, &wmInfo);
+#if defined(__linux__)
+ SetImageAsIcon("icons/512.png", window);
+#endif
+
#if defined(_WIN32)
return ultramodern::renderer::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
#elif defined(__linux__) || defined(__ANDROID__)
@@ -176,7 +225,7 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
}
void update_gfx(void*) {
- recomp::handle_events();
+ recompinput::handle_events();
}
static SDL_AudioCVT audio_convert;
@@ -220,7 +269,7 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
// Convert the audio from 16-bit values to floats and swap the audio channels into the
// swap buffer to correct for the address xor caused by endianness handling.
- float cur_main_volume = zelda64::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
+ float cur_main_volume = static_cast(recompui::config::sound::get_main_volume()) / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
for (size_t i = 0; i < sample_count; i += input_channels) {
swap_buffer[i + 0 + duplicated_input_frames * input_channels] =
audio_data[i + 1] * (1.0f / 32768.0f) * cur_main_volume;
@@ -358,9 +407,11 @@ std::vector supported_games = {
{
.rom_hash = 0x163fd3fc3813f54eULL,
.internal_name = "STARFOX64",
+ .display_name = "Starfox 64",
.game_id = u8"sf64.n64.us.1.1",
.mod_game_id = "sf64",
.save_type = recomp::SaveType::Eep4k,
+ .thumbnail_bytes = std::span(icon_bytes),
.is_enabled = true,
.decompression_routine = zelda64::decompress_sf64,
.has_compressed_code = true,
@@ -369,13 +420,25 @@ std::vector supported_games = {
},
};
+typedef enum {
+ /* 0 */ THREAD_ID_SYSTEM,
+ /* 1 */ THREAD_ID_IDLE,
+ /* 2 */ THREAD_ID_FAULT,
+ /* 3 */ THREAD_ID_MAIN,
+ /* 4 */ THREAD_ID_4,
+ /* 5 */ THREAD_ID_AUDIO,
+ /* 6 */ THREAD_ID_GRAPHICS,
+ /* 7 */ THREAD_ID_TIMER,
+ /* 8 */ THREAD_ID_SERIAL,
+} ThreadID;
+
// TODO: move somewhere else
namespace zelda64 {
std::string get_game_thread_name(const OSThread* t) {
std::string name = "[Game] ";
switch (t->id) {
- case 0:
+ case THREAD_ID_SYSTEM:
switch (t->priority) {
case 150:
name += "PIMGR";
@@ -391,56 +454,32 @@ std::string get_game_thread_name(const OSThread* t) {
}
break;
- case 1:
+ case THREAD_ID_IDLE:
name += "IDLE";
break;
- case 2:
- switch (t->priority) {
- case 5:
- name += "SLOWLY";
- break;
-
- case 127:
- name += "FAULT";
- break;
-
- default:
- name += std::to_string(t->id);
- break;
- }
+ case THREAD_ID_FAULT:
+ name += "FAULT";
break;
- case 3:
+ case THREAD_ID_MAIN:
name += "MAIN";
break;
-
- case 4:
- name += "GRAPH";
- break;
-
- case 5:
- name += "SCHED";
- break;
-
- case 7:
- name += "PADMGR";
- break;
-
- case 10:
- name += "AUDIOMGR";
+
+ case THREAD_ID_AUDIO:
+ name += "AUDIO";
break;
- case 13:
- name += "FLASHROM";
+ case THREAD_ID_GRAPHICS:
+ name += "GRAPH";
break;
- case 18:
- name += "DMAMGR";
+ case THREAD_ID_TIMER:
+ name += "TIMER";
break;
- case 19:
- name += "IRQMGR";
+ case THREAD_ID_SERIAL:
+ name += "SERIAL";
break;
default:
@@ -545,7 +584,7 @@ void release_preload(PreloadContext& context) {
context = {};
}
-#else
+#elif defined(__linux__) || defined(APPLE)
struct PreloadContext {};
@@ -560,15 +599,29 @@ void release_preload(PreloadContext& context) {
#endif
void enable_texture_pack(recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) {
- zelda64::renderer::enable_texture_pack(context, mod);
+ recompui::renderer::enable_texture_pack(context, mod);
}
void disable_texture_pack(recomp::mods::ModContext&, const recomp::mods::ModHandle& mod) {
- zelda64::renderer::disable_texture_pack(mod);
+ recompui::renderer::disable_texture_pack(mod);
}
void reorder_texture_pack(recomp::mods::ModContext&) {
- zelda64::renderer::trigger_texture_pack_update();
+ recompui::renderer::trigger_texture_pack_update();
+}
+
+void on_launcher_init(recompui::LauncherMenu *menu) {
+ auto game_options_menu = menu->init_game_options_menu(
+ supported_games[0].game_id,
+ supported_games[0].mod_game_id,
+ supported_games[0].display_name,
+ supported_games[0].thumbnail_bytes,
+ recompui::GameOptionsMenuLayout::Right
+ );
+ game_options_menu->add_default_options();
+
+ recompui::Element *menu_container = menu->get_menu_container();
+ zelda64::launcher_animation_setup(menu);
}
#define REGISTER_FUNC(name) recomp::overlays::register_base_export(#name, name)
@@ -642,6 +695,13 @@ int main(int argc, char** argv) {
std::filesystem::current_path("/var/data", ec);
#endif
+ // Initialize native file dialogs.
+ NFD_Init();
+
+ // Initialize program settings.
+ recompui::programconfig::set_program_name(zelda64::program_name);
+ recompui::programconfig::set_program_id(zelda64::program_id);
+
// Initialize SDL audio and set the output frequency.
SDL_InitSubSystem(SDL_INIT_AUDIO);
reset_audio(48000);
@@ -652,7 +712,11 @@ int main(int argc, char** argv) {
fprintf(stderr, "Failed to load controller mappings: %s\n", SDL_GetError());
}
- recomp::register_config_path(zelda64::get_app_folder_path());
+ // Register fonts.
+ recompui::register_primary_font("LatoLatin-Regular.ttf", "LatoLatin");
+ recompui::register_extra_font("LatoLatin-Bold.ttf");
+
+ recomp::register_config_path(recompui::file::get_app_folder_path());
// Register supported games and patches
for (const auto& game : supported_games) {
@@ -669,9 +733,10 @@ int main(int argc, char** argv) {
REGISTER_FUNC(recomp_get_invert_y_axis_mode);
REGISTER_FUNC(recomp_get_radio_comm_box_mode);
REGISTER_FUNC(recomp_get_camera_inputs);
- REGISTER_FUNC(recomp_get_targeting_mode);
+ // REGISTER_FUNC(recomp_get_targeting_mode);
REGISTER_FUNC(recomp_get_bgm_volume);
- REGISTER_FUNC(recomp_get_low_health_beeps_enabled);
+ REGISTER_FUNC(recomp_get_sfx_volume);
+ // REGISTER_FUNC(recomp_get_low_health_beeps_enabled);
REGISTER_FUNC(recomp_get_gyro_deltas);
REGISTER_FUNC(recomp_get_mouse_deltas);
REGISTER_FUNC(recomp_get_inverted_axes);
@@ -681,15 +746,29 @@ int main(int argc, char** argv) {
zelda64::register_overlays();
zelda64::register_patches();
+
// recomputil::init_extended_actor_data();
- zelda64::load_config();
+
+ recompinput::players::set_single_player_mode(true);
+
+ zelda64::init_config();
+
+ recompui::register_launcher_init_callback(on_launcher_init);
+ recompui::register_launcher_update_callback(zelda64::launcher_animation_update);
recomp::rsp::callbacks_t rsp_callbacks{
.get_rsp_microcode = get_rsp_microcode,
};
ultramodern::renderer::callbacks_t renderer_callbacks{
- .create_render_context = zelda64::renderer::create_render_context,
+ .create_render_context =
+ [](uint8_t* rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode) {
+ auto presentation_mode = ultramodern::renderer::PresentationMode::PresentEarly;
+ std::unique_ptr render_context =
+ recompui::renderer::create_render_context(rdram, window_handle, presentation_mode, developer_mode);
+ render_context->set_post_blend_negative_dither_noise(true);
+ return std::unique_ptr(std::move(render_context));
+ },
};
ultramodern::gfx_callbacks_t gfx_callbacks{
@@ -705,15 +784,15 @@ int main(int argc, char** argv) {
};
ultramodern::input::callbacks_t input_callbacks{
- .poll_input = recomp::poll_inputs,
- .get_input = recomp::get_n64_input,
- .set_rumble = recomp::set_rumble,
- .get_connected_device_info = recomp::get_connected_device_info,
+ .poll_input = recompinput::poll_inputs,
+ .get_input = recompinput::profiles::get_n64_input,
+ .set_rumble = recompinput::set_rumble,
+ .get_connected_device_info = get_connected_device_info,
};
ultramodern::events::callbacks_t thread_callbacks{
- .vi_callback = recomp::update_rumble,
- .gfx_init_callback = recompui::update_supported_options,
+ .vi_callback = recompinput::update_rumble,
+ .gfx_init_callback = nullptr,
};
ultramodern::error_handling::callbacks_t error_handling_callbacks{
@@ -753,6 +832,9 @@ int main(int argc, char** argv) {
recomp::start(cfg);
+ // recomp::start(project_version, {}, rsp_callbacks, renderer_callbacks, audio_callbacks, input_callbacks,
+ // gfx_callbacks, thread_callbacks, error_handling_callbacks, threads_callbacks);
+
NFD_Quit();
if (preloaded) {
diff --git a/src/main/theme.cpp b/src/main/theme.cpp
new file mode 100644
index 0000000..1091b14
--- /dev/null
+++ b/src/main/theme.cpp
@@ -0,0 +1,106 @@
+#include "elements/ui_theme.h"
+#include "theme.h"
+
+void recomptheme::set_custom_theme() {
+ using namespace recompui;
+
+ theme::set_theme_color(theme::color::Background1, Color{8, 7, 13, 255});
+ theme::set_theme_color(theme::color::Background2, Color{18, 16, 24, 255});
+ theme::set_theme_color(theme::color::Background3, Color{25, 22, 34, 255});
+ theme::set_theme_color(theme::color::BGOverlay, Color{190, 184, 219, 25}); // actually the overlay for the modal
+ theme::set_theme_color(theme::color::ModalOverlay, Color{8, 7, 13, 229}); // actually the background color of the modal itself
+ theme::set_theme_color(theme::color::BGShadow, Color{0, 0, 0, 89});
+ theme::set_theme_color(theme::color::BGShadow2, Color{8, 7, 13, 184});
+ theme::set_theme_color(theme::color::Text, Color{242, 242, 242, 255});
+ theme::set_theme_color(theme::color::TextActive, Color{245, 245, 245, 255});
+ theme::set_theme_color(theme::color::TextDim, Color{204, 204, 204, 255});
+ theme::set_theme_color(theme::color::TextInactive, Color{255, 255, 255, 153});
+ theme::set_theme_color(theme::color::TextA5, Color{242, 242, 242, 13});
+ theme::set_theme_color(theme::color::TextA20, Color{242, 242, 242, 51});
+ theme::set_theme_color(theme::color::TextA30, Color{242, 242, 242, 77});
+ theme::set_theme_color(theme::color::TextA50, Color{242, 242, 242, 128});
+ theme::set_theme_color(theme::color::TextA80, Color{242, 242, 242, 204});
+ theme::set_theme_color(theme::color::Primary, Color{0xB9, 0x7D, 0xF2, 255});
+ theme::set_theme_color(theme::color::PrimaryL, Color{0xDA, 0xBA, 0xF7, 255});
+ theme::set_theme_color(theme::color::PrimaryD, Color{0x7A, 0x2A, 0xC6, 255});
+ theme::set_theme_color(theme::color::PrimaryA5, Color{185, 125, 242, 13});
+ theme::set_theme_color(theme::color::PrimaryA20, Color{185, 125, 242, 51});
+ theme::set_theme_color(theme::color::PrimaryA30, Color{185, 125, 242, 77});
+ theme::set_theme_color(theme::color::PrimaryA50, Color{185, 125, 242, 128});
+ theme::set_theme_color(theme::color::PrimaryA80, Color{185, 125, 242, 204});
+ theme::set_theme_color(theme::color::Secondary, Color{0x17, 0xD6, 0xE8, 255});
+ theme::set_theme_color(theme::color::SecondaryL, Color{0xA2, 0xEF, 0xF6, 255});
+ theme::set_theme_color(theme::color::SecondaryD, Color{0x25, 0xA1, 0xAD, 255});
+ theme::set_theme_color(theme::color::SecondaryA5, Color{23, 214, 232, 13});
+ theme::set_theme_color(theme::color::SecondaryA20, Color{23, 214, 232, 51});
+ theme::set_theme_color(theme::color::SecondaryA30, Color{23, 214, 232, 77});
+ theme::set_theme_color(theme::color::SecondaryA50, Color{23, 214, 232, 128});
+ theme::set_theme_color(theme::color::SecondaryA80, Color{23, 214, 232, 204});
+ theme::set_theme_color(theme::color::Warning, Color{0xE9, 0xCD, 0x35, 255});
+ theme::set_theme_color(theme::color::WarningL, Color{0xF9, 0xE5, 0x7C, 255});
+ theme::set_theme_color(theme::color::WarningD, Color{0xC5, 0xAA, 0x16, 255});
+ theme::set_theme_color(theme::color::WarningA5, Color{233, 205, 53, 13});
+ theme::set_theme_color(theme::color::WarningA20, Color{233, 205, 53, 51});
+ theme::set_theme_color(theme::color::WarningA30, Color{233, 205, 53, 77});
+ theme::set_theme_color(theme::color::WarningA50, Color{233, 205, 53, 128});
+ theme::set_theme_color(theme::color::WarningA80, Color{233, 205, 53, 204});
+ theme::set_theme_color(theme::color::Danger, Color{0xF8, 0x60, 0x39, 255});
+ theme::set_theme_color(theme::color::DangerL, Color{0xFE, 0x86, 0x67, 255});
+ theme::set_theme_color(theme::color::DangerD, Color{0xB2, 0x39, 0x19, 255});
+ theme::set_theme_color(theme::color::DangerA5, Color{248, 96, 57, 13});
+ theme::set_theme_color(theme::color::DangerA20, Color{248, 96, 57, 51});
+ theme::set_theme_color(theme::color::DangerA30, Color{248, 96, 57, 77});
+ theme::set_theme_color(theme::color::DangerA50, Color{248, 96, 57, 128});
+ theme::set_theme_color(theme::color::DangerA80, Color{248, 96, 57, 204});
+ theme::set_theme_color(theme::color::Success, Color{0x45, 0xD0, 0x43, 255});
+ theme::set_theme_color(theme::color::SuccessL, Color{0xAA, 0xEA, 0xA9, 255});
+ theme::set_theme_color(theme::color::SuccessD, Color{0x2C, 0xA7, 0x2A, 255});
+ theme::set_theme_color(theme::color::SuccessA5, Color{69, 208, 67, 13});
+ theme::set_theme_color(theme::color::SuccessA20, Color{69, 208, 67, 51});
+ theme::set_theme_color(theme::color::SuccessA30, Color{69, 208, 67, 77});
+ theme::set_theme_color(theme::color::SuccessA50, Color{69, 208, 67, 128});
+ theme::set_theme_color(theme::color::SuccessA80, Color{69, 208, 67, 204});
+ theme::set_theme_color(theme::color::Border, Color{255, 255, 255, 51});
+ theme::set_theme_color(theme::color::BorderSoft, Color{255, 255, 255, 26});
+ theme::set_theme_color(theme::color::BorderHard, Color{255, 255, 255, 77});
+ theme::set_theme_color(theme::color::BorderSolid, Color{255, 255, 255, 153});
+ theme::set_theme_color(theme::color::Transparent, Color{0, 0, 0, 0});
+ theme::set_theme_color(theme::color::A, Color{51, 51, 255, 255});
+ theme::set_theme_color(theme::color::AL, Color{178, 178, 255, 255});
+ theme::set_theme_color(theme::color::AD, Color{32, 32, 172, 255});
+ theme::set_theme_color(theme::color::AA5, Color{51, 51, 255, 13});
+ theme::set_theme_color(theme::color::AA20, Color{51, 51, 255, 51});
+ theme::set_theme_color(theme::color::AA30, Color{51, 51, 255, 77});
+ theme::set_theme_color(theme::color::AA50, Color{51, 51, 255, 128});
+ theme::set_theme_color(theme::color::AA80, Color{51, 51, 255, 204});
+ theme::set_theme_color(theme::color::White, Color{255, 255, 255, 255});
+ theme::set_theme_color(theme::color::WhiteA5, Color{255, 255, 255, 13});
+ theme::set_theme_color(theme::color::WhiteA20, Color{255, 255, 255, 51});
+ theme::set_theme_color(theme::color::WhiteA30, Color{255, 255, 255, 77});
+ theme::set_theme_color(theme::color::WhiteA50, Color{255, 255, 255, 128});
+ theme::set_theme_color(theme::color::WhiteA80, Color{255, 255, 255, 204});
+ theme::set_theme_color(theme::color::BW05, Color{13, 13, 13, 255});
+ theme::set_theme_color(theme::color::BW10, Color{26, 26, 26, 255});
+ theme::set_theme_color(theme::color::BW25, Color{64, 64, 64, 255});
+ theme::set_theme_color(theme::color::BW50, Color{128, 128, 128, 255});
+ theme::set_theme_color(theme::color::BW75, Color{191, 191, 191, 255});
+ theme::set_theme_color(theme::color::BW90, Color{229, 229, 229, 255});
+
+ theme::border::radius_sm = 8.0f;
+ theme::border::radius_md = 12.0f;
+ theme::border::radius_lg = 16.0f;
+
+ const uint32_t header_weight = 700;
+ const uint32_t label_weight = 700;
+ const uint32_t base_weight = 400;
+ theme::set_typography_preset(theme::Typography::Header1, 64.0f + 4.0f, 0.07f, header_weight);
+ theme::set_typography_preset(theme::Typography::Header2, 48.0f + 4.0f, 0.07f, header_weight);
+ theme::set_typography_preset(theme::Typography::Header3, 32.0f + 4.0f, 0.07f, header_weight);
+ theme::set_typography_preset(theme::Typography::LabelLG, 32.0f + 4.0f, 0.11f, label_weight);
+ theme::set_typography_preset(theme::Typography::LabelMD, 24.0f + 4.0f, 0.11f, label_weight);
+ theme::set_typography_preset(theme::Typography::LabelSM, 16.0f + 4.0f, 0.14f, label_weight);
+ theme::set_typography_preset(theme::Typography::LabelXS, 14.0f + 4.0f, 0.14f, base_weight);
+ theme::set_typography_preset(theme::Typography::Body, 16.0f + 4.0f, 0, base_weight);
+};
+
+
diff --git a/src/main/theme.h b/src/main/theme.h
new file mode 100644
index 0000000..deaa66b
--- /dev/null
+++ b/src/main/theme.h
@@ -0,0 +1,6 @@
+#pragma once
+
+namespace recomptheme {
+ // Applies custom themes. recompui::apply_color_hack MUST be called after.
+ void set_custom_theme();
+} // namespace recomptheme
diff --git a/src/ui/core/ui_context.cpp b/src/ui/core/ui_context.cpp
deleted file mode 100644
index cff69fc..0000000
--- a/src/ui/core/ui_context.cpp
+++ /dev/null
@@ -1,725 +0,0 @@
-#include
-#include
-#include
-#include
-
-#include "slot_map.h"
-#include "RmlUi/Core/StreamMemory.h"
-
-#include "ultramodern/error_handling.hpp"
-#include "recomp_ui.h"
-#include "ui_context.h"
-#include "../elements/ui_element.h"
-
-// Hash implementations for ContextId and ResourceId.
-template <>
-struct std::hash {
- std::size_t operator()(const recompui::ContextId& id) const {
- return std::hash()(id.slot_id);
- }
-};
-
-template <>
-struct std::hash {
- std::size_t operator()(const recompui::ResourceId& id) const {
- return std::hash()(id.slot_id);
- }
-};
-
-using resource_slotmap = dod::slot_map32>;
-
-namespace recompui {
- struct Context {
- std::mutex context_lock;
- resource_slotmap resources;
- Rml::ElementDocument* document;
- Element root_element;
- Element* autofocus_element = nullptr;
- std::vector loose_elements;
- std::unordered_set to_update;
- std::vector> to_set_text;
- bool captures_input = true;
- bool captures_mouse = true;
- Context(Rml::ElementDocument* document) : document(document), root_element(document) {}
- };
-} // namespace recompui
-
-using context_slotmap = dod::slot_map32;
-
-static struct {
- std::recursive_mutex all_contexts_lock;
- context_slotmap all_contexts;
- std::unordered_set opened_contexts;
- std::unordered_map documents_to_contexts;
- Rml::SharedPtr style_sheet;
-} context_state;
-
-thread_local recompui::Context* opened_context = nullptr;
-thread_local recompui::ContextId opened_context_id = recompui::ContextId::null();
-
-enum class ContextErrorType {
- OpenWithoutClose,
- OpenInvalidContext,
- CloseWithoutOpen,
- CloseWrongContext,
- DestroyInvalidContext,
- GetContextWithoutOpen,
- AddResourceWithoutOpen,
- AddResourceToWrongContext,
- UpdateElementWithoutContext,
- UpdateElementInWrongContext,
- SetTextElementWithoutContext,
- SetTextElementInWrongContext,
- GetResourceWithoutOpen,
- GetResourceFailed,
- DestroyResourceWithoutOpen,
- DestroyResourceInWrongContext,
- DestroyResourceNotFound,
- GetDocumentInvalidContext,
- GetAutofocusInvalidContext,
- SetAutofocusInvalidContext,
- InternalError,
-};
-
-enum class SlotTag : uint8_t {
- Style = 0,
- Element = 1,
-};
-
-void context_error(recompui::ContextId id, ContextErrorType type) {
- (void)id;
-
- const char* error_message = "";
-
- switch (type) {
- case ContextErrorType::OpenWithoutClose:
- error_message = "Attempted to open a UI context without closing another UI context";
- break;
- case ContextErrorType::OpenInvalidContext:
- error_message = "Attempted to open an invalid UI context";
- break;
- case ContextErrorType::CloseWithoutOpen:
- error_message = "Attempted to close a UI context without one being open";
- break;
- case ContextErrorType::CloseWrongContext:
- error_message = "Attempted to close a different UI context than the one that's open";
- break;
- case ContextErrorType::DestroyInvalidContext:
- error_message = "Attempted to destroy an invalid UI element";
- break;
- case ContextErrorType::GetContextWithoutOpen:
- error_message = "Attempted to get the current UI context with no UI context open";
- break;
- case ContextErrorType::AddResourceWithoutOpen:
- error_message = "Attempted to create a UI resource with no open UI context";
- break;
- case ContextErrorType::AddResourceToWrongContext:
- error_message = "Attempted to create a UI resource in a different UI context than the one that's open";
- break;
- case ContextErrorType::UpdateElementWithoutContext:
- error_message = "Attempted to update a UI element with no open UI context";
- break;
- case ContextErrorType::UpdateElementInWrongContext:
- error_message = "Attempted to update a UI element in a different UI context than the one that's open";
- break;
- case ContextErrorType::SetTextElementWithoutContext:
- error_message = "Attempted to set the text of a UI element with no open UI context";
- break;
- case ContextErrorType::SetTextElementInWrongContext:
- error_message = "Attempted to set the text of a UI element in a different UI context than the one that's open";
- break;
- case ContextErrorType::GetResourceWithoutOpen:
- error_message = "Attempted to get a UI resource with no open UI context";
- break;
- case ContextErrorType::GetResourceFailed:
- error_message = "Failed to get a UI resource from the current open UI context";
- break;
- case ContextErrorType::DestroyResourceWithoutOpen:
- error_message = "Attempted to destroy a UI resource with no open UI context";
- break;
- case ContextErrorType::DestroyResourceInWrongContext:
- error_message = "Attempted to destroy a UI resource in a different UI context than the one that's open";
- break;
- case ContextErrorType::DestroyResourceNotFound:
- error_message = "Attempted to destroy a UI resource that doesn't exist in the current context";
- break;
- case ContextErrorType::GetDocumentInvalidContext:
- error_message = "Attempted to get the document of an invalid UI context";
- break;
- case ContextErrorType::GetAutofocusInvalidContext:
- error_message = "Attempted to get the autofocus element of an invalid UI context";
- break;
- case ContextErrorType::SetAutofocusInvalidContext:
- error_message = "Attempted to set the autofocus element of an invalid UI context";
- break;
- case ContextErrorType::InternalError:
- error_message = "Internal error in UI context";
- break;
- default:
- error_message = "Unknown UI context error";
- break;
- }
-
- // This assumes the error is coming from a mod, as it's unlikely that an end user will see a UI context error
- // in the base recomp.
- recompui::message_box((std::string{"Fatal error in mod - "} + error_message + ".").c_str());
- assert(false);
- ultramodern::error_handling::quick_exit(__FILE__, __LINE__, __FUNCTION__);
-}
-
-recompui::ContextId create_context_impl(Rml::ElementDocument* document) {
- static Rml::ElementDocument dummy_document{""};
- bool add_to_dict = true;
-
- if (document == nullptr) {
- document = &dummy_document;
- add_to_dict = false;
- }
-
- recompui::ContextId ret;
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- ret = { context_state.all_contexts.emplace(document).raw };
-
- if (add_to_dict) {
- context_state.documents_to_contexts.emplace(document, ret);
- }
- }
-
- return ret;
-}
-
-void recompui::init_styling(const std::filesystem::path& rcss_file) {
- std::string style{};
- {
- std::ifstream style_stream{rcss_file};
- style_stream.seekg(0, std::ios::end);
- style.resize(style_stream.tellg());
- style_stream.seekg(0, std::ios::beg);
-
- style_stream.read(style.data(), style.size());
- }
- std::unique_ptr rml_stream = std::make_unique(reinterpret_cast(style.data()), style.size());
- rml_stream->SetSourceURL(rcss_file.filename().string());
- context_state.style_sheet = Rml::Factory::InstanceStyleSheetStream(rml_stream.get());
-}
-
-recompui::ContextId recompui::create_context(const std::filesystem::path& path) {
- ContextId new_context = create_context_impl(nullptr);
-
- auto workingdir = std::filesystem::current_path();
-
- new_context.open();
- Rml::ElementDocument* doc = recompui::load_document(path.string());
- opened_context->document = doc;
- opened_context->root_element.base = doc;
- new_context.close();
-
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- context_state.documents_to_contexts.emplace(doc, new_context);
- }
-
- return new_context;
-}
-
-recompui::ContextId recompui::create_context(Rml::ElementDocument* document) {
- assert(document != nullptr);
-
- return create_context_impl(document);
-}
-
-recompui::ContextId recompui::create_context() {
- Rml::ElementDocument* doc = create_empty_document();
- doc->SetStyleSheetContainer(context_state.style_sheet);
- ContextId ret = create_context_impl(doc);
- Element* root = ret.get_root_element();
- // Mark the root element as not being a shim, as that's only needed for elements that were parented to Rml ones manually.
- root->shim = false;
-
- ret.open();
- root->set_width(100.0f, Unit::Percent);
- root->set_height(100.0f, Unit::Percent);
- root->set_display(Display::Flex);
- ret.close();
-
- doc->Hide();
-
- return ret;
-}
-
-void recompui::destroy_context(ContextId id) {
- bool existed = false;
-
- // TODO prevent deletion of a context while its mutex is in use. Second lock on the context's mutex before popping
- // from the slotmap?
-
- // Check if the provided id exists.
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- // Check if the target context is currently open.
- existed = context_state.all_contexts.has_key(context_slotmap::key{ id.slot_id });
- }
-
-
- // Raise an error if the context didn't exist.
- if (!existed) {
- context_error(id, ContextErrorType::DestroyInvalidContext);
- }
-
- id.open();
- id.clear_children();
- id.close();
-
- // Delete the provided id.
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- context_state.all_contexts.erase(context_slotmap::key{ id.slot_id });
- }
-}
-
-void recompui::destroy_all_contexts() {
- recompui::hide_all_contexts();
-
- std::lock_guard lock{ context_state.all_contexts_lock };
-
- // TODO prevent deletion of a context while its mutex is in use. Second lock on the context's mutex before popping
- // from the slotmap
-
- std::vector keys{};
- for (const auto& [key, item] : context_state.all_contexts.items()) {
- keys.push_back(key);
- }
-
- for (auto key : keys) {
- Context* ctx = context_state.all_contexts.get(key);
-
- std::lock_guard context_lock{ ctx->context_lock };
- opened_context = ctx;
- opened_context_id = ContextId{ key };
-
- opened_context_id.clear_children();
-
- opened_context = nullptr;
- opened_context_id = ContextId::null();
- }
-
- context_state.all_contexts.reset();
- context_state.documents_to_contexts.clear();
-}
-
-void recompui::ContextId::open() {
- // Ensure no other context is opened by this thread already.
- if (opened_context_id != ContextId::null()) {
- context_error(*this, ContextErrorType::OpenWithoutClose);
- }
-
- // Get the context with this id.
- Context* ctx;
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- ctx = context_state.all_contexts.get(context_slotmap::key{ slot_id });
- // If the context was found, add it to the opened contexts.
- if (ctx != nullptr) {
- context_state.opened_contexts.emplace(*this);
- }
- }
-
- // Check if the context exists.
- if (ctx == nullptr) {
- context_error(*this, ContextErrorType::OpenInvalidContext);
- }
-
- // Take ownership of the target context.
- ctx->context_lock.lock();
- opened_context = ctx;
- opened_context_id = *this;
-}
-
-bool recompui::ContextId::open_if_not_already() {
- if (opened_context_id == *this) {
- return false;
- }
-
- open();
- return true;
-}
-
-void recompui::ContextId::close() {
- // Ensure a context is currently opened by this thread.
- if (opened_context_id == ContextId::null()) {
- context_error(*this, ContextErrorType::CloseWithoutOpen);
- }
-
- // Check that the context that was specified is the same one that's currently open.
- if (*this != opened_context_id) {
- context_error(*this, ContextErrorType::CloseWrongContext);
- }
-
- // Release ownership of the target context.
- opened_context->context_lock.unlock();
- opened_context = nullptr;
- opened_context_id = ContextId::null();
-
- // Remove this context from the opened contexts.
- {
- std::lock_guard lock{ context_state.all_contexts_lock };
- context_state.opened_contexts.erase(*this);
- }
-}
-
-recompui::ContextId recompui::try_close_current_context() {
- if (opened_context_id != ContextId::null()) {
- ContextId prev_context = opened_context_id;
- opened_context_id.close();
- return prev_context;
- }
- return ContextId::null();
-}
-
-void recompui::ContextId::process_updates() {
- // Ensure a context is currently opened by this thread.
- if (opened_context_id == ContextId::null()) {
- context_error(*this, ContextErrorType::InternalError);
- }
-
- // Check that the context that was specified is the same one that's currently open.
- if (*this != opened_context_id) {
- context_error(*this, ContextErrorType::InternalError);
- }
-
- // Move the current update set into a local variable. This clears the update set
- // and allows it to be used to queue updates from any element callbacks.
- std::unordered_set to_update = std::move(opened_context->to_update);
-
- Event update_event = Event::update_event();
-
- for (auto cur_resource_id : to_update) {
- resource_slotmap::key cur_key{ cur_resource_id.slot_id };
-
- // Ignore any resources that aren't elements.
- if (cur_key.get_tag() != static_cast(SlotTag::Element)) {
- // Assert to catch errors of queueing other resource types for update.
- // This isn't an actual error, so there's no issue with continuing in release builds.
- assert(false);
- continue;
- }
-
- // Get the resource being updaten from the context.
- std::unique_ptr